packages: uboot-sunxi: re-add Olimex A13 SOM which went AWOL in u-boot trunk
[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 --- a/.gitignore
10 +++ b/.gitignore
11 @@ -49,6 +49,13 @@
12  /u-boot.sb
13  /u-boot.bd
14  /u-boot.geany
15 +/u-boot.bin.lzma
16 +/u-boot.bin.lzo
17 +/u-boot.ltq.lzma.norspl
18 +/u-boot.ltq.lzo.norspl
19 +/u-boot.ltq.norspl
20 +/u-boot.lzma.img
21 +/u-boot.lzo.img
22  
23  #
24  # Generated files
25 --- a/Makefile
26 +++ b/Makefile
27 @@ -435,6 +435,12 @@ $(obj)u-boot.bin:  $(obj)u-boot
28                 $(OBJCOPY) ${OBJCFLAGS} -O binary $< $@
29                 $(BOARD_SIZE_CHECK)
30  
31 +$(obj)u-boot.bin.lzma: $(obj)u-boot.bin
32 +               cat $< | lzma -9 -f - > $@
33 +
34 +$(obj)u-boot.bin.lzo:  $(obj)u-boot.bin
35 +               cat $< | lzop -9 -f - > $@
36 +
37  $(obj)u-boot.ldr:      $(obj)u-boot
38                 $(CREATE_LDR_ENV)
39                 $(LDR) -T $(CONFIG_BFIN_CPU) -c $@ $< $(LDR_FLAGS)
40 @@ -454,13 +460,23 @@ ifndef CONFIG_SYS_UBOOT_START
41  CONFIG_SYS_UBOOT_START := 0
42  endif
43  
44 -$(obj)u-boot.img:      $(obj)u-boot.bin
45 -               $(obj)tools/mkimage -A $(ARCH) -T firmware -C none \
46 +define GEN_UBOOT_IMAGE
47 +               $(obj)tools/mkimage -A $(ARCH) -T firmware -C $(1) \
48                 -O u-boot -a $(CONFIG_SYS_TEXT_BASE) \
49                 -e $(CONFIG_SYS_UBOOT_START) \
50                 -n $(shell sed -n -e 's/.*U_BOOT_VERSION//p' $(VERSION_FILE) | \
51                         sed -e 's/"[     ]*$$/ for $(BOARD) board"/') \
52                 -d $< $@
53 +endef
54 +
55 +$(obj)u-boot.img:      $(obj)u-boot.bin
56 +               $(call GEN_UBOOT_IMAGE,none)
57 +
58 +$(obj)u-boot.lzma.img: $(obj)u-boot.bin.lzma
59 +               $(call GEN_UBOOT_IMAGE,lzma)
60 +
61 +$(obj)u-boot.lzo.img:  $(obj)u-boot.bin.lzo
62 +               $(call GEN_UBOOT_IMAGE,lzo)
63  
64  $(obj)u-boot.imx: $(obj)u-boot.bin depend
65                 $(MAKE) -C $(SRCTREE)/arch/arm/imx-common $(OBJTREE)/u-boot.imx
66 @@ -571,6 +587,27 @@ $(obj)u-boot-img-spl-at-end.bin: $(obj)s
67                         conv=notrunc 2>/dev/null
68                 cat $(obj)u-boot-pad.img $(obj)spl/u-boot-spl.bin > $@
69  
70 +$(obj)u-boot.ltq.sfspl:        $(obj)u-boot.img $(obj)spl/u-boot-spl.bin
71 +               $(obj)tools/ltq-boot-image -t sfspl -e $(CONFIG_SPL_TEXT_BASE) \
72 +                       -s $(obj)spl/u-boot-spl.bin -u $< -o $@
73 +
74 +$(obj)u-boot.ltq.lzo.sfspl: $(obj)u-boot.lzo.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.lzma.sfspl: $(obj)u-boot.lzma.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.norspl: $(obj)u-boot.img $(obj)spl/u-boot-spl.bin
83 +       cat $(obj)spl/u-boot-spl.bin $< > $@
84 +
85 +$(obj)u-boot.ltq.lzo.norspl: $(obj)u-boot.lzo.img $(obj)spl/u-boot-spl.bin
86 +       cat $(obj)spl/u-boot-spl.bin $< > $@
87 +
88 +$(obj)u-boot.ltq.lzma.norspl: $(obj)u-boot.lzma.img $(obj)spl/u-boot-spl.bin
89 +       cat $(obj)spl/u-boot-spl.bin $< > $@
90 +
91  ifeq ($(CONFIG_SANDBOX),y)
92  GEN_UBOOT = \
93                 cd $(LNDIR) && $(CC) $(SYMS) -T $(obj)u-boot.lds \
94 --- a/README
95 +++ b/README
96 @@ -468,6 +468,11 @@ The following options need to be configu
97                         CONF_CM_CACHABLE_CUW
98                         CONF_CM_CACHABLE_ACCELERATED
99  
100 +               CONFIG_SYS_MIPS_CACHE_EXT_INIT
101 +
102 +               Enable this to use extended cache initialization for recent
103 +               MIPS CPU cores.
104 +
105                 CONFIG_SYS_XWAY_EBU_BOOTCFG
106  
107                 Special option for Lantiq XWAY SoCs for booting from NOR flash.
108 --- a/arch/mips/config.mk
109 +++ b/arch/mips/config.mk
110 @@ -45,9 +45,13 @@ PLATFORM_CPPFLAGS += -DCONFIG_MIPS -D__M
111  # On the other hand, we want PIC in the U-Boot code to relocate it from ROM
112  # to RAM. $28 is always used as gp.
113  #
114 -PLATFORM_CPPFLAGS              += -G 0 -mabicalls -fpic $(ENDIANNESS)
115 +PF_ABICALLS                    ?= -mabicalls
116 +PF_PIC                         ?= -fpic
117 +PF_PIE                         ?= -pie
118 +
119 +PLATFORM_CPPFLAGS              += -G 0 $(PF_ABICALLS) $(PF_PIC) $(ENDIANNESS)
120  PLATFORM_CPPFLAGS              += -msoft-float
121  PLATFORM_LDFLAGS               += -G 0 -static -n -nostdlib $(ENDIANNESS)
122  PLATFORM_RELFLAGS              += -ffunction-sections -fdata-sections
123 -LDFLAGS_FINAL                  += --gc-sections -pie
124 +LDFLAGS_FINAL                  += --gc-sections $(PF_PIE)
125  OBJCFLAGS                      += --remove-section=.dynsym
126 --- a/arch/mips/cpu/mips32/cache.S
127 +++ b/arch/mips/cpu/mips32/cache.S
128 @@ -29,7 +29,11 @@
129   */
130  #define MIPS_MAX_CACHE_SIZE    0x10000
131  
132 +#ifdef CONFIG_SYS_MIPS_CACHE_EXT_INIT
133 +#define INDEX_BASE     0x9fc00000
134 +#else
135  #define INDEX_BASE     CKSEG0
136 +#endif
137  
138         .macro  cache_op op addr
139         .set    push
140 @@ -65,7 +69,11 @@
141   */
142  LEAF(mips_init_icache)
143         blez            a1, 9f
144 +#ifdef CONFIG_SYS_MIPS_CACHE_EXT_INIT
145 +       mtc0            zero, CP0_ITAGLO
146 +#else
147         mtc0            zero, CP0_TAGLO
148 +#endif
149         /* clear tag to invalidate */
150         PTR_LI          t0, INDEX_BASE
151         PTR_ADDU        t1, t0, a1
152 @@ -90,7 +98,11 @@ LEAF(mips_init_icache)
153   */
154  LEAF(mips_init_dcache)
155         blez            a1, 9f
156 +#ifdef CONFIG_SYS_MIPS_CACHE_EXT_INIT
157 +       mtc0            zero, CP0_DTAGLO
158 +#else
159         mtc0            zero, CP0_TAGLO
160 +#endif
161         /* clear all tags */
162         PTR_LI          t0, INDEX_BASE
163         PTR_ADDU        t1, t0, a1
164 --- /dev/null
165 +++ b/arch/mips/cpu/mips32/danube/Makefile
166 @@ -0,0 +1,31 @@
167 +#
168 +# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de
169 +#
170 +# SPDX-License-Identifier:     GPL-2.0+
171 +#
172 +
173 +include $(TOPDIR)/config.mk
174 +
175 +LIB    = $(obj)lib$(SOC).o
176 +
177 +COBJS-y        += cgu.o chipid.o ebu.o mem.o pmu.o rcu.o
178 +SOBJS-y        += cgu_init.o mem_init.o
179 +
180 +COBJS  := $(COBJS-y)
181 +SOBJS  := $(SOBJS-y)
182 +SRCS   := $(SOBJS:.o=.S) $(COBJS:.o=.c)
183 +OBJS   := $(addprefix $(obj),$(SOBJS) $(COBJS))
184 +
185 +all:   $(LIB)
186 +
187 +$(LIB):        $(obj).depend $(OBJS)
188 +       $(call cmd_link_o_target, $(OBJS))
189 +
190 +#########################################################################
191 +
192 +# defines $(obj).depend target
193 +include $(SRCTREE)/rules.mk
194 +
195 +sinclude $(obj).depend
196 +
197 +#########################################################################
198 --- /dev/null
199 +++ b/arch/mips/cpu/mips32/danube/cgu.c
200 @@ -0,0 +1,117 @@
201 +/*
202 + * Copyright (C) 2007-2010 Lantiq Deutschland GmbH
203 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
204 + *
205 + * SPDX-License-Identifier:    GPL-2.0+
206 + */
207 +
208 +#include <common.h>
209 +#include <asm/arch/soc.h>
210 +#include <asm/lantiq/clk.h>
211 +#include <asm/lantiq/io.h>
212 +
213 +#define LTQ_CGU_SYS_DDR_MASK           0x0003
214 +#define LTQ_CGU_SYS_DDR_SHIFT          0
215 +#define LTQ_CGU_SYS_CPU0_MASK          0x000C
216 +#define LTQ_CGU_SYS_CPU0_SHIFT         2
217 +#define LTQ_CGU_SYS_FPI_MASK           0x0040
218 +#define LTQ_CGU_SYS_FPI_SHIFT          6
219 +
220 +struct ltq_cgu_regs {
221 +       u32     rsvd0;
222 +       u32     pll0_cfg;       /* PLL0 config */
223 +       u32     pll1_cfg;       /* PLL1 config */
224 +       u32     pll2_cfg;       /* PLL2 config */
225 +       u32     sys;            /* System clock */
226 +       u32     update;         /* CGU update control */
227 +       u32     if_clk;         /* Interface clock */
228 +       u32     osc_con;        /* Update OSC Control */
229 +       u32     smd;            /* SDRAM Memory Control */
230 +       u32     rsvd1[3];
231 +       u32     pcm_cr;         /* PCM control */
232 +       u32     pci_cr;         /* PCI clock control */
233 +};
234 +
235 +static struct ltq_cgu_regs *ltq_cgu_regs =
236 +       (struct ltq_cgu_regs *) CKSEG1ADDR(LTQ_CGU_BASE);
237 +
238 +static inline u32 ltq_cgu_sys_readl(u32 mask, u32 shift)
239 +{
240 +       return (ltq_readl(&ltq_cgu_regs->sys) & mask) >> shift;
241 +}
242 +
243 +unsigned long ltq_get_io_region_clock(void)
244 +{
245 +       u32 ddr_sel;
246 +       unsigned long clk;
247 +
248 +       ddr_sel = ltq_cgu_sys_readl(LTQ_CGU_SYS_DDR_MASK,
249 +                                       LTQ_CGU_SYS_DDR_SHIFT);
250 +
251 +       switch (ddr_sel) {
252 +       case 0:
253 +               clk = CLOCK_166_MHZ;
254 +               break;
255 +       case 1:
256 +               clk = CLOCK_133_MHZ;
257 +               break;
258 +       case 2:
259 +               clk = CLOCK_111_MHZ;
260 +               break;
261 +       case 3:
262 +               clk = CLOCK_83_MHZ;
263 +               break;
264 +       default:
265 +               clk = 0;
266 +               break;
267 +       }
268 +
269 +       return clk;
270 +}
271 +
272 +unsigned long ltq_get_cpu_clock(void)
273 +{
274 +       u32 cpu0_sel;
275 +       unsigned long clk;
276 +
277 +       cpu0_sel = ltq_cgu_sys_readl(LTQ_CGU_SYS_CPU0_MASK,
278 +                                       LTQ_CGU_SYS_CPU0_SHIFT);
279 +
280 +       switch (cpu0_sel) {
281 +               /* Same as PLL0 output (333,33 MHz) */
282 +       case 0:
283 +               clk = CLOCK_333_MHZ;
284 +               break;
285 +               /* 1/1 fixed ratio to DDR clock */
286 +       case 1:
287 +               clk = ltq_get_io_region_clock();
288 +               break;
289 +               /* 1/2 fixed ratio to DDR clock */
290 +       case 2:
291 +               clk = ltq_get_io_region_clock() << 1;
292 +               break;
293 +       default:
294 +               clk = 0;
295 +               break;
296 +       }
297 +
298 +       return clk;
299 +}
300 +
301 +unsigned long ltq_get_bus_clock(void)
302 +{
303 +       u32 fpi_sel;
304 +       unsigned long clk;
305 +
306 +       fpi_sel = ltq_cgu_sys_readl(LTQ_CGU_SYS_FPI_MASK,
307 +                                       LTQ_CGU_SYS_FPI_SHIFT);
308 +
309 +       if (fpi_sel)
310 +               /* Half the DDR clock */
311 +               clk = ltq_get_io_region_clock() >> 1;
312 +       else
313 +               /* Same as DDR clock */
314 +               clk = ltq_get_io_region_clock();
315 +
316 +       return clk;
317 +}
318 --- /dev/null
319 +++ b/arch/mips/cpu/mips32/danube/cgu_init.S
320 @@ -0,0 +1,142 @@
321 +/*
322 + * Copyright (C) 2007-2010 Lantiq Deutschland GmbH
323 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
324 + *
325 + * SPDX-License-Identifier:    GPL-2.0+
326 + */
327 +
328 +#include <config.h>
329 +#include <asm/asm.h>
330 +#include <asm/regdef.h>
331 +#include <asm/addrspace.h>
332 +#include <asm/arch/soc.h>
333 +
334 +/* RCU module register */
335 +#define LTQ_RCU_RST_REQ                        0x0010
336 +#define LTQ_RCU_RST_STAT               0x0014
337 +#define LTQ_RCU_RST_REQ_VALUE          0x40000008
338 +#define LTQ_RCU_RST_STAT_XTAL_F        0x20000
339 +
340 +/* CGU module register */
341 +#define LTQ_CGU_PLL0_CFG               0x0004  /* PLL0 config */
342 +#define LTQ_CGU_PLL1_CFG               0x0008  /* PLL1 config */
343 +#define LTQ_CGU_PLL2_CFG               0x000C  /* PLL2 config */
344 +#define LTQ_CGU_SYS                    0x0010  /* System clock */
345 +
346 +/* Valid SYS.CPU0/1 values */
347 +#define LTQ_CGU_SYS_CPU0_SHIFT         2
348 +#define LTQ_CGU_SYS_CPU1_SHIFT         4
349 +#define LTQ_CGU_SYS_CPU_PLL0           0x0
350 +#define LTQ_CGU_SYS_CPU_DDR_EQUAL      0x1
351 +#define LTQ_CGU_SYS_CPU_DDR_TWICE      0x2
352 +
353 +/* Valid SYS.DDR values */
354 +#define LTQ_CGU_SYS_DDR_SHIFT          0
355 +#define LTQ_CGU_SYS_DDR_167_MHZ        0x0
356 +#define LTQ_CGU_SYS_DDR_133_MHZ        0x1
357 +#define LTQ_CGU_SYS_DDR_111_MHZ        0x2
358 +#define LTQ_CGU_SYS_DDR_83_MHZ         0x3
359 +
360 +/* Valid SYS.FPI values */
361 +#define LTQ_CGU_SYS_FPI_SHIFT          6
362 +#define LTQ_CGU_SYS_FPI_DDR_EQUAL      0x0
363 +#define LTQ_CGU_SYS_FPI_DDR_HALF       0x1
364 +
365 +/* Valid SYS.PPE values */
366 +#define LTQ_CGU_SYS_PPE_SHIFT          7
367 +#define LTQ_CGU_SYS_PPE_266_MHZ        0x0
368 +#define LTQ_CGU_SYS_PPE_240_MHZ        0x1
369 +#define LTQ_CGU_SYS_PPE_222_MHZ        0x2
370 +#define LTQ_CGU_SYS_PPE_133_MHZ        0x3
371 +
372 +#if (CONFIG_SYS_CLOCK_MODE == LTQ_CLK_CPU_333_DDR_167)
373 +#define LTQ_CGU_SYS_CPU_CONFIG         LTQ_CGU_SYS_CPU_DDR_TWICE
374 +#define LTQ_CGU_SYS_DDR_CONFIG         LTQ_CGU_SYS_DDR_167_MHZ
375 +#define LTQ_CGU_SYS_FPI_CONFIG         LTQ_CGU_SYS_FPI_DDR_HALF
376 +#define LTQ_CGU_SYS_PPE_CONFIG         LTQ_CGU_SYS_PPE_266_MHZ
377 +#elif (CONFIG_SYS_CLOCK_MODE == LTQ_CLK_CPU_111_DDR_111)
378 +#define LTQ_CGU_SYS_CPU_CONFIG         LTQ_CGU_SYS_CPU_DDR_EQUAL
379 +#define LTQ_CGU_SYS_DDR_CONFIG         LTQ_CGU_SYS_DDR_111_MHZ
380 +#define LTQ_CGU_SYS_FPI_CONFIG         LTQ_CGU_SYS_FPI_DDR_HALF
381 +#define LTQ_CGU_SYS_PPE_CONFIG         LTQ_CGU_SYS_PPE_133_MHZ
382 +#else
383 +#error "Invalid system clock configuration!"
384 +#endif
385 +
386 +/* Build register values */
387 +#define LTQ_CGU_SYS_VALUE      ((LTQ_CGU_SYS_PPE_CONFIG << \
388 +                                       LTQ_CGU_SYS_PPE_SHIFT) | \
389 +                               (LTQ_CGU_SYS_FPI_CONFIG << \
390 +                                       LTQ_CGU_SYS_FPI_SHIFT) | \
391 +                               (LTQ_CGU_SYS_CPU_CONFIG << \
392 +                                       LTQ_CGU_SYS_CPU1_SHIFT) | \
393 +                               (LTQ_CGU_SYS_CPU_CONFIG << \
394 +                                       LTQ_CGU_SYS_CPU0_SHIFT) | \
395 +                               LTQ_CGU_SYS_DDR_CONFIG)
396 +
397 +/* Reset values for PLL registers for usage with 35.328 MHz crystal */
398 +#define PLL0_35MHZ_CONFIG      0x9D861059
399 +#define PLL1_35MHZ_CONFIG      0x1A260CD9
400 +#define PLL2_35MHZ_CONFIG      0x8000f1e5
401 +
402 +/* Reset values for PLL registers for usage with 36 MHz crystal */
403 +#define PLL0_36MHZ_CONFIG      0x1000125D
404 +#define PLL1_36MHZ_CONFIG      0x1B1E0C99
405 +#define PLL2_36MHZ_CONFIG      0x8002f2a1
406 +
407 +LEAF(ltq_cgu_init)
408 +       /* Load current CGU register value */
409 +       li      t0, (LTQ_CGU_BASE | KSEG1)
410 +       lw      t1, LTQ_CGU_SYS(t0)
411 +
412 +       /* Load target CGU register values */
413 +       li      t3, LTQ_CGU_SYS_VALUE
414 +
415 +       /* Only update registers if values differ */
416 +       beq     t1, t3, finished
417 +
418 +       /*
419 +        * Check whether the XTAL_F bit in RST_STAT register is set or not.
420 +        * This bit is latched in via pin strapping. If bit is set then
421 +        * clock source is a 36 MHz crystal. Otherwise a 35.328 MHz crystal.
422 +        */
423 +        li     t1, (LTQ_RCU_BASE | KSEG1)
424 +        lw     t2, LTQ_RCU_RST_STAT(t1)
425 +        and    t2, t2, LTQ_RCU_RST_STAT_XTAL_F
426 +        beq    t2, LTQ_RCU_RST_STAT_XTAL_F, boot_36mhz
427 +
428 +boot_35mhz:
429 +       /* Configure PLL for 35.328 MHz */
430 +       li      t2, PLL0_35MHZ_CONFIG
431 +       sw      t2, LTQ_CGU_PLL0_CFG(t0)
432 +       li      t2, PLL1_35MHZ_CONFIG
433 +       sw      t2, LTQ_CGU_PLL1_CFG(t0)
434 +       li      t2, PLL2_35MHZ_CONFIG
435 +       sw      t2, LTQ_CGU_PLL2_CFG(t0)
436 +
437 +       b       do_reset
438 +
439 +boot_36mhz:
440 +       /* Configure PLL for 36 MHz */
441 +       li      t2, PLL0_36MHZ_CONFIG
442 +       sw      t2, LTQ_CGU_PLL0_CFG(t0)
443 +       li      t2, PLL1_36MHZ_CONFIG
444 +       sw      t2, LTQ_CGU_PLL1_CFG(t0)
445 +       li      t2, PLL2_36MHZ_CONFIG
446 +       sw      t2, LTQ_CGU_PLL2_CFG(t0)
447 +
448 +do_reset:
449 +       /* Store new clock config */
450 +       sw      t3, LTQ_CGU_SYS(t0)
451 +
452 +       /* Perform software reset to activate new clock config */
453 +       li      t2, LTQ_RCU_RST_REQ_VALUE
454 +       sw      t2, LTQ_RCU_RST_REQ(t1)
455 +
456 +wait_reset:
457 +       b       wait_reset
458 +
459 +finished:
460 +       jr      ra
461 +
462 +       END(ltq_cgu_init)
463 --- /dev/null
464 +++ b/arch/mips/cpu/mips32/danube/chipid.c
465 @@ -0,0 +1,59 @@
466 +/*
467 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
468 + *
469 + * SPDX-License-Identifier:    GPL-2.0+
470 + */
471 +
472 +#include <common.h>
473 +#include <asm/lantiq/io.h>
474 +#include <asm/lantiq/chipid.h>
475 +#include <asm/arch/soc.h>
476 +
477 +#define LTQ_CHIPID_VERSION_SHIFT       28
478 +#define LTQ_CHIPID_VERSION_MASK                (0xF << LTQ_CHIPID_VERSION_SHIFT)
479 +#define LTQ_CHIPID_PNUM_SHIFT          12
480 +#define LTQ_CHIPID_PNUM_MASK           (0xFFFF << LTQ_CHIPID_PNUM_SHIFT)
481 +
482 +struct ltq_chipid_regs {
483 +       u32     manid;          /* Manufacturer identification */
484 +       u32     chipid;         /* Chip identification */
485 +};
486 +
487 +static struct ltq_chipid_regs *ltq_chipid_regs =
488 +       (struct ltq_chipid_regs *) CKSEG1ADDR(LTQ_CHIPID_BASE);
489 +
490 +unsigned int ltq_chip_version_get(void)
491 +{
492 +       u32 chipid;
493 +
494 +       chipid = ltq_readl(&ltq_chipid_regs->chipid);
495 +
496 +       return (chipid & LTQ_CHIPID_VERSION_MASK) >> LTQ_CHIPID_VERSION_SHIFT;
497 +}
498 +
499 +unsigned int ltq_chip_partnum_get(void)
500 +{
501 +       u32 chipid;
502 +
503 +       chipid = ltq_readl(&ltq_chipid_regs->chipid);
504 +
505 +       return (chipid & LTQ_CHIPID_PNUM_MASK) >> LTQ_CHIPID_PNUM_SHIFT;
506 +}
507 +
508 +const char *ltq_chip_partnum_str(void)
509 +{
510 +       enum ltq_chip_partnum partnum = ltq_chip_partnum_get();
511 +
512 +       switch (partnum) {
513 +       case LTQ_SOC_DANUBE:
514 +               return "Danube";
515 +       case LTQ_SOC_DANUBE_S:
516 +               return "Danube-S";
517 +       case LTQ_SOC_TWINPASS:
518 +               return "Twinpass";
519 +       default:
520 +               printf("Unknown partnum: %x\n", partnum);
521 +       }
522 +
523 +       return "";
524 +}
525 --- /dev/null
526 +++ b/arch/mips/cpu/mips32/danube/config.mk
527 @@ -0,0 +1,25 @@
528 +#
529 +# Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
530 +#
531 +# SPDX-License-Identifier:     GPL-2.0+
532 +#
533 +
534 +PF_CPPFLAGS_DANUBE := $(call cc-option,-mtune=24kec,)
535 +PLATFORM_CPPFLAGS += $(PF_CPPFLAGS_DANUBE)
536 +
537 +ifdef CONFIG_SPL_BUILD
538 +PF_ABICALLS            := -mno-abicalls
539 +PF_PIC                 := -fno-pic
540 +PF_PIE                 :=
541 +USE_PRIVATE_LIBGCC     := yes
542 +endif
543 +
544 +LIBS-y += $(CPUDIR)/lantiq-common/liblantiq-common.o
545 +
546 +ifndef CONFIG_SPL_BUILD
547 +ifdef CONFIG_SYS_BOOT_NORSPL
548 +ALL-y += $(obj)u-boot.ltq.norspl
549 +ALL-$(CONFIG_SPL_LZO_SUPPORT) += $(obj)u-boot.ltq.lzo.norspl
550 +ALL-$(CONFIG_SPL_LZMA_SUPPORT) += $(obj)u-boot.ltq.lzma.norspl
551 +endif
552 +endif
553 --- /dev/null
554 +++ b/arch/mips/cpu/mips32/danube/ebu.c
555 @@ -0,0 +1,105 @@
556 +/*
557 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
558 + *
559 + * SPDX-License-Identifier:    GPL-2.0+
560 + */
561 +
562 +#include <common.h>
563 +#include <asm/arch/soc.h>
564 +#include <asm/lantiq/io.h>
565 +
566 +#define EBU_ADDRSEL_MASK(mask)         ((mask & 0xf) << 4)
567 +#define EBU_ADDRSEL_REGEN              (1 << 0)
568 +
569 +#define EBU_CON_WRDIS                  (1 << 31)
570 +#define EBU_CON_AGEN_DEMUX             (0x0 << 24)
571 +#define EBU_CON_AGEN_MUX               (0x2 << 24)
572 +#define EBU_CON_SETUP                  (1 << 22)
573 +#define EBU_CON_WAIT_DIS               (0x0 << 20)
574 +#define EBU_CON_WAIT_ASYNC             (0x1 << 20)
575 +#define EBU_CON_WAIT_SYNC              (0x2 << 20)
576 +#define EBU_CON_WINV                   (1 << 19)
577 +#define EBU_CON_PW_8BIT                        (0x0 << 16)
578 +#define EBU_CON_PW_16BIT               (0x1 << 16)
579 +#define EBU_CON_ALEC(cycles)           ((cycles & 0x3) << 14)
580 +#define EBU_CON_BCGEN_CS               (0x0 << 12)
581 +#define EBU_CON_BCGEN_INTEL            (0x1 << 12)
582 +#define EBU_CON_BCGEN_MOTOROLA         (0x2 << 12)
583 +#define EBU_CON_WAITWRC(cycles)                ((cycles & 0x7) << 8)
584 +#define EBU_CON_WAITRDC(cycles)                ((cycles & 0x3) << 6)
585 +#define EBU_CON_HOLDC(cycles)          ((cycles & 0x3) << 4)
586 +#define EBU_CON_RECOVC(cycles)         ((cycles & 0x3) << 2)
587 +#define EBU_CON_CMULT_1                        0x0
588 +#define EBU_CON_CMULT_4                        0x1
589 +#define EBU_CON_CMULT_8                        0x2
590 +#define EBU_CON_CMULT_16               0x3
591 +
592 +#if defined(CONFIG_LTQ_SUPPORT_NOR_FLASH)
593 +#define ebu_region0_enable             1
594 +#else
595 +#define ebu_region0_enable             0
596 +#endif
597 +
598 +#if defined(CONFIG_LTQ_SUPPORT_NAND_FLASH)
599 +#define ebu_region1_enable             1
600 +#else
601 +#define ebu_region1_enable             0
602 +#endif
603 +
604 +struct ltq_ebu_regs {
605 +       u32     clc;
606 +       u32     rsvd0[3];
607 +       u32     con;
608 +       u32     rsvd1[3];
609 +       u32     addr_sel_0;
610 +       u32     addr_sel_1;
611 +       u32     rsvd2[14];
612 +       u32     con_0;
613 +       u32     con_1;
614 +};
615 +
616 +static struct ltq_ebu_regs *ltq_ebu_regs =
617 +       (struct ltq_ebu_regs *) CKSEG1ADDR(LTQ_EBU_BASE);
618 +
619 +void ltq_ebu_init(void)
620 +{
621 +       if (ebu_region0_enable) {
622 +               /*
623 +                * Map EBU region 0 to range 0x10000000-0x13ffffff and enable
624 +                * region control. This supports up to 32 MiB NOR flash in
625 +                * bank 0.
626 +                */
627 +               ltq_writel(&ltq_ebu_regs->addr_sel_0, LTQ_EBU_REGION0_BASE |
628 +                       EBU_ADDRSEL_MASK(1) | EBU_ADDRSEL_REGEN);
629 +
630 +               ltq_writel(&ltq_ebu_regs->con_0, EBU_CON_AGEN_DEMUX |
631 +                       EBU_CON_WAIT_DIS | EBU_CON_PW_16BIT |
632 +                       EBU_CON_ALEC(3) | EBU_CON_BCGEN_INTEL |
633 +                       EBU_CON_WAITWRC(7) | EBU_CON_WAITRDC(3) |
634 +                       EBU_CON_HOLDC(3) | EBU_CON_RECOVC(3) |
635 +                       EBU_CON_CMULT_16);
636 +       } else
637 +               ltq_clrbits(&ltq_ebu_regs->addr_sel_0, EBU_ADDRSEL_REGEN);
638 +
639 +       if (ebu_region1_enable) {
640 +               /*
641 +                * Map EBU region 1 to range 0x14000000-0x13ffffff and enable
642 +                * region control. This supports NAND flash in bank 1.
643 +                */
644 +               ltq_writel(&ltq_ebu_regs->addr_sel_1, LTQ_EBU_REGION1_BASE |
645 +                       EBU_ADDRSEL_MASK(3) | EBU_ADDRSEL_REGEN);
646 +
647 +               ltq_writel(&ltq_ebu_regs->con_1, EBU_CON_AGEN_DEMUX |
648 +                       EBU_CON_SETUP | EBU_CON_WAIT_DIS | EBU_CON_PW_8BIT |
649 +                       EBU_CON_ALEC(3) | EBU_CON_BCGEN_INTEL |
650 +                       EBU_CON_WAITWRC(2) | EBU_CON_WAITRDC(2) |
651 +                       EBU_CON_HOLDC(1) | EBU_CON_RECOVC(1) |
652 +                       EBU_CON_CMULT_4);
653 +       } else
654 +               ltq_clrbits(&ltq_ebu_regs->addr_sel_1, EBU_ADDRSEL_REGEN);
655 +}
656 +
657 +void *flash_swap_addr(unsigned long addr)
658 +{
659 +       return (void *)(addr ^ 2);
660 +}
661 --- /dev/null
662 +++ b/arch/mips/cpu/mips32/danube/mem.c
663 @@ -0,0 +1,30 @@
664 +/*
665 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
666 + *
667 + * SPDX-License-Identifier:    GPL-2.0+
668 + */
669 +
670 +#include <common.h>
671 +#include <asm/arch/soc.h>
672 +#include <asm/lantiq/io.h>
673 +
674 +static void *ltq_mc_ddr_base = (void *) CKSEG1ADDR(LTQ_MC_DDR_BASE);
675 +
676 +static inline u32 ltq_mc_dc_read(u32 index)
677 +{
678 +       return ltq_readl(ltq_mc_ddr_base + LTQ_MC_DDR_DC_OFFSET(index));
679 +}
680 +
681 +phys_size_t initdram(int board_type)
682 +{
683 +       u32 col, row, dc04, dc19, dc20;
684 +
685 +       dc04 = ltq_mc_dc_read(4);
686 +       dc19 = ltq_mc_dc_read(19);
687 +       dc20 = ltq_mc_dc_read(20);
688 +
689 +       row = (dc04 & 0xF) - ((dc19 & 0x700) >> 8);
690 +       col = ((dc04 & 0xF00) >> 8) - (dc20 & 0x7);
691 +
692 +       return (1 << (row + col)) * 4 * 2;
693 +}
694 --- /dev/null
695 +++ b/arch/mips/cpu/mips32/danube/mem_init.S
696 @@ -0,0 +1,114 @@
697 +/*
698 + * Copyright (C) 2007-2010 Lantiq Deutschland GmbH
699 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
700 + *
701 + * SPDX-License-Identifier:    GPL-2.0+
702 + */
703 +
704 +#include <config.h>
705 +#include <asm/asm.h>
706 +#include <asm/regdef.h>
707 +#include <asm/addrspace.h>
708 +#include <asm/arch/soc.h>
709 +
710 +/* Must be configured in BOARDDIR */
711 +#include <ddr_settings.h>
712 +
713 +#define LTQ_MC_GEN_ERRCAUSE            0x0010
714 +#define LTQ_MC_GEN_ERRADDR             0x0020
715 +#define LTQ_MC_GEN_CON                 0x0060
716 +#define LTQ_MC_GEN_STAT                        0x0070
717 +#define LTQ_MC_GEN_CON_SRAM_DDR_ENABLE 0x5
718 +#define LTQ_MC_GEN_STAT_DLCK_PWRON     0xC
719 +
720 +#define LTQ_MC_DDR_DC03_MC_START       0x100
721 +
722 +       /* Store given value in MC DDR CCRx register */
723 +       .macro dc_sw num, val
724 +       li      t2, \val
725 +       sw      t2, LTQ_MC_DDR_DC_OFFSET(\num)(t1)
726 +       .endm
727 +
728 +LEAF(ltq_mem_init)
729 +       /* Load MC General and MC DDR module base */
730 +       li      t0, (LTQ_MC_GEN_BASE | KSEG1)
731 +       li      t1, (LTQ_MC_DDR_BASE | KSEG1)
732 +
733 +       /* Clear access error log registers */
734 +       sw      zero, LTQ_MC_GEN_ERRCAUSE(t0)
735 +       sw      zero, LTQ_MC_GEN_ERRADDR(t0)
736 +
737 +       /* Enable DDR and SRAM module in memory controller */
738 +       li      t2, LTQ_MC_GEN_CON_SRAM_DDR_ENABLE
739 +       sw      t2, LTQ_MC_GEN_CON(t0)
740 +
741 +       /* Clear start bit of DDR memory controller */
742 +       sw      zero, LTQ_MC_DDR_DC_OFFSET(3)(t1)
743 +
744 +       /* Init memory controller registers with values ddr_settings.h */
745 +       dc_sw   0, MC_DC00_VALUE
746 +       dc_sw   1, MC_DC01_VALUE
747 +       dc_sw   2, MC_DC02_VALUE
748 +       dc_sw   4, MC_DC04_VALUE
749 +       dc_sw   5, MC_DC05_VALUE
750 +       dc_sw   6, MC_DC06_VALUE
751 +       dc_sw   7, MC_DC07_VALUE
752 +       dc_sw   8, MC_DC08_VALUE
753 +       dc_sw   9, MC_DC09_VALUE
754 +
755 +       dc_sw   10, MC_DC10_VALUE
756 +       dc_sw   11, MC_DC11_VALUE
757 +       dc_sw   12, MC_DC12_VALUE
758 +       dc_sw   13, MC_DC13_VALUE
759 +       dc_sw   14, MC_DC14_VALUE
760 +       dc_sw   15, MC_DC15_VALUE
761 +       dc_sw   16, MC_DC16_VALUE
762 +       dc_sw   17, MC_DC17_VALUE
763 +       dc_sw   18, MC_DC18_VALUE
764 +       dc_sw   19, MC_DC19_VALUE
765 +
766 +       dc_sw   20, MC_DC20_VALUE
767 +       dc_sw   21, MC_DC21_VALUE
768 +       dc_sw   22, MC_DC22_VALUE
769 +       dc_sw   23, MC_DC23_VALUE
770 +       dc_sw   24, MC_DC24_VALUE
771 +       dc_sw   25, MC_DC25_VALUE
772 +       dc_sw   26, MC_DC26_VALUE
773 +       dc_sw   27, MC_DC27_VALUE
774 +       dc_sw   28, MC_DC28_VALUE
775 +       dc_sw   29, MC_DC29_VALUE
776 +
777 +       dc_sw   30, MC_DC30_VALUE
778 +       dc_sw   31, MC_DC31_VALUE
779 +       dc_sw   32, MC_DC32_VALUE
780 +       dc_sw   33, MC_DC33_VALUE
781 +       dc_sw   34, MC_DC34_VALUE
782 +       dc_sw   35, MC_DC35_VALUE
783 +       dc_sw   36, MC_DC36_VALUE
784 +       dc_sw   37, MC_DC37_VALUE
785 +       dc_sw   38, MC_DC38_VALUE
786 +       dc_sw   39, MC_DC39_VALUE
787 +
788 +       dc_sw   40, MC_DC40_VALUE
789 +       dc_sw   41, MC_DC41_VALUE
790 +       dc_sw   42, MC_DC42_VALUE
791 +       dc_sw   43, MC_DC43_VALUE
792 +       dc_sw   44, MC_DC44_VALUE
793 +       dc_sw   45, MC_DC45_VALUE
794 +       dc_sw   46, MC_DC46_VALUE
795 +
796 +       /* Set start bit of DDR memory controller */
797 +       li      t2, LTQ_MC_DDR_DC03_MC_START
798 +       sw      t2, LTQ_MC_DDR_DC_OFFSET(3)(t1)
799 +
800 +       /* Wait until DLL has locked and core is ready for data transfers */
801 +wait_ready:
802 +       lw      t2, LTQ_MC_GEN_STAT(t0)
803 +       li      t3, LTQ_MC_GEN_STAT_DLCK_PWRON
804 +       and     t2, t3
805 +       bne     t2, t3, wait_ready
806 +
807 +finished:
808 +       jr      ra
809 +
810 +       END(ltq_mem_init)
811 --- /dev/null
812 +++ b/arch/mips/cpu/mips32/danube/pmu.c
813 @@ -0,0 +1,117 @@
814 +/*
815 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
816 + *
817 + * SPDX-License-Identifier:    GPL-2.0+
818 + */
819 +
820 +#include <common.h>
821 +#include <asm/lantiq/io.h>
822 +#include <asm/lantiq/pm.h>
823 +#include <asm/arch/soc.h>
824 +
825 +#define LTQ_PMU_PWDCR_RESERVED         0xFD0C001C
826 +
827 +#define LTQ_PMU_PWDCR_TDM              (1 << 25)
828 +#define LTQ_PMU_PWDCR_PPE_ENET0                (1 << 23)
829 +#define LTQ_PMU_PWDCR_PPE_ENET1                (1 << 22)
830 +#define LTQ_PMU_PWDCR_PPE_TC           (1 << 21)
831 +#define LTQ_PMU_PWDCR_DEU              (1 << 20)
832 +#define LTQ_PMU_PWDCR_UART1            (1 << 17)
833 +#define LTQ_PMU_PWDCR_SDIO             (1 << 16)
834 +#define LTQ_PMU_PWDCR_AHB              (1 << 15)
835 +#define LTQ_PMU_PWDCR_FPI0             (1 << 14)
836 +#define LTQ_PMU_PWDCR_PPE              (1 << 13)
837 +#define LTQ_PMU_PWDCR_GPTC             (1 << 12)
838 +#define LTQ_PMU_PWDCR_LEDC             (1 << 11)
839 +#define LTQ_PMU_PWDCR_EBU              (1 << 10)
840 +#define LTQ_PMU_PWDCR_DSL              (1 << 9)
841 +#define LTQ_PMU_PWDCR_SPI              (1 << 8)
842 +#define LTQ_PMU_PWDCR_UART0            (1 << 7)
843 +#define LTQ_PMU_PWDCR_USB              (1 << 6)
844 +#define LTQ_PMU_PWDCR_DMA              (1 << 5)
845 +#define LTQ_PMU_PWDCR_FPI1             (1 << 1)
846 +#define LTQ_PMU_PWDCR_USB_PHY          (1 << 0)
847 +
848 +struct ltq_pmu_regs {
849 +       u32     rsvd0[7];
850 +       u32     pwdcr;
851 +       u32     sr;
852 +       u32     pwdcr1;
853 +       u32     sr1;
854 +};
855 +
856 +static struct ltq_pmu_regs *ltq_pmu_regs =
857 +       (struct ltq_pmu_regs *) CKSEG1ADDR(LTQ_PMU_BASE);
858 +
859 +u32 ltq_pm_map(enum ltq_pm_modules module)
860 +{
861 +       u32 val;
862 +
863 +       switch (module) {
864 +       case LTQ_PM_CORE:
865 +               val = LTQ_PMU_PWDCR_UART1 | LTQ_PMU_PWDCR_FPI0 |
866 +                       LTQ_PMU_PWDCR_LEDC | LTQ_PMU_PWDCR_EBU;
867 +               break;
868 +       case LTQ_PM_DMA:
869 +               val = LTQ_PMU_PWDCR_DMA;
870 +               break;
871 +       case LTQ_PM_ETH:
872 +               val = LTQ_PMU_PWDCR_PPE_ENET0 | LTQ_PMU_PWDCR_PPE_TC |
873 +                       LTQ_PMU_PWDCR_PPE;
874 +               break;
875 +       case LTQ_PM_SPI:
876 +               val = LTQ_PMU_PWDCR_SPI;
877 +               break;
878 +       default:
879 +               val = 0;
880 +               break;
881 +       }
882 +
883 +       return val;
884 +}
885 +
886 +int ltq_pm_enable(enum ltq_pm_modules module)
887 +{
888 +       const unsigned long timeout = 1000;
889 +       unsigned long timebase;
890 +       u32 sr, val;
891 +
892 +       val = ltq_pm_map(module);
893 +       if (unlikely(!val))
894 +               return 1;
895 +
896 +       ltq_clrbits(&ltq_pmu_regs->pwdcr, val);
897 +
898 +       timebase = get_timer(0);
899 +
900 +       do {
901 +               sr = ltq_readl(&ltq_pmu_regs->sr);
902 +               if (~sr & val)
903 +                       return 0;
904 +       } while (get_timer(timebase) < timeout);
905 +
906 +       return 1;
907 +}
908 +
909 +int ltq_pm_disable(enum ltq_pm_modules module)
910 +{
911 +       u32 val;
912 +
913 +       val = ltq_pm_map(module);
914 +       if (unlikely(!val))
915 +               return 1;
916 +
917 +       ltq_setbits(&ltq_pmu_regs->pwdcr, val);
918 +
919 +       return 0;
920 +}
921 +
922 +void ltq_pmu_init(void)
923 +{
924 +       u32 set, clr;
925 +
926 +       clr = ltq_pm_map(LTQ_PM_CORE);
927 +       set = ~(LTQ_PMU_PWDCR_RESERVED | clr);
928 +
929 +       ltq_clrsetbits(&ltq_pmu_regs->pwdcr, clr, set);
930 +}
931 --- /dev/null
932 +++ b/arch/mips/cpu/mips32/danube/rcu.c
933 @@ -0,0 +1,125 @@
934 +/*
935 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
936 + *
937 + * SPDX-License-Identifier:    GPL-2.0+
938 + */
939 +
940 +#include <common.h>
941 +#include <asm/lantiq/io.h>
942 +#include <asm/lantiq/reset.h>
943 +#include <asm/lantiq/cpu.h>
944 +#include <asm/arch/soc.h>
945 +
946 +#define LTQ_RCU_RD_SRST                (1 << 30)       /* Global SW Reset */
947 +#define LTQ_RCU_RD_MC          (1 << 14)       /* Memory Controller */
948 +#define LTQ_RCU_RD_PCI         (1 << 13)       /* PCI core */
949 +#define LTQ_RCU_RD_DFE_AFE     (1 << 12)       /* Voice DFE/AFE */
950 +#define LTQ_RCU_RD_DSL_AFE     (1 << 11)       /* DSL AFE */
951 +#define LTQ_RCU_RD_SDIO                (1 << 10)       /* SDIO core */
952 +#define LTQ_RCU_RD_DMA         (1 << 9)        /* DMA core */
953 +#define LTQ_RCU_RD_PPE         (1 << 8)        /* PPE core */
954 +#define LTQ_RCU_RD_ARC_DFE     (1 << 7)        /* ARC/DFE core */
955 +#define LTQ_RCU_RD_AHB         (1 << 6)        /* AHB bus */
956 +#define LTQ_RCU_RD_ENET_MAC1   (1 << 5)        /* Ethernet MAC1 */
957 +#define LTQ_RCU_RD_USB         (1 << 4)        /* USB and Phy core */
958 +#define LTQ_RCU_RD_CPU1                (1 << 3)        /* CPU1 subsystem */
959 +#define LTQ_RCU_RD_FPI         (1 << 2)        /* FPI bus */
960 +#define LTQ_RCU_RD_CPU0                (1 << 1)        /* CPU0 subsystem */
961 +#define LTQ_RCU_RD_HRST                (1 << 0)        /* HW reset via HRST pin */
962 +
963 +#define LTQ_RCU_STAT_BOOT_SHIFT                18
964 +#define LTQ_RCU_STAT_BOOT_MASK         (0x7 << LTQ_RCU_STAT_BOOT_SHIFT)
965 +
966 +struct ltq_rcu_regs {
967 +       u32     rsvd0[4];
968 +       u32     req;            /* Reset request */
969 +       u32     stat;           /* Reset status */
970 +       u32     usb_cfg;        /* USB configure */
971 +       u32     rsvd1[2];
972 +       u32     pci_rdy;        /* PCI boot ready */
973 +};
974 +
975 +static struct ltq_rcu_regs *ltq_rcu_regs =
976 +       (struct ltq_rcu_regs *) CKSEG1ADDR(LTQ_RCU_BASE);
977 +
978 +u32 ltq_reset_map(enum ltq_reset_modules module)
979 +{
980 +       u32 val;
981 +
982 +       switch (module) {
983 +       case LTQ_RESET_CORE:
984 +       case LTQ_RESET_SOFT:
985 +               val = LTQ_RCU_RD_SRST | LTQ_RCU_RD_CPU1;
986 +               break;
987 +       case LTQ_RESET_DMA:
988 +               val = LTQ_RCU_RD_DMA;
989 +               break;
990 +       case LTQ_RESET_ETH:
991 +               val = LTQ_RCU_RD_PPE;
992 +               break;
993 +       case LTQ_RESET_HARD:
994 +               val = LTQ_RCU_RD_HRST;
995 +               break;
996 +       default:
997 +               val = 0;
998 +               break;
999 +       }
1000 +
1001 +       return val;
1002 +}
1003 +
1004 +int ltq_reset_activate(enum ltq_reset_modules module)
1005 +{
1006 +       u32 val;
1007 +
1008 +       val = ltq_reset_map(module);
1009 +       if (unlikely(!val))
1010 +               return 1;
1011 +
1012 +       ltq_setbits(&ltq_rcu_regs->req, val);
1013 +
1014 +       return 0;
1015 +}
1016 +
1017 +int ltq_reset_deactivate(enum ltq_reset_modules module)
1018 +{
1019 +       u32 val;
1020 +
1021 +       val = ltq_reset_map(module);
1022 +       if (unlikely(!val))
1023 +               return 1;
1024 +
1025 +       ltq_clrbits(&ltq_rcu_regs->req, val);
1026 +
1027 +       return 0;
1028 +}
1029 +
1030 +enum ltq_boot_select ltq_boot_select(void)
1031 +{
1032 +       u32 stat;
1033 +       unsigned int bootstrap;
1034 +
1035 +       stat = ltq_readl(&ltq_rcu_regs->stat);
1036 +       bootstrap = (stat & LTQ_RCU_STAT_BOOT_MASK) >> LTQ_RCU_STAT_BOOT_SHIFT;
1037 +
1038 +       switch (bootstrap) {
1039 +       case 0:
1040 +               return BOOT_NOR_NO_BOOTROM;
1041 +       case 1:
1042 +               return BOOT_NOR;
1043 +       case 2:
1044 +               return BOOT_MII0;
1045 +       case 3:
1046 +               return BOOT_PCI;
1047 +       case 4:
1048 +               return BOOT_UART;
1049 +       case 5:
1050 +               return BOOT_SPI;
1051 +       case 6:
1052 +               return BOOT_NAND;
1053 +       case 7:
1054 +               return BOOT_RMII0;
1055 +       default:
1056 +               return BOOT_UNKNOWN;
1057 +       }
1058 +}
1059 --- /dev/null
1060 +++ b/arch/mips/cpu/mips32/lantiq-common/Makefile
1061 @@ -0,0 +1,34 @@
1062 +#
1063 +# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de
1064 +#
1065 +# SPDX-License-Identifier:     GPL-2.0+
1066 +#
1067 +
1068 +include $(TOPDIR)/config.mk
1069 +
1070 +LIB    = $(obj)liblantiq-common.o
1071 +
1072 +START  = start.o
1073 +COBJS-y        = cpu.o pmu.o
1074 +COBJS-$(CONFIG_SPL_BUILD) += spl.o
1075 +SOBJS-y        = lowlevel_init.o
1076 +
1077 +COBJS  := $(COBJS-y)
1078 +SOBJS  := $(SOBJS-y)
1079 +SRCS   := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
1080 +OBJS   := $(addprefix $(obj),$(SOBJS) $(COBJS))
1081 +START  := $(addprefix $(obj),$(START))
1082 +
1083 +all:   $(LIB)
1084 +
1085 +$(LIB):        $(obj).depend $(OBJS)
1086 +       $(call cmd_link_o_target, $(OBJS))
1087 +
1088 +#########################################################################
1089 +
1090 +# defines $(obj).depend target
1091 +include $(SRCTREE)/rules.mk
1092 +
1093 +sinclude $(obj).depend
1094 +
1095 +#########################################################################
1096 --- /dev/null
1097 +++ b/arch/mips/cpu/mips32/lantiq-common/cpu.c
1098 @@ -0,0 +1,59 @@
1099 +/*
1100 + * Copyright (C) 2012-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
1101 + *
1102 + * SPDX-License-Identifier:    GPL-2.0+
1103 + */
1104 +
1105 +#include <common.h>
1106 +#include <asm/lantiq/chipid.h>
1107 +#include <asm/lantiq/clk.h>
1108 +#include <asm/lantiq/reset.h>
1109 +#include <asm/lantiq/cpu.h>
1110 +
1111 +static const char ltq_bootsel_strings[][16] = {
1112 +       "NOR",
1113 +       "NOR w/o BootROM",
1114 +       "UART",
1115 +       "UART w/o EEPROM",
1116 +       "SPI",
1117 +       "NAND",
1118 +       "PCI",
1119 +       "MII0",
1120 +       "RMII0",
1121 +       "RGMII1",
1122 +       "unknown",
1123 +};
1124 +
1125 +const char *ltq_boot_select_str(void)
1126 +{      enum ltq_boot_select bootsel = ltq_boot_select();
1127 +
1128 +       if (bootsel > BOOT_UNKNOWN)
1129 +               bootsel = BOOT_UNKNOWN;
1130 +
1131 +       return ltq_bootsel_strings[bootsel];
1132 +}
1133 +
1134 +void ltq_chip_print_info(void)
1135 +{
1136 +       char buf[32];
1137 +
1138 +       printf("SoC:   Lantiq %s v1.%u\n", ltq_chip_partnum_str(),
1139 +               ltq_chip_version_get());
1140 +       printf("CPU:   %s MHz\n", strmhz(buf, ltq_get_cpu_clock()));
1141 +       printf("IO:    %s MHz\n", strmhz(buf, ltq_get_io_region_clock()));
1142 +       printf("BUS:   %s MHz\n", strmhz(buf, ltq_get_bus_clock()));
1143 +       printf("BOOT:  %s\n", ltq_boot_select_str());
1144 +}
1145 +
1146 +int arch_cpu_init(void)
1147 +{
1148 +       ltq_pmu_init();
1149 +       ltq_ebu_init();
1150 +
1151 +       return 0;
1152 +}
1153 +
1154 +void _machine_restart(void)
1155 +{
1156 +       ltq_reset_activate(LTQ_RESET_CORE);
1157 +}
1158 --- /dev/null
1159 +++ b/arch/mips/cpu/mips32/lantiq-common/lowlevel_init.S
1160 @@ -0,0 +1,20 @@
1161 +/*
1162 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
1163 + *
1164 + * SPDX-License-Identifier:    GPL-2.0+
1165 + */
1166 +
1167 +#include <asm/asm.h>
1168 +#include <asm/regdef.h>
1169 +
1170 +NESTED(lowlevel_init, 0, ra)
1171 +       move    t8, ra
1172 +
1173 +       la      t7, ltq_cgu_init
1174 +       jalr    t7
1175 +
1176 +       la      t7, ltq_mem_init
1177 +       jalr    t7
1178 +
1179 +       jr      t8
1180 +       END(lowlevel_init)
1181 --- /dev/null
1182 +++ b/arch/mips/cpu/mips32/lantiq-common/pmu.c
1183 @@ -0,0 +1,9 @@
1184 +/*
1185 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
1186 + *
1187 + * SPDX-License-Identifier:    GPL-2.0+
1188 + */
1189 +
1190 +#include <common.h>
1191 +#include <asm/lantiq/pm.h>
1192 +
1193 --- /dev/null
1194 +++ b/arch/mips/cpu/mips32/lantiq-common/spl.c
1195 @@ -0,0 +1,403 @@
1196 +/*
1197 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
1198 + *
1199 + * SPDX-License-Identifier:    GPL-2.0+
1200 + */
1201 +
1202 +#include <common.h>
1203 +#include <image.h>
1204 +#include <version.h>
1205 +#include <spi_flash.h>
1206 +#include <linux/compiler.h>
1207 +#include <lzma/LzmaDec.h>
1208 +#include <linux/lzo.h>
1209 +#include <asm/mipsregs.h>
1210 +
1211 +#if defined(CONFIG_LTQ_SPL_CONSOLE)
1212 +#define spl_has_console                1
1213 +
1214 +#if defined(CONFIG_LTQ_SPL_DEBUG)
1215 +#define spl_has_debug          1
1216 +#else
1217 +#define spl_has_debug          0
1218 +#endif
1219 +
1220 +#else
1221 +#define spl_has_console                0
1222 +#define spl_has_debug          0
1223 +#endif
1224 +
1225 +#define spl_debug(fmt, args...)                        \
1226 +       do {                                    \
1227 +               if (spl_has_debug)              \
1228 +                       printf(fmt, ##args);    \
1229 +       } while (0)
1230 +
1231 +#define spl_puts(msg)                          \
1232 +       do {                                    \
1233 +               if (spl_has_console)            \
1234 +                       puts(msg);              \
1235 +       } while (0)
1236 +
1237 +#if defined(CONFIG_LTQ_SUPPORT_SPL_SPI_FLASH) && defined(CONFIG_SYS_BOOT_SFSPL)
1238 +#define spl_boot_spi_flash     1
1239 +#else
1240 +#define spl_boot_spi_flash     0
1241 +#ifndef CONFIG_SPL_SPI_BUS
1242 +#define CONFIG_SPL_SPI_BUS     0
1243 +#endif
1244 +#ifndef CONFIG_SPL_SPI_CS
1245 +#define CONFIG_SPL_SPI_CS      0
1246 +#endif
1247 +#ifndef CONFIG_SPL_SPI_MAX_HZ
1248 +#define CONFIG_SPL_SPI_MAX_HZ  0
1249 +#endif
1250 +#ifndef CONFIG_SPL_SPI_MODE
1251 +#define CONFIG_SPL_SPI_MODE    0
1252 +#endif
1253 +#endif
1254 +
1255 +#if defined(CONFIG_LTQ_SUPPORT_SPL_NOR_FLASH) && defined(CONFIG_SYS_BOOT_NORSPL)
1256 +#define spl_boot_nor_flash     1
1257 +#else
1258 +#define spl_boot_nor_flash     0
1259 +#endif
1260 +
1261 +#define spl_sync()     __asm__ __volatile__("sync");
1262 +
1263 +struct spl_image {
1264 +       ulong data_addr;
1265 +       ulong entry_addr;
1266 +       ulong data_size;
1267 +       ulong entry_size;
1268 +       ulong data_crc;
1269 +       u8 comp;
1270 +};
1271 +
1272 +DECLARE_GLOBAL_DATA_PTR;
1273 +
1274 +/* Emulated malloc area needed for LZMA allocator in BSS */
1275 +static u8 *spl_mem_ptr __maybe_unused;
1276 +static size_t spl_mem_size __maybe_unused;
1277 +
1278 +static int spl_is_comp_lzma(const struct spl_image *spl)
1279 +{
1280 +#if defined(CONFIG_LTQ_SPL_COMP_LZMA)
1281 +       return spl->comp == IH_COMP_LZMA;
1282 +#else
1283 +       return 0;
1284 +#endif
1285 +}
1286 +
1287 +static int spl_is_comp_lzo(const struct spl_image *spl)
1288 +{
1289 +#if defined(CONFIG_LTQ_SPL_COMP_LZO)
1290 +       return spl->comp == IH_COMP_LZO;
1291 +#else
1292 +       return 0;
1293 +#endif
1294 +}
1295 +
1296 +static int spl_is_compressed(const struct spl_image *spl)
1297 +{
1298 +       if (spl_is_comp_lzma(spl))
1299 +               return 1;
1300 +
1301 +       if (spl_is_comp_lzo(spl))
1302 +               return 1;
1303 +
1304 +       return 0;
1305 +}
1306 +
1307 +static void spl_console_init(void)
1308 +{
1309 +       if (!spl_has_console)
1310 +               return;
1311 +
1312 +       gd->flags |= GD_FLG_RELOC;
1313 +       gd->baudrate = CONFIG_BAUDRATE;
1314 +
1315 +       serial_init();
1316 +
1317 +       gd->have_console = 1;
1318 +
1319 +       spl_puts("\nU-Boot SPL " PLAIN_VERSION " (" U_BOOT_DATE " - " \
1320 +               U_BOOT_TIME ")\n");
1321 +}
1322 +
1323 +static int spl_parse_image(const image_header_t *hdr, struct spl_image *spl)
1324 +{
1325 +       spl_puts("SPL: checking U-Boot image\n");
1326 +
1327 +       if (!image_check_magic(hdr)) {
1328 +               spl_puts("SPL: invalid magic\n");
1329 +               return -1;
1330 +       }
1331 +
1332 +        if (!image_check_hcrc(hdr)) {
1333 +               spl_puts("SPL: invalid header CRC\n");
1334 +               return -1;
1335 +       }
1336 +
1337 +       spl->data_addr += image_get_header_size();
1338 +       spl->entry_addr = image_get_load(hdr);
1339 +       spl->data_size = image_get_data_size(hdr);
1340 +       spl->data_crc = image_get_dcrc(hdr);
1341 +       spl->comp = image_get_comp(hdr);
1342 +
1343 +       spl_debug("SPL: data %08lx, size %lu, entry %08lx, comp %u\n",
1344 +               spl->data_addr, spl->data_size, spl->entry_addr, spl->comp);
1345 +
1346 +       return 0;
1347 +}
1348 +
1349 +static int spl_check_data(const struct spl_image *spl, ulong loadaddr)
1350 +{
1351 +       ulong dcrc = crc32(0, (unsigned char *)loadaddr, spl->data_size);
1352 +
1353 +       if (dcrc != spl->data_crc) {
1354 +               spl_puts("SPL: invalid data CRC\n");
1355 +               return 0;
1356 +       }
1357 +
1358 +       return 1;
1359 +}
1360 +
1361 +static void *spl_lzma_alloc(void *p, size_t size)
1362 +{
1363 +       u8 *ret;
1364 +
1365 +       if (size > spl_mem_size)
1366 +               return NULL;
1367 +
1368 +       ret = spl_mem_ptr;
1369 +       spl_mem_ptr += size;
1370 +       spl_mem_size -= size;
1371 +
1372 +       return ret;
1373 +}
1374 +
1375 +static void spl_lzma_free(void *p, void *addr)
1376 +{
1377 +}
1378 +
1379 +static int spl_copy_image(struct spl_image *spl)
1380 +{
1381 +       spl_puts("SPL: copying U-Boot to RAM\n");
1382 +
1383 +       memcpy((void *) spl->entry_addr, (const void *) spl->data_addr,
1384 +               spl->data_size);
1385 +
1386 +       spl->entry_size = spl->data_size;
1387 +
1388 +       return 0;
1389 +}
1390 +
1391 +static int spl_uncompress_lzma(struct spl_image *spl, unsigned long loadaddr)
1392 +{
1393 +       SRes res;
1394 +       const Byte *prop = (const Byte *) loadaddr;
1395 +       const Byte *src = (const Byte *) loadaddr + LZMA_PROPS_SIZE +
1396 +                                                       sizeof(uint64_t);
1397 +       Byte *dest = (Byte *) spl->entry_addr;
1398 +       SizeT dest_len = 0xFFFFFFFF;
1399 +       SizeT src_len = spl->data_size - LZMA_PROPS_SIZE;
1400 +       ELzmaStatus status = 0;
1401 +       ISzAlloc alloc;
1402 +
1403 +       spl_puts("SPL: decompressing U-Boot with LZMA\n");
1404 +
1405 +       alloc.Alloc = spl_lzma_alloc;
1406 +       alloc.Free = spl_lzma_free;
1407 +       spl_mem_ptr = (u8 *) CONFIG_SPL_MALLOC_BASE;
1408 +       spl_mem_size = CONFIG_SPL_MALLOC_MAX_SIZE;
1409 +
1410 +       res = LzmaDecode(dest, &dest_len, src, &src_len, prop, LZMA_PROPS_SIZE,
1411 +               LZMA_FINISH_ANY, &status, &alloc);
1412 +       if (res != SZ_OK)
1413 +               return 1;
1414 +
1415 +       spl->entry_size = dest_len;
1416 +
1417 +       return 0;
1418 +}
1419 +
1420 +static int spl_uncompress_lzo(struct spl_image *spl, unsigned long loadaddr)
1421 +{
1422 +       size_t len;
1423 +       int ret;
1424 +
1425 +       spl_puts("SPL: decompressing U-Boot with LZO\n");
1426 +
1427 +       ret = lzop_decompress(
1428 +               (const unsigned char*) loadaddr, spl->data_size,
1429 +               (unsigned char *) spl->entry_addr, &len);
1430 +
1431 +       spl->entry_size = len;
1432 +
1433 +       return ret;
1434 +}
1435 +
1436 +static int spl_uncompress(struct spl_image *spl, unsigned long loadaddr)
1437 +{
1438 +       int ret;
1439 +
1440 +       if (spl_is_comp_lzma(spl))
1441 +               ret = spl_uncompress_lzma(spl, loadaddr);
1442 +       else if (spl_is_comp_lzo(spl))
1443 +               ret = spl_uncompress_lzo(spl, loadaddr);
1444 +       else
1445 +               ret = 1;
1446 +
1447 +       return ret;
1448 +}
1449 +
1450 +static int spl_load_spi_flash(struct spl_image *spl)
1451 +{
1452 +       struct spi_flash sf = { 0 };
1453 +       image_header_t hdr;
1454 +       int ret;
1455 +       unsigned long loadaddr;
1456 +
1457 +       /*
1458 +        * Image format:
1459 +        *
1460 +        * - 12 byte non-volatile bootstrap header
1461 +        * - SPL binary
1462 +        * - 12 byte non-volatile bootstrap header
1463 +        * - 64 byte U-Boot mkimage header
1464 +        * - U-Boot binary
1465 +        */
1466 +       spl->data_addr = image_copy_end() - CONFIG_SPL_TEXT_BASE + 24;
1467 +
1468 +       spl_puts("SPL: probing SPI flash\n");
1469 +
1470 +       spi_init();
1471 +       ret = spl_spi_flash_probe(&sf);
1472 +       if (ret)
1473 +               return ret;
1474 +
1475 +       spl_debug("SPL: reading image header at offset %lx\n", spl->data_addr);
1476 +
1477 +       ret = spi_flash_read(&sf, spl->data_addr, sizeof(hdr), &hdr);
1478 +       if (ret)
1479 +               return ret;
1480 +
1481 +       spl_debug("SPL: checking image header at offset %lx\n", spl->data_addr);
1482 +
1483 +       ret = spl_parse_image(&hdr, spl);
1484 +       if (ret)
1485 +               return ret;
1486 +
1487 +       if (spl_is_compressed(spl))
1488 +               loadaddr = CONFIG_LOADADDR;
1489 +       else
1490 +               loadaddr = spl->entry_addr;
1491 +
1492 +       spl_puts("SPL: loading U-Boot to RAM\n");
1493 +
1494 +       ret = spi_flash_read(&sf, spl->data_addr, spl->data_size,
1495 +                               (void *) loadaddr);
1496 +
1497 +       if (!spl_check_data(spl, loadaddr))
1498 +               return -1;
1499 +
1500 +       if (spl_is_compressed(spl))
1501 +               ret = spl_uncompress(spl, loadaddr);
1502 +
1503 +       return ret;
1504 +}
1505 +
1506 +static int spl_load_nor_flash(struct spl_image *spl)
1507 +{
1508 +       const image_header_t *hdr;
1509 +       int ret;
1510 +
1511 +       /*
1512 +        * Image format:
1513 +        *
1514 +        * - SPL binary
1515 +        * - 64 byte U-Boot mkimage header
1516 +        * - U-Boot binary
1517 +        */
1518 +       spl->data_addr = image_copy_end();
1519 +       hdr = (const image_header_t *) image_copy_end();
1520 +
1521 +       spl_debug("SPL: checking image header at address %p\n", hdr);
1522 +
1523 +       ret = spl_parse_image(hdr, spl);
1524 +       if (ret)
1525 +               return ret;
1526 +
1527 +       if (spl_is_compressed(spl))
1528 +               ret = spl_uncompress(spl, spl->data_addr);
1529 +       else
1530 +               ret = spl_copy_image(spl);
1531 +
1532 +       return ret;
1533 +}
1534 +
1535 +static int spl_load(struct spl_image *spl)
1536 +{
1537 +       int ret;
1538 +
1539 +       if (spl_boot_spi_flash)
1540 +               ret = spl_load_spi_flash(spl);
1541 +       else if (spl_boot_nor_flash)
1542 +               ret = spl_load_nor_flash(spl);
1543 +       else
1544 +               ret = 1;
1545 +
1546 +       return ret;
1547 +}
1548 +
1549 +void __noreturn spl_lantiq_init(void)
1550 +{
1551 +       void (*uboot)(void) __noreturn;
1552 +       struct spl_image spl;
1553 +       gd_t gd_data;
1554 +       int ret;
1555 +
1556 +       gd = &gd_data;
1557 +       barrier();
1558 +       memset((void *)gd, 0, sizeof(gd_t));
1559 +
1560 +       spl_console_init();
1561 +
1562 +       spl_debug("SPL: initializing\n");
1563 +
1564 +#if 0
1565 +       spl_debug("CP0_CONFIG:   %08x\n", read_c0_config());
1566 +       spl_debug("CP0_CONFIG1:  %08x\n", read_c0_config1());
1567 +       spl_debug("CP0_CONFIG2:  %08x\n", read_c0_config2());
1568 +       spl_debug("CP0_CONFIG3:  %08x\n", read_c0_config3());
1569 +       spl_debug("CP0_CONFIG6:  %08x\n", read_c0_config6());
1570 +       spl_debug("CP0_CONFIG7:  %08x\n", read_c0_config7());
1571 +       spl_debug("CP0_STATUS:   %08x\n", read_c0_status());
1572 +       spl_debug("CP0_PRID:     %08x\n", read_c0_prid());
1573 +#endif
1574 +
1575 +       board_early_init_f();
1576 +       timer_init();
1577 +
1578 +       memset(&spl, 0, sizeof(spl));
1579 +
1580 +       ret = spl_load(&spl);
1581 +       if (ret)
1582 +               goto hang;
1583 +
1584 +       spl_debug("SPL: U-Boot entry %08lx\n", spl.entry_addr);
1585 +       spl_puts("SPL: jumping to U-Boot\n");
1586 +
1587 +       flush_cache(spl.entry_addr, spl.entry_size);
1588 +       spl_sync();
1589 +
1590 +       uboot = (void *) spl.entry_addr;
1591 +       uboot();
1592 +
1593 +hang:
1594 +       spl_puts("SPL: cannot start U-Boot\n");
1595 +
1596 +       for (;;)
1597 +               ;
1598 +}
1599 --- /dev/null
1600 +++ b/arch/mips/cpu/mips32/lantiq-common/start.S
1601 @@ -0,0 +1,143 @@
1602 +/*
1603 + * Copyright (C) 2010 Lantiq Deutschland GmbH
1604 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
1605 + *
1606 + * SPDX-License-Identifier:    GPL-2.0+
1607 + */
1608 +
1609 +#include <config.h>
1610 +#include <asm/regdef.h>
1611 +#include <asm/mipsregs.h>
1612 +
1613 +#define S_PRIdCoID     16              /* Company ID (R) */
1614 +#define M_PRIdCoID     (0xff << S_PRIdCoID)
1615 +#define S_PRIdImp      8               /* Implementation ID (R) */
1616 +#define M_PRIdImp      (0xff << S_PRIdImp)
1617 +
1618 +#define K_CacheAttrCWTnWA      0       /* Cacheable, write-thru, no write allocate */
1619 +#define K_CacheAttrCWTWA       1       /* Cacheable, write-thru, write allocate */
1620 +#define K_CacheAttrU           2       /* Uncached */
1621 +#define K_CacheAttrC           3       /* Cacheable */
1622 +#define K_CacheAttrCN          3       /* Cacheable, non-coherent */
1623 +#define K_CacheAttrCCE         4       /* Cacheable, coherent, exclusive */
1624 +#define K_CacheAttrCCS         5       /* Cacheable, coherent, shared */
1625 +#define K_CacheAttrCCU         6       /* Cacheable, coherent, update */
1626 +#define K_CacheAttrUA          7       /* Uncached accelerated */
1627 +
1628 +#define S_ConfigK23            28      /* Kseg2/3 coherency algorithm (FM MMU only) (R/W) */
1629 +#define M_ConfigK23            (0x7 << S_ConfigK23)
1630 +#define W_ConfigK23            3
1631 +#define S_ConfigKU             25      /* Kuseg coherency algorithm (FM MMU only) (R/W) */
1632 +#define M_ConfigKU             (0x7 << S_ConfigKU)
1633 +#define W_ConfigKU             3
1634 +
1635 +#define S_ConfigMM             18      /* Merge mode (implementation specific) */
1636 +#define M_ConfigMM             (0x1 << S_ConfigMM)
1637 +
1638 +#define S_StatusBEV            22      /* Enable Boot Exception Vectors (R/W) */
1639 +#define M_StatusBEV            (0x1 << S_StatusBEV)
1640 +
1641 +#define S_StatusFR             26      /* Enable 64-bit FPRs (R/W) */
1642 +#define M_StatusFR             (0x1 << S_StatusFR)
1643 +
1644 +#define S_ConfigK0             0       /* Kseg0 coherency algorithm (R/W) */
1645 +#define M_ConfigK0             (0x7 << S_ConfigK0)
1646 +
1647 +#define CONFIG0_MIPS32_64_MSK  0x8000ffff
1648 +#define STATUS_MIPS32_64_MSK   0xfffcffff
1649 +
1650 +#define STATUS_MIPS24K         0
1651 +#define CONFIG0_MIPS24K                ((K_CacheAttrCN << S_ConfigK23) |\
1652 +                               (K_CacheAttrCN << S_ConfigKU)  |\
1653 +                               (M_ConfigMM))
1654 +
1655 +#define STATUS_MIPS34K         0
1656 +#define CONFIG0_MIPS34K                ((K_CacheAttrCN << S_ConfigK23) |\
1657 +                               (K_CacheAttrCN << S_ConfigKU) |\
1658 +                               (M_ConfigMM))
1659 +
1660 +#define STATUS_MIPS32_64       (M_StatusBEV | M_StatusFR)
1661 +#define CONFIG0_MIPS32_64      (K_CacheAttrCN << S_ConfigK0)
1662 +
1663 +#ifdef CONFIG_SOC_XWAY_DANUBE
1664 +#define CONFIG0_LANTIQ         (CONFIG0_MIPS24K | CONFIG0_MIPS32_64)
1665 +#define STATUS_LANTIQ          (STATUS_MIPS24K | STATUS_MIPS32_64)
1666 +#endif
1667 +
1668 +#ifdef CONFIG_SOC_XWAY_VRX200
1669 +#define CONFIG0_LANTIQ         (CONFIG0_MIPS34K | CONFIG0_MIPS32_64)
1670 +#define STATUS_LANTIQ          (STATUS_MIPS34K | STATUS_MIPS32_64)
1671 +#endif
1672 +
1673 +
1674 +       .set noreorder
1675 +
1676 +       .globl _start
1677 +       .text
1678 +_start:
1679 +       /* Entry point */
1680 +       b       main
1681 +        nop
1682 +
1683 +       /* Lantiq SoC Boot config word */
1684 +       .org    0x10
1685 +#ifdef CONFIG_SYS_XWAY_EBU_BOOTCFG
1686 +       .word   CONFIG_SYS_XWAY_EBU_BOOTCFG
1687 +#else
1688 +       .word   0
1689 +#endif
1690 +       .word   0
1691 +
1692 +       .align  4
1693 +main:
1694 +
1695 +       /* Init Timer */
1696 +       mtc0    zero, CP0_COUNT
1697 +       mtc0    zero, CP0_COMPARE
1698 +
1699 +       /* Setup MIPS24K/MIPS34K specifics (implementation dependent fields) */
1700 +       mfc0    t0, CP0_CONFIG
1701 +       li      t1, CONFIG0_MIPS32_64_MSK
1702 +       and     t0, t1
1703 +       li      t1, CONFIG0_LANTIQ
1704 +       or      t0, t1
1705 +       mtc0    t0, CP0_CONFIG
1706 +
1707 +       mfc0    t0, CP0_STATUS
1708 +       li      t1, STATUS_MIPS32_64_MSK
1709 +       and     t0, t1
1710 +       li      t1, STATUS_LANTIQ
1711 +       or      t0, t1
1712 +       mtc0    t0, CP0_STATUS
1713 +
1714 +       /* Initialize CGU */
1715 +       la      t9, ltq_cgu_init
1716 +       jalr    t9
1717 +        nop
1718 +
1719 +       /* Initialize memory controller */
1720 +       la      t9, ltq_mem_init
1721 +       jalr    t9
1722 +        nop
1723 +
1724 +       /* Initialize caches... */
1725 +       la      t9, mips_cache_reset
1726 +       jalr    t9
1727 +        nop
1728 +
1729 +       /* Clear BSS */
1730 +       la      t1, __bss_start
1731 +       la      t2, __bss_end
1732 +       sub     t1, 4
1733 +1:
1734 +       addi    t1, 4
1735 +       bltl    t1, t2, 1b
1736 +        sw     zero, 0(t1)
1737 +
1738 +       /* Setup stack pointer and force alignment on a 16 byte boundary */
1739 +       li      t0, (CONFIG_SPL_STACK_BASE & ~0xF)
1740 +       la      sp, 0(t0)
1741 +
1742 +       la      t9, spl_lantiq_init
1743 +       jr      t9
1744 +        nop
1745 --- /dev/null
1746 +++ b/arch/mips/cpu/mips32/lantiq-common/u-boot-spl.lds
1747 @@ -0,0 +1,48 @@
1748 +/*
1749 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
1750 + *
1751 + * SPDX-License-Identifier:    GPL-2.0+
1752 + */
1753 +
1754 +MEMORY { .spl_mem : ORIGIN = CONFIG_SPL_TEXT_BASE, \
1755 +               LENGTH = CONFIG_SPL_MAX_SIZE }
1756 +MEMORY { .bss_mem : ORIGIN = CONFIG_SPL_BSS_BASE, \
1757 +               LENGTH = CONFIG_SPL_BSS_MAX_SIZE }
1758 +
1759 +OUTPUT_FORMAT("elf32-tradbigmips", "elf32-tradbigmips", "elf32-tradlittlemips")
1760 +OUTPUT_ARCH(mips)
1761 +ENTRY(_start)
1762 +SECTIONS
1763 +{
1764 +       . = ALIGN(4);
1765 +       .text : {
1766 +               *(.text*)
1767 +       } > .spl_mem
1768 +
1769 +       . = ALIGN(4);
1770 +       .rodata : {
1771 +               *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*)))
1772 +       } > .spl_mem
1773 +
1774 +       . = ALIGN(4);
1775 +       .data : {
1776 +               *(SORT_BY_ALIGNMENT(.data*))
1777 +               *(SORT_BY_ALIGNMENT(.sdata*))
1778 +       } > .spl_mem
1779 +
1780 +       . = ALIGN(4);
1781 +       __image_copy_end = .;
1782 +       uboot_end_data = .;
1783 +
1784 +       .bss : {
1785 +               __bss_start = .;
1786 +               *(.bss*)
1787 +               *(.sbss*)
1788 +               . = ALIGN(4);
1789 +               __bss_end = .;
1790 +       } > .bss_mem
1791 +
1792 +       . = ALIGN(4);
1793 +       __end = .;
1794 +       uboot_end = .;
1795 +}
1796 --- a/arch/mips/cpu/mips32/start.S
1797 +++ b/arch/mips/cpu/mips32/start.S
1798 @@ -105,7 +105,7 @@ reset:
1799         mtc0    zero, CP0_COUNT
1800         mtc0    zero, CP0_COMPARE
1801  
1802 -#ifndef CONFIG_SKIP_LOWLEVEL_INIT
1803 +#if !defined(CONFIG_SKIP_LOWLEVEL_INIT) || defined(CONFIG_SYS_DISABLE_CACHE)
1804         /* CONFIG0 register */
1805         li      t0, CONF_CM_UNCACHED
1806         mtc0    t0, CP0_CONFIG
1807 --- /dev/null
1808 +++ b/arch/mips/cpu/mips32/vrx200/Makefile
1809 @@ -0,0 +1,32 @@
1810 +#
1811 +# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de
1812 +#
1813 +# SPDX-License-Identifier:     GPL-2.0+
1814 +#
1815 +
1816 +include $(TOPDIR)/config.mk
1817 +
1818 +LIB    = $(obj)lib$(SOC).o
1819 +
1820 +COBJS-y        += cgu.o chipid.o dcdc.o ebu.o gphy.o mem.o pmu.o rcu.o
1821 +SOBJS-y        += cgu_init.o mem_init.o
1822 +SOBJS-y        += gphy_fw.o
1823 +
1824 +COBJS  := $(COBJS-y)
1825 +SOBJS  := $(SOBJS-y)
1826 +SRCS   := $(SOBJS:.o=.S) $(COBJS:.o=.c)
1827 +OBJS   := $(addprefix $(obj),$(SOBJS) $(COBJS))
1828 +
1829 +all:   $(LIB)
1830 +
1831 +$(LIB):        $(obj).depend $(OBJS)
1832 +       $(call cmd_link_o_target, $(OBJS))
1833 +
1834 +#########################################################################
1835 +
1836 +# defines $(obj).depend target
1837 +include $(SRCTREE)/rules.mk
1838 +
1839 +sinclude $(obj).depend
1840 +
1841 +#########################################################################
1842 --- /dev/null
1843 +++ b/arch/mips/cpu/mips32/vrx200/cgu.c
1844 @@ -0,0 +1,208 @@
1845 +/*
1846 + * Copyright (C) 2010 Lantiq Deutschland GmbH
1847 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
1848 + *
1849 + * SPDX-License-Identifier:    GPL-2.0+
1850 + */
1851 +
1852 +#include <common.h>
1853 +#include <asm/arch/soc.h>
1854 +#include <asm/arch/gphy.h>
1855 +#include <asm/lantiq/clk.h>
1856 +#include <asm/lantiq/io.h>
1857 +
1858 +#define LTQ_CGU_PLL1_PLLN_SHIFT                6
1859 +#define LTQ_CGU_PLL1_PLLN_MASK         (0x3F << LTQ_CGU_PLL1_PLLN_SHIFT)
1860 +#define LTQ_CGU_PLL1_PLLM_SHIFT                2
1861 +#define LTQ_CGU_PLL1_PLLM_MASK         (0xF << LTQ_CGU_PLL1_PLLM_SHIFT)
1862 +#define LTQ_CGU_PLL1_PLLL              (1 << 1)
1863 +#define LTQ_CGU_PLL1_PLL_EN            1
1864 +
1865 +#define LTQ_CGU_SYS_OCP_SHIFT          0
1866 +#define LTQ_CGU_SYS_OCP_MASK           (0x3 << LTQ_CGU_SYS_OCP_SHIFT)
1867 +#define LTQ_CGU_SYS_CPU_SHIFT          4
1868 +#define LTQ_CGU_SYS_CPU_MASK           (0xF << LTQ_CGU_SYS_CPU_SHIFT)
1869 +
1870 +#define LTQ_CGU_UPDATE                 1
1871 +
1872 +#define LTQ_CGU_IFCLK_GPHY_SEL_SHIFT   2
1873 +#define LTQ_CGU_IFCLK_GPHY_SEL_MASK    (0x7 << LTQ_CGU_IFCLK_GPHY_SEL_SHIFT)
1874 +
1875 +struct ltq_cgu_regs {
1876 +       u32     rsvd0;
1877 +       u32     pll0_cfg;       /* PLL0 config */
1878 +       u32     pll1_cfg;       /* PLL1 config */
1879 +       u32     sys;            /* System clock */
1880 +       u32     clk_fsr;        /* Clock frequency select */
1881 +       u32     clk_gsr;        /* Clock gating status */
1882 +       u32     clk_gcr0;       /* Clock gating control 0 */
1883 +       u32     clk_gcr1;       /* Clock gating control 1 */
1884 +       u32     update;         /* CGU update control */
1885 +       u32     if_clk;         /* Interface clock */
1886 +       u32     ddr;            /* DDR memory control */
1887 +       u32     ct1_sr;         /* CT status 1 */
1888 +       u32     ct_kval;        /* CT K value */
1889 +       u32     pcm_cr;         /* PCM control */
1890 +       u32     pci_cr;         /* PCI clock control */
1891 +       u32     rsvd1;
1892 +       u32     gphy1_cfg;      /* GPHY1 config */
1893 +       u32     gphy0_cfg;      /* GPHY0 config */
1894 +       u32     rsvd2[6];
1895 +       u32     pll2_cfg;       /* PLL2 config */
1896 +};
1897 +
1898 +static struct ltq_cgu_regs *ltq_cgu_regs =
1899 +       (struct ltq_cgu_regs *) CKSEG1ADDR(LTQ_CGU_BASE);
1900 +
1901 +static inline u32 ltq_cgu_sys_readl(u32 mask, u32 shift)
1902 +{
1903 +       return (ltq_readl(&ltq_cgu_regs->sys) & mask) >> shift;
1904 +}
1905 +
1906 +unsigned long ltq_get_io_region_clock(void)
1907 +{
1908 +       unsigned int ocp_sel;
1909 +       unsigned long clk, cpu_clk;
1910 +
1911 +       cpu_clk = ltq_get_cpu_clock();
1912 +
1913 +       ocp_sel = ltq_cgu_sys_readl(LTQ_CGU_SYS_OCP_MASK,
1914 +                       LTQ_CGU_SYS_OCP_SHIFT);
1915 +
1916 +       switch (ocp_sel) {
1917 +       case 0:
1918 +               /* OCP ratio 1 */
1919 +               clk = cpu_clk;
1920 +               break;
1921 +       case 2:
1922 +               /* OCP ratio 2 */
1923 +               clk = cpu_clk / 2;
1924 +               break;
1925 +       case 3:
1926 +               /* OCP ratio 2.5 */
1927 +               clk = (cpu_clk * 2) / 5;
1928 +               break;
1929 +       case 4:
1930 +               /* OCP ratio 3 */
1931 +               clk = cpu_clk / 3;
1932 +               break;
1933 +       default:
1934 +               clk = 0;
1935 +               break;
1936 +       }
1937 +
1938 +       return clk;
1939 +}
1940 +
1941 +unsigned long ltq_get_cpu_clock(void)
1942 +{
1943 +       unsigned int cpu_sel;
1944 +       unsigned long clk;
1945 +
1946 +       cpu_sel = ltq_cgu_sys_readl(LTQ_CGU_SYS_CPU_MASK,
1947 +                       LTQ_CGU_SYS_CPU_SHIFT);
1948 +
1949 +       switch (cpu_sel) {
1950 +       case 0:
1951 +               clk = CLOCK_600_MHZ;
1952 +               break;
1953 +       case 1:
1954 +               clk = CLOCK_500_MHZ;
1955 +               break;
1956 +       case 2:
1957 +               clk = CLOCK_393_MHZ;
1958 +               break;
1959 +       case 3:
1960 +               clk = CLOCK_333_MHZ;
1961 +               break;
1962 +       case 5:
1963 +       case 6:
1964 +               clk = CLOCK_197_MHZ;
1965 +               break;
1966 +       case 7:
1967 +               clk = CLOCK_166_MHZ;
1968 +               break;
1969 +       case 4:
1970 +       case 8:
1971 +       case 9:
1972 +               clk = CLOCK_125_MHZ;
1973 +               break;
1974 +       default:
1975 +               clk = 0;
1976 +               break;
1977 +       }
1978 +
1979 +       return clk;
1980 +}
1981 +
1982 +unsigned long ltq_get_bus_clock(void)
1983 +{
1984 +       return ltq_get_io_region_clock();
1985 +}
1986 +
1987 +void ltq_cgu_gphy_clk_src(enum ltq_gphy_clk clk)
1988 +{
1989 +       ltq_clrbits(&ltq_cgu_regs->if_clk, LTQ_CGU_IFCLK_GPHY_SEL_MASK);
1990 +       ltq_setbits(&ltq_cgu_regs->if_clk, clk << LTQ_CGU_IFCLK_GPHY_SEL_SHIFT);
1991 +}
1992 +
1993 +static inline int ltq_cgu_pll1_locked(void)
1994 +{
1995 +       u32 pll1_cfg = ltq_readl(&ltq_cgu_regs->pll1_cfg);
1996 +
1997 +       return pll1_cfg & LTQ_CGU_PLL1_PLLL;
1998 +}
1999 +
2000 +static inline void ltq_cgu_pll1_restart(unsigned m, unsigned n)
2001 +{
2002 +       u32 pll1_cfg;
2003 +
2004 +       ltq_clrbits(&ltq_cgu_regs->pll1_cfg, LTQ_CGU_PLL1_PLL_EN);
2005 +       ltq_setbits(&ltq_cgu_regs->update, LTQ_CGU_UPDATE);
2006 +
2007 +       pll1_cfg = ltq_readl(&ltq_cgu_regs->pll1_cfg);
2008 +       pll1_cfg &= ~(LTQ_CGU_PLL1_PLLN_MASK | LTQ_CGU_PLL1_PLLM_MASK);
2009 +       pll1_cfg |= n << LTQ_CGU_PLL1_PLLN_SHIFT;
2010 +       pll1_cfg |= m << LTQ_CGU_PLL1_PLLM_SHIFT;
2011 +       pll1_cfg |= LTQ_CGU_PLL1_PLL_EN;
2012 +       ltq_writel(&ltq_cgu_regs->pll1_cfg, pll1_cfg);
2013 +       ltq_setbits(&ltq_cgu_regs->update, LTQ_CGU_UPDATE);
2014 +
2015 +       __udelay(1000);
2016 +}
2017 +
2018 +/*
2019 + * From chapter 9 in errata sheet:
2020 + *
2021 + * Under certain condition, the PLL1 may failed to enter into lock
2022 + * status by hardware default N, M setting.
2023 + *
2024 + * Since system always starts from PLL0, the system software can run
2025 + * and re-program the PLL1 settings.
2026 + */
2027 +static void ltq_cgu_pll1_init(void)
2028 +{
2029 +       unsigned i;
2030 +       const unsigned pll1_m[] = { 1, 2, 3, 4 };
2031 +       const unsigned pll1_n[] = { 21, 32, 43, 54 };
2032 +
2033 +       /* Check if PLL1 has locked with hardware default settings */
2034 +       if (ltq_cgu_pll1_locked())
2035 +               return;
2036 +
2037 +       for (i = 0; i < 4; i++) {
2038 +               ltq_cgu_pll1_restart(pll1_m[i], pll1_n[i]);
2039 +
2040 +               if (ltq_cgu_pll1_locked())
2041 +                       goto done;
2042 +       }
2043 +
2044 +done:
2045 +       /* Restart with hardware default values M=5, N=64 */
2046 +       ltq_cgu_pll1_restart(5, 64);
2047 +}
2048 +
2049 +void ltq_pll_init(void)
2050 +{
2051 +       ltq_cgu_pll1_init();
2052 +}
2053 --- /dev/null
2054 +++ b/arch/mips/cpu/mips32/vrx200/cgu_init.S
2055 @@ -0,0 +1,119 @@
2056 +/*
2057 + * Copyright (C) 2010 Lantiq Deutschland GmbH
2058 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
2059 + *
2060 + * SPDX-License-Identifier:    GPL-2.0+
2061 + */
2062 +
2063 +#include <config.h>
2064 +#include <asm/asm.h>
2065 +#include <asm/regdef.h>
2066 +#include <asm/addrspace.h>
2067 +#include <asm/arch/soc.h>
2068 +
2069 +/* RCU module register */
2070 +#define LTQ_RCU_RST_REQ                        0x0010  /* Reset request */
2071 +#define LTQ_RCU_RST_REQ_VALUE          ((1 << 14) | (1 << 1))
2072 +
2073 +/* CGU module register */
2074 +#define LTQ_CGU_PLL0_CFG               0x0004  /* PLL0 config */
2075 +#define LTQ_CGU_PLL1_CFG               0x0008  /* PLL1 config */
2076 +#define LTQ_CGU_PLL2_CFG               0x0060  /* PLL2 config */
2077 +#define LTQ_CGU_SYS                    0x000C  /* System clock */
2078 +#define LTQ_CGU_CLK_FSR                        0x0010  /* Clock frequency select */
2079 +#define LTQ_CGU_UPDATE                 0x0020  /* Clock update control */
2080 +
2081 +/* Valid SYS.CPU values */
2082 +#define LTQ_CGU_SYS_CPU_SHIFT          4
2083 +#define LTQ_CGU_SYS_CPU_600_MHZ                0x0
2084 +#define LTQ_CGU_SYS_CPU_500_MHZ                0x1
2085 +#define LTQ_CGU_SYS_CPU_393_MHZ                0x2
2086 +#define LTQ_CGU_SYS_CPU_333_MHZ                0x3
2087 +#define LTQ_CGU_SYS_CPU_197_MHZ                0x5
2088 +#define LTQ_CGU_SYS_CPU_166_MHZ                0x7
2089 +#define LTQ_CGU_SYS_CPU_125_MHZ                0x9
2090 +
2091 +/* Valid SYS.OCP values */
2092 +#define LTQ_CGU_SYS_OCP_SHIFT          0
2093 +#define LTQ_CGU_SYS_OCP_1              0x0
2094 +#define LTQ_CGU_SYS_OCP_2              0x2
2095 +#define LTQ_CGU_SYS_OCP_2_5            0x3
2096 +#define LTQ_CGU_SYS_OCP_3              0x4
2097 +
2098 +/* Valid CLK_FSR.ETH values */
2099 +#define LTQ_CGU_CLK_FSR_ETH_SHIFT      24
2100 +#define LTQ_CGU_CLK_FSR_ETH_50_MHZ     0x0
2101 +#define LTQ_CGU_CLK_FSR_ETH_25_MHZ     0x1
2102 +#define LTQ_CGU_CLK_FSR_ETH_2_5_MHZ    0x2
2103 +#define LTQ_CGU_CLK_FSR_ETH_125_MHZ    0x3
2104 +
2105 +/* Valid CLK_FSR.PPE values */
2106 +#define LTQ_CGU_CLK_FSR_PPE_SHIFT      16
2107 +#define LTQ_CGU_CLK_FSR_PPE_500_MHZ    0x0     /* Overclock frequency */
2108 +#define LTQ_CGU_CLK_FSR_PPE_450_MHZ    0x1     /* High frequency */
2109 +#define LTQ_CGU_CLK_FSR_PPE_400_MHZ    0x2     /* Low frequency */
2110 +
2111 +#if (CONFIG_SYS_CLOCK_MODE == LTQ_CLK_CPU_500_DDR_250)
2112 +#define LTQ_CGU_SYS_CPU_CONFIG         LTQ_CGU_SYS_CPU_500_MHZ
2113 +#define LTQ_CGU_SYS_OCP_CONFIG         LTQ_CGU_SYS_OCP_2
2114 +#define LTQ_CGU_CLK_FSR_ETH_CONFIG     LTQ_CGU_CLK_FSR_ETH_125_MHZ
2115 +#define LTQ_CGU_CLK_FSR_PPE_CONFIG     LTQ_CGU_CLK_FSR_PPE_450_MHZ
2116 +#else
2117 +#error "Invalid system clock configuration!"
2118 +#endif
2119 +
2120 +/* Build register values */
2121 +#define LTQ_CGU_SYS_VALUE      ((LTQ_CGU_SYS_CPU_CONFIG << \
2122 +                                       LTQ_CGU_SYS_CPU_SHIFT) | \
2123 +                                       LTQ_CGU_SYS_OCP_CONFIG)
2124 +
2125 +#define LTQ_CGU_CLK_FSR_VALUE  ((LTQ_CGU_CLK_FSR_ETH_CONFIG << \
2126 +                                       LTQ_CGU_CLK_FSR_ETH_SHIFT) | \
2127 +                               (LTQ_CGU_CLK_FSR_PPE_CONFIG << \
2128 +                                       LTQ_CGU_CLK_FSR_PPE_SHIFT))
2129 +
2130 +       .set noreorder
2131 +
2132 +LEAF(ltq_cgu_init)
2133 +       /* Load current CGU register values */
2134 +       li      t0, (LTQ_CGU_BASE | KSEG1)
2135 +       lw      t1, LTQ_CGU_SYS(t0)
2136 +       lw      t2, LTQ_CGU_CLK_FSR(t0)
2137 +
2138 +       /* Load target CGU register values */
2139 +       li      t3, LTQ_CGU_SYS_VALUE
2140 +       li      t4, LTQ_CGU_CLK_FSR_VALUE
2141 +
2142 +       /* Only update registers if values differ */
2143 +       bne     t1, t3, update
2144 +        nop
2145 +       beq     t2, t4, finished
2146 +        nop
2147 +
2148 +update:
2149 +       /* Store target register values */
2150 +       sw      t3, LTQ_CGU_SYS(t0)
2151 +       sw      t4, LTQ_CGU_CLK_FSR(t0)
2152 +
2153 +       /* Perform software reset to activate new clock config */
2154 +#if 0
2155 +       li      t0, (LTQ_RCU_BASE | KSEG1)
2156 +       lw      t1, LTQ_RCU_RST_REQ(t0)
2157 +       or      t1, LTQ_RCU_RST_REQ_VALUE
2158 +       sw      t1, LTQ_RCU_RST_REQ(t0)
2159 +#else
2160 +       li      t1, 1
2161 +       sw      t1, LTQ_CGU_UPDATE(t0)
2162 +#endif
2163 +
2164 +#if 0
2165 +wait_reset:
2166 +       b       wait_reset
2167 +        nop
2168 +#endif
2169 +
2170 +finished:
2171 +       jr      ra
2172 +        nop
2173 +
2174 +       END(ltq_cgu_init)
2175 --- /dev/null
2176 +++ b/arch/mips/cpu/mips32/vrx200/chipid.c
2177 @@ -0,0 +1,62 @@
2178 +/*
2179 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
2180 + *
2181 + * SPDX-License-Identifier:    GPL-2.0+
2182 + */
2183 +
2184 +#include <common.h>
2185 +#include <asm/lantiq/io.h>
2186 +#include <asm/lantiq/chipid.h>
2187 +#include <asm/arch/soc.h>
2188 +
2189 +#define LTQ_CHIPID_VERSION_SHIFT       28
2190 +#define LTQ_CHIPID_VERSION_MASK                (0x7 << LTQ_CHIPID_VERSION_SHIFT)
2191 +#define LTQ_CHIPID_PNUM_SHIFT          12
2192 +#define LTQ_CHIPID_PNUM_MASK           (0xFFFF << LTQ_CHIPID_PNUM_SHIFT)
2193 +
2194 +struct ltq_chipid_regs {
2195 +       u32     manid;          /* Manufacturer identification */
2196 +       u32     chipid;         /* Chip identification */
2197 +};
2198 +
2199 +static struct ltq_chipid_regs *ltq_chipid_regs =
2200 +       (struct ltq_chipid_regs *) CKSEG1ADDR(LTQ_CHIPID_BASE);
2201 +
2202 +unsigned int ltq_chip_version_get(void)
2203 +{
2204 +       u32 chipid;
2205 +
2206 +       chipid = ltq_readl(&ltq_chipid_regs->chipid);
2207 +
2208 +       return (chipid & LTQ_CHIPID_VERSION_MASK) >> LTQ_CHIPID_VERSION_SHIFT;
2209 +}
2210 +
2211 +unsigned int ltq_chip_partnum_get(void)
2212 +{
2213 +       u32 chipid;
2214 +
2215 +       chipid = ltq_readl(&ltq_chipid_regs->chipid);
2216 +
2217 +       return (chipid & LTQ_CHIPID_PNUM_MASK) >> LTQ_CHIPID_PNUM_SHIFT;
2218 +}
2219 +
2220 +const char *ltq_chip_partnum_str(void)
2221 +{
2222 +       enum ltq_chip_partnum partnum = ltq_chip_partnum_get();
2223 +
2224 +       switch (partnum) {
2225 +       case LTQ_SOC_VRX268:
2226 +       case LTQ_SOC_VRX268_2:
2227 +               return "VRX268";
2228 +       case LTQ_SOC_VRX288:
2229 +       case LTQ_SOC_VRX288_2:
2230 +               return "VRX288";
2231 +       case LTQ_SOC_GRX288:
2232 +       case LTQ_SOC_GRX288_2:
2233 +               return "GRX288";
2234 +       default:
2235 +               printf("Unknown partnum: %x\n", partnum);
2236 +       }
2237 +
2238 +       return "";
2239 +}
2240 --- /dev/null
2241 +++ b/arch/mips/cpu/mips32/vrx200/config.mk
2242 @@ -0,0 +1,30 @@
2243 +#
2244 +# Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
2245 +#
2246 +# SPDX-License-Identifier:     GPL-2.0+
2247 +#
2248 +
2249 +PF_CPPFLAGS_XRX := $(call cc-option,-mtune=34kc,)
2250 +PLATFORM_CPPFLAGS += $(PF_CPPFLAGS_XRX)
2251 +
2252 +ifdef CONFIG_SPL_BUILD
2253 +PF_ABICALLS            := -mno-abicalls
2254 +PF_PIC                 := -fno-pic
2255 +PF_PIE                 :=
2256 +USE_PRIVATE_LIBGCC     := yes
2257 +endif
2258 +
2259 +LIBS-y += $(CPUDIR)/lantiq-common/liblantiq-common.o
2260 +
2261 +ifndef CONFIG_SPL_BUILD
2262 +ifdef CONFIG_SYS_BOOT_SFSPL
2263 +ALL-y += $(obj)u-boot.ltq.sfspl
2264 +ALL-$(CONFIG_SPL_LZO_SUPPORT) += $(obj)u-boot.ltq.lzo.sfspl
2265 +ALL-$(CONFIG_SPL_LZMA_SUPPORT) += $(obj)u-boot.ltq.lzma.sfspl
2266 +endif
2267 +ifdef CONFIG_SYS_BOOT_NORSPL
2268 +ALL-y += $(obj)u-boot.ltq.norspl
2269 +ALL-$(CONFIG_SPL_LZO_SUPPORT) += $(obj)u-boot.ltq.lzo.norspl
2270 +ALL-$(CONFIG_SPL_LZMA_SUPPORT) += $(obj)u-boot.ltq.lzma.norspl
2271 +endif
2272 +endif
2273 --- /dev/null
2274 +++ b/arch/mips/cpu/mips32/vrx200/dcdc.c
2275 @@ -0,0 +1,106 @@
2276 +/*
2277 + * Copyright (C) 2010 Lantiq Deutschland GmbH
2278 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
2279 + *
2280 + * SPDX-License-Identifier:    GPL-2.0+
2281 + */
2282 +
2283 +#include <common.h>
2284 +#include <asm/arch/soc.h>
2285 +#include <asm/lantiq/io.h>
2286 +
2287 +#define LTQ_DCDC_CLK_SET0_CLK_SEL_P            (1 << 6)
2288 +#define LTQ_DCDC_CLK_SET1_SEL_DIV25            (1 << 5)
2289 +#define LTQ_DCDC_CONF_TEST_DIG_PID_FREEZE      (1 << 5)
2290 +
2291 +struct ltq_dcdc_regs {
2292 +       u8      b0_coeh;                /* Coefficient b0 */
2293 +       u8      b0_coel;                /* Coefficient b0 */
2294 +       u8      b1_coeh;                /* Coefficient b1 */
2295 +       u8      b1_coel;                /* Coefficient b1 */
2296 +       u8      b2_coeh;                /* Coefficient b2 */
2297 +       u8      b2_coel;                /* Coefficient b2 */
2298 +       u8      clk_set0;               /* Clock setup */
2299 +       u8      clk_set1;               /* Clock setup */
2300 +       u8      pwm_confh;              /* Configure PWM */
2301 +       u8      pwm_confl;              /* Configure PWM */
2302 +       u8      bias_vreg0;             /* Bias and regulator setup */
2303 +       u8      bias_vreg1;             /* Bias and regulator setup */
2304 +       u8      adc_gen0;               /* ADC and general control */
2305 +       u8      adc_gen1;               /* ADC and general control */
2306 +       u8      adc_con0;               /* ADC and general config */
2307 +       u8      adc_con1;               /* ADC and general config */
2308 +       u8      conf_test_ana;          /* not documented */
2309 +       u8      conf_test_dig;          /* not documented */
2310 +       u8      dcdc_status;            /* not documented */
2311 +       u8      pid_status;             /* not documented */
2312 +       u8      duty_cycle;             /* not documented */
2313 +       u8      non_ov_delay;           /* not documented */
2314 +       u8      analog_gain;            /* not documented */
2315 +       u8      duty_cycle_max_sat;     /* not documented */
2316 +       u8      duty_cycle_min_sat;     /* not documented */
2317 +       u8      duty_cycle_max;         /* not documented */
2318 +       u8      duty_cycle_min;         /* not documented */
2319 +       u8      error_max;              /* not documented */
2320 +       u8      error_read;             /* not documented */
2321 +       u8      delay_deglitch;         /* not documented */
2322 +       u8      latch_control;          /* not documented */
2323 +       u8      rsvd[240];
2324 +       u8      osc_conf;               /* OSC general config */
2325 +       u8      osc_stat;               /* OSC general status */
2326 +};
2327 +
2328 +static struct ltq_dcdc_regs *ltq_dcdc_regs =
2329 +       (struct ltq_dcdc_regs *) CKSEG1ADDR(LTQ_DCDC_BASE);
2330 +
2331 +void ltq_dcdc_init(unsigned int dig_ref)
2332 +{
2333 +       u8 dig_ref_cur, val;
2334 +
2335 +       /* Set duty cycle max sat. to 70/90, enable PID freeze */
2336 +       ltq_writeb(&ltq_dcdc_regs->duty_cycle_max_sat, 0x5A);
2337 +       ltq_writeb(&ltq_dcdc_regs->duty_cycle_min_sat, 0x46);
2338 +       val = ltq_readb(&ltq_dcdc_regs->conf_test_dig);
2339 +       val |= LTQ_DCDC_CONF_TEST_DIG_PID_FREEZE;
2340 +       ltq_writeb(&ltq_dcdc_regs->conf_test_dig, val);
2341 +
2342 +       /* Program new coefficients */
2343 +       ltq_writeb(&ltq_dcdc_regs->b0_coeh, 0x00);
2344 +       ltq_writeb(&ltq_dcdc_regs->b0_coel, 0x00);
2345 +       ltq_writeb(&ltq_dcdc_regs->b1_coeh, 0xFF);
2346 +       ltq_writeb(&ltq_dcdc_regs->b1_coel, 0xE6);
2347 +       ltq_writeb(&ltq_dcdc_regs->b2_coeh, 0x00);
2348 +       ltq_writeb(&ltq_dcdc_regs->b2_coel, 0x1B);
2349 +       ltq_writeb(&ltq_dcdc_regs->non_ov_delay, 0x8B);
2350 +
2351 +       /* Set duty cycle max sat. to 60/108, disable PID freeze */
2352 +       ltq_writeb(&ltq_dcdc_regs->duty_cycle_max_sat, 0x6C);
2353 +       ltq_writeb(&ltq_dcdc_regs->duty_cycle_min_sat, 0x3C);
2354 +       val = ltq_readb(&ltq_dcdc_regs->conf_test_dig);
2355 +       val &= ~LTQ_DCDC_CONF_TEST_DIG_PID_FREEZE;
2356 +       ltq_writeb(&ltq_dcdc_regs->conf_test_dig, val);
2357 +
2358 +       /* Init clock and DLL settings */
2359 +       val = ltq_readb(&ltq_dcdc_regs->clk_set0);
2360 +       val |= LTQ_DCDC_CLK_SET0_CLK_SEL_P;
2361 +       ltq_writeb(&ltq_dcdc_regs->clk_set0, val);
2362 +       val = ltq_readb(&ltq_dcdc_regs->clk_set1);
2363 +       val |= LTQ_DCDC_CLK_SET1_SEL_DIV25;
2364 +       ltq_writeb(&ltq_dcdc_regs->clk_set1, val);
2365 +       ltq_writeb(&ltq_dcdc_regs->pwm_confh, 0xF9);
2366 +
2367 +       wmb();
2368 +
2369 +       /* Adapt value of digital reference of DCDC converter */
2370 +       dig_ref_cur = ltq_readb(&ltq_dcdc_regs->bias_vreg1);
2371 +
2372 +       while (dig_ref_cur != dig_ref) {
2373 +               if (dig_ref >= dig_ref_cur)
2374 +                       dig_ref_cur++;
2375 +               else if (dig_ref < dig_ref_cur)
2376 +                       dig_ref_cur--;
2377 +
2378 +               ltq_writeb(&ltq_dcdc_regs->bias_vreg1, dig_ref_cur);
2379 +               __udelay(1000);
2380 +       }
2381 +}
2382 --- /dev/null
2383 +++ b/arch/mips/cpu/mips32/vrx200/ebu.c
2384 @@ -0,0 +1,111 @@
2385 +/*
2386 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
2387 + *
2388 + * SPDX-License-Identifier:    GPL-2.0+
2389 + */
2390 +
2391 +#include <common.h>
2392 +#include <asm/arch/soc.h>
2393 +#include <asm/lantiq/io.h>
2394 +
2395 +#define EBU_ADDRSEL_MASK(mask)         ((mask & 0xf) << 4)
2396 +#define EBU_ADDRSEL_REGEN              (1 << 0)
2397 +
2398 +#define EBU_CON_WRDIS                  (1 << 31)
2399 +#define EBU_CON_AGEN_DEMUX             (0x0 << 24)
2400 +#define EBU_CON_AGEN_MUX               (0x2 << 24)
2401 +#define EBU_CON_SETUP                  (1 << 22)
2402 +#define EBU_CON_WAIT_DIS               (0x0 << 20)
2403 +#define EBU_CON_WAIT_ASYNC             (0x1 << 20)
2404 +#define EBU_CON_WAIT_SYNC              (0x2 << 20)
2405 +#define EBU_CON_WINV                   (1 << 19)
2406 +#define EBU_CON_PW_8BIT                        (0x0 << 16)
2407 +#define EBU_CON_PW_16BIT               (0x1 << 16)
2408 +#define EBU_CON_ALEC(cycles)           ((cycles & 0x3) << 14)
2409 +#define EBU_CON_BCGEN_CS               (0x0 << 12)
2410 +#define EBU_CON_BCGEN_INTEL            (0x1 << 12)
2411 +#define EBU_CON_BCGEN_MOTOROLA         (0x2 << 12)
2412 +#define EBU_CON_WAITWRC(cycles)                ((cycles & 0x7) << 8)
2413 +#define EBU_CON_WAITRDC(cycles)                ((cycles & 0x3) << 6)
2414 +#define EBU_CON_HOLDC(cycles)          ((cycles & 0x3) << 4)
2415 +#define EBU_CON_RECOVC(cycles)         ((cycles & 0x3) << 2)
2416 +#define EBU_CON_CMULT_1                        0x0
2417 +#define EBU_CON_CMULT_4                        0x1
2418 +#define EBU_CON_CMULT_8                        0x2
2419 +#define EBU_CON_CMULT_16               0x3
2420 +
2421 +#if defined(CONFIG_LTQ_SUPPORT_NOR_FLASH)
2422 +#define ebu_region0_enable             1
2423 +#else
2424 +#define ebu_region0_enable             0
2425 +#endif
2426 +
2427 +#if defined(CONFIG_LTQ_SUPPORT_NAND_FLASH)
2428 +#define ebu_region1_enable             1
2429 +#else
2430 +#define ebu_region1_enable             0
2431 +#endif
2432 +
2433 +struct ltq_ebu_regs {
2434 +       u32     clc;
2435 +       u32     rsvd0;
2436 +       u32     id;
2437 +       u32     rsvd1;
2438 +       u32     con;
2439 +       u32     rsvd2[3];
2440 +       u32     addr_sel_0;
2441 +       u32     addr_sel_1;
2442 +       u32     addr_sel_2;
2443 +       u32     addr_sel_3;
2444 +       u32     rsvd3[12];
2445 +       u32     con_0;
2446 +       u32     con_1;
2447 +       u32     con_2;
2448 +       u32     con_3;
2449 +};
2450 +
2451 +static struct ltq_ebu_regs *ltq_ebu_regs =
2452 +       (struct ltq_ebu_regs *) CKSEG1ADDR(LTQ_EBU_BASE);
2453 +
2454 +void ltq_ebu_init(void)
2455 +{
2456 +       if (ebu_region0_enable) {
2457 +               /*
2458 +                * Map EBU region 0 to range 0x10000000-0x13ffffff and enable
2459 +                * region control. This supports up to 32 MiB NOR flash in
2460 +                * bank 0.
2461 +                */
2462 +               ltq_writel(&ltq_ebu_regs->addr_sel_0, LTQ_EBU_REGION0_BASE |
2463 +                       EBU_ADDRSEL_MASK(1) | EBU_ADDRSEL_REGEN);
2464 +
2465 +               ltq_writel(&ltq_ebu_regs->con_0, EBU_CON_AGEN_DEMUX |
2466 +                       EBU_CON_WAIT_DIS | EBU_CON_PW_16BIT |
2467 +                       EBU_CON_ALEC(3) | EBU_CON_BCGEN_INTEL |
2468 +                       EBU_CON_WAITWRC(7) | EBU_CON_WAITRDC(3) |
2469 +                       EBU_CON_HOLDC(3) | EBU_CON_RECOVC(3) |
2470 +                       EBU_CON_CMULT_16);
2471 +       } else
2472 +               ltq_clrbits(&ltq_ebu_regs->addr_sel_0, EBU_ADDRSEL_REGEN);
2473 +
2474 +       if (ebu_region1_enable) {
2475 +               /*
2476 +                * Map EBU region 1 to range 0x14000000-0x13ffffff and enable
2477 +                * region control. This supports NAND flash in bank 1.
2478 +                */
2479 +               ltq_writel(&ltq_ebu_regs->addr_sel_1, LTQ_EBU_REGION1_BASE |
2480 +                       EBU_ADDRSEL_MASK(3) | EBU_ADDRSEL_REGEN);
2481 +
2482 +               ltq_writel(&ltq_ebu_regs->con_1, EBU_CON_AGEN_DEMUX |
2483 +                       EBU_CON_SETUP | EBU_CON_WAIT_DIS | EBU_CON_PW_8BIT |
2484 +                       EBU_CON_ALEC(3) | EBU_CON_BCGEN_INTEL |
2485 +                       EBU_CON_WAITWRC(2) | EBU_CON_WAITRDC(2) |
2486 +                       EBU_CON_HOLDC(1) | EBU_CON_RECOVC(1) |
2487 +                       EBU_CON_CMULT_4);
2488 +       } else
2489 +               ltq_clrbits(&ltq_ebu_regs->addr_sel_1, EBU_ADDRSEL_REGEN);
2490 +}
2491 +
2492 +void *flash_swap_addr(unsigned long addr)
2493 +{
2494 +       return (void *)(addr ^ 2);
2495 +}
2496 --- /dev/null
2497 +++ b/arch/mips/cpu/mips32/vrx200/gphy.c
2498 @@ -0,0 +1,58 @@
2499 +/*
2500 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
2501 + *
2502 + * SPDX-License-Identifier:    GPL-2.0+
2503 + */
2504 +
2505 +#include <common.h>
2506 +#include <asm/lantiq/io.h>
2507 +#include <asm/arch/soc.h>
2508 +#include <asm/arch/gphy.h>
2509 +
2510 +static inline void ltq_gphy_copy(const void *fw_start, const void *fw_end,
2511 +                               ulong dst_addr)
2512 +{
2513 +       const ulong fw_len = (ulong) fw_end - (ulong) fw_start;
2514 +       const ulong addr = CKSEG1ADDR(dst_addr);
2515 +
2516 +       debug("ltq_gphy_copy: addr %08lx, fw_start %p, fw_end %p\n",
2517 +               addr, fw_start, fw_end);
2518 +
2519 +       memcpy((void *) addr, fw_start, fw_len);
2520 +}
2521 +
2522 +void ltq_gphy_phy11g_a1x_load(ulong addr)
2523 +{
2524 +       extern ulong __ltq_fw_phy11g_a1x_start;
2525 +       extern ulong __ltq_fw_phy11g_a1x_end;
2526 +
2527 +       ltq_gphy_copy(&__ltq_fw_phy11g_a1x_start, &__ltq_fw_phy11g_a1x_end,
2528 +                       addr);
2529 +}
2530 +
2531 +void ltq_gphy_phy11g_a2x_load(ulong addr)
2532 +{
2533 +       extern ulong __ltq_fw_phy11g_a2x_start;
2534 +       extern ulong __ltq_fw_phy11g_a2x_end;
2535 +
2536 +       ltq_gphy_copy(&__ltq_fw_phy11g_a2x_start, &__ltq_fw_phy11g_a2x_end,
2537 +                       addr);
2538 +}
2539 +
2540 +void ltq_gphy_phy22f_a1x_load(ulong addr)
2541 +{
2542 +       extern ulong __ltq_fw_phy22f_a1x_start;
2543 +       extern ulong __ltq_fw_phy22f_a1x_end;
2544 +
2545 +       ltq_gphy_copy(&__ltq_fw_phy22f_a1x_start, &__ltq_fw_phy22f_a1x_end,
2546 +                       addr);
2547 +}
2548 +
2549 +void ltq_gphy_phy22f_a2x_load(ulong addr)
2550 +{
2551 +       extern ulong __ltq_fw_phy22f_a2x_start;
2552 +       extern ulong __ltq_fw_phy22f_a2x_end;
2553 +
2554 +       ltq_gphy_copy(&__ltq_fw_phy22f_a2x_start, &__ltq_fw_phy22f_a2x_end,
2555 +                       addr);
2556 +}
2557 --- /dev/null
2558 +++ b/arch/mips/cpu/mips32/vrx200/gphy_fw.S
2559 @@ -0,0 +1,27 @@
2560 +/*
2561 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
2562 + *
2563 + * SPDX-License-Identifier:    GPL-2.0+
2564 + */
2565 +
2566 +#include <asm/asm.h>
2567 +
2568 +       .section .rodata.__ltq_fw_phy11g_a1x
2569 +EXPORT(__ltq_fw_phy11g_a1x_start)
2570 +       .incbin "fw_phy11g_a1x.blob"
2571 +EXPORT(__ltq_fw_phy11g_a1x_end)
2572 +
2573 +       .section .rodata.__ltq_fw_phy11g_a2x
2574 +EXPORT(__ltq_fw_phy11g_a2x_start)
2575 +       .incbin "fw_phy11g_a2x.blob"
2576 +EXPORT(__ltq_fw_phy11g_a2x_end)
2577 +
2578 +       .section .rodata.__ltq_fw_phy22f_a1x
2579 +EXPORT(__ltq_fw_phy22f_a1x_start)
2580 +       .incbin "fw_phy22f_a1x.blob"
2581 +EXPORT(__ltq_fw_phy22f_a1x_end)
2582 +
2583 +       .section .rodata.__ltq_fw_phy22f_a2x
2584 +EXPORT(__ltq_fw_phy22f_a2x_start)
2585 +       .incbin "fw_phy22f_a2x.blob"
2586 +EXPORT(__ltq_fw_phy22f_a2x_end)
2587 --- /dev/null
2588 +++ b/arch/mips/cpu/mips32/vrx200/mem.c
2589 @@ -0,0 +1,57 @@
2590 +/*
2591 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
2592 + *
2593 + * SPDX-License-Identifier:    GPL-2.0+
2594 + */
2595 +
2596 +#include <common.h>
2597 +#include <asm/arch/soc.h>
2598 +#include <asm/lantiq/io.h>
2599 +
2600 +#define LTQ_CCR03_EIGHT_BANK_MODE      (1 << 0)
2601 +#define LTQ_CCR08_CS_MAP_SHIFT         24
2602 +#define LTQ_CCR08_CS_MAP_MASK          (0x3 << LTQ_CCR08_CS_MAP_SHIFT)
2603 +#define LTQ_CCR11_COLUMN_SIZE_SHIFT    24
2604 +#define LTQ_CCR11_COLUMN_SIZE_MASK     (0x7 << LTQ_CCR11_COLUMN_SIZE_SHIFT)
2605 +#define LTQ_CCR11_ADDR_PINS_MASK       0x7
2606 +#define LTQ_CCR15_MAX_COL_REG_SHIFT    24
2607 +#define LTQ_CCR15_MAX_COL_REG_MASK     (0xF << LTQ_CCR15_MAX_COL_REG_SHIFT)
2608 +#define LTQ_CCR16_MAX_ROW_REG_MASK     0xF
2609 +
2610 +static void *ltq_mc_ddr_base = (void *) CKSEG1ADDR(LTQ_MC_DDR_BASE);
2611 +
2612 +static inline u32 ltq_mc_ccr_read(u32 index)
2613 +{
2614 +       return ltq_readl(ltq_mc_ddr_base + LTQ_MC_DDR_CCR_OFFSET(index));
2615 +}
2616 +
2617 +phys_size_t initdram(int board_type)
2618 +{
2619 +       u32 max_col_reg, max_row_reg, column_size, addr_pins;
2620 +       u32 banks, cs_map;
2621 +       phys_size_t size;
2622 +
2623 +       banks = (ltq_mc_ccr_read(3) & LTQ_CCR03_EIGHT_BANK_MODE) ? 8 : 4;
2624 +
2625 +       cs_map = (ltq_mc_ccr_read(8) & LTQ_CCR08_CS_MAP_MASK) >>
2626 +               LTQ_CCR08_CS_MAP_SHIFT;
2627 +
2628 +       column_size = (ltq_mc_ccr_read(11) & LTQ_CCR11_COLUMN_SIZE_MASK) >>
2629 +               LTQ_CCR11_COLUMN_SIZE_SHIFT;
2630 +
2631 +       addr_pins = ltq_mc_ccr_read(11) & LTQ_CCR11_ADDR_PINS_MASK;
2632 +
2633 +       max_col_reg = (ltq_mc_ccr_read(15) & LTQ_CCR15_MAX_COL_REG_MASK) >>
2634 +               LTQ_CCR15_MAX_COL_REG_SHIFT;
2635 +
2636 +       max_row_reg = ltq_mc_ccr_read(16) & LTQ_CCR16_MAX_ROW_REG_MASK;
2637 +
2638 +       /*
2639 +        * size (bytes) = 2 ^ rowsize * 2 ^ colsize * banks * chipselects
2640 +        *                 * datawidth (bytes)
2641 +        */
2642 +       size = (2 << (max_col_reg - column_size - 1)) *
2643 +               (2 << (max_row_reg - addr_pins - 1)) * banks * cs_map * 2;
2644 +
2645 +       return size;
2646 +}
2647 --- /dev/null
2648 +++ b/arch/mips/cpu/mips32/vrx200/mem_init.S
2649 @@ -0,0 +1,233 @@
2650 +/*
2651 + * Copyright (C) 2010 Lantiq Deutschland GmbH
2652 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
2653 + *
2654 + * SPDX-License-Identifier:    GPL-2.0+
2655 + */
2656 +
2657 +#include <config.h>
2658 +#include <asm/asm.h>
2659 +#include <asm/regdef.h>
2660 +#include <asm/addrspace.h>
2661 +#include <asm/arch/soc.h>
2662 +
2663 +/* Must be configured in BOARDDIR */
2664 +#include <ddr_settings.h>
2665 +
2666 +#define LTQ_MC_DDR_START               (1 << 8)
2667 +#define LTQ_MC_DDR_DLL_LOCK_IND        1
2668 +
2669 +#define CCS_ALWAYS_LAST                        0x0430
2670 +#define CCS_AHBM_CR_BURST_EN           (1 << 2)
2671 +#define CCS_FPIM_CR_BURST_EN           (1 << 1)
2672 +
2673 +#define CCR03_EIGHT_BANK_MODE          (1 << 0)
2674 +
2675 +       /* Store given value in MC DDR CCRx register */
2676 +       .macro ccr_sw num, val
2677 +       li      t1, \val
2678 +       sw      t1, LTQ_MC_DDR_CCR_OFFSET(\num)(t0)
2679 +       .endm
2680 +
2681 +LEAF(ltq_mem_init)
2682 +       /* Load MC DDR module base */
2683 +       li      t0, (LTQ_MC_DDR_BASE | KSEG1)
2684 +
2685 +       /* Put memory controller in inactive mode */
2686 +       sw      zero, LTQ_MC_DDR_CCR_OFFSET(7)(t0)
2687 +
2688 +       /* Init MC DDR CCR registers with values from ddr_settings.h */
2689 +       ccr_sw  0, MC_CCR00_VALUE
2690 +       ccr_sw  1, MC_CCR01_VALUE
2691 +       ccr_sw  2, MC_CCR02_VALUE
2692 +       ccr_sw  3, MC_CCR03_VALUE
2693 +       ccr_sw  4, MC_CCR04_VALUE
2694 +       ccr_sw  5, MC_CCR05_VALUE
2695 +       ccr_sw  6, MC_CCR06_VALUE
2696 +       ccr_sw  7, MC_CCR07_VALUE
2697 +       ccr_sw  8, MC_CCR08_VALUE
2698 +       ccr_sw  9, MC_CCR09_VALUE
2699 +
2700 +       ccr_sw  10, MC_CCR10_VALUE
2701 +       ccr_sw  11, MC_CCR11_VALUE
2702 +       ccr_sw  12, MC_CCR12_VALUE
2703 +       ccr_sw  13, MC_CCR13_VALUE
2704 +       ccr_sw  14, MC_CCR14_VALUE
2705 +       ccr_sw  15, MC_CCR15_VALUE
2706 +       ccr_sw  16, MC_CCR16_VALUE
2707 +       ccr_sw  17, MC_CCR17_VALUE
2708 +       ccr_sw  18, MC_CCR18_VALUE
2709 +       ccr_sw  19, MC_CCR19_VALUE
2710 +
2711 +       ccr_sw  20, MC_CCR20_VALUE
2712 +       ccr_sw  21, MC_CCR21_VALUE
2713 +       ccr_sw  22, MC_CCR22_VALUE
2714 +       ccr_sw  23, MC_CCR23_VALUE
2715 +       ccr_sw  24, MC_CCR24_VALUE
2716 +       ccr_sw  25, MC_CCR25_VALUE
2717 +       ccr_sw  26, MC_CCR26_VALUE
2718 +       ccr_sw  27, MC_CCR27_VALUE
2719 +       ccr_sw  28, MC_CCR28_VALUE
2720 +       ccr_sw  29, MC_CCR29_VALUE
2721 +
2722 +       ccr_sw  30, MC_CCR30_VALUE
2723 +       ccr_sw  31, MC_CCR31_VALUE
2724 +       ccr_sw  32, MC_CCR32_VALUE
2725 +       ccr_sw  33, MC_CCR33_VALUE
2726 +       ccr_sw  34, MC_CCR34_VALUE
2727 +       ccr_sw  35, MC_CCR35_VALUE
2728 +       ccr_sw  36, MC_CCR36_VALUE
2729 +       ccr_sw  37, MC_CCR37_VALUE
2730 +       ccr_sw  38, MC_CCR38_VALUE
2731 +       ccr_sw  39, MC_CCR39_VALUE
2732 +
2733 +       ccr_sw  40, MC_CCR40_VALUE
2734 +       ccr_sw  41, MC_CCR41_VALUE
2735 +       ccr_sw  42, MC_CCR42_VALUE
2736 +       ccr_sw  43, MC_CCR43_VALUE
2737 +       ccr_sw  44, MC_CCR44_VALUE
2738 +       ccr_sw  45, MC_CCR45_VALUE
2739 +       ccr_sw  46, MC_CCR46_VALUE
2740 +
2741 +       ccr_sw  52, MC_CCR52_VALUE
2742 +       ccr_sw  53, MC_CCR53_VALUE
2743 +       ccr_sw  54, MC_CCR54_VALUE
2744 +       ccr_sw  55, MC_CCR55_VALUE
2745 +       ccr_sw  56, MC_CCR56_VALUE
2746 +       ccr_sw  57, MC_CCR57_VALUE
2747 +       ccr_sw  58, MC_CCR58_VALUE
2748 +       ccr_sw  59, MC_CCR59_VALUE
2749 +
2750 +       ccr_sw  60, MC_CCR60_VALUE
2751 +       ccr_sw  61, MC_CCR61_VALUE
2752 +
2753 +       /* Disable bursts between FPI Master bus and XBAR bus */
2754 +       li      t4, (LTQ_MC_GLOBAL_BASE | KSEG1)
2755 +       li      t5, CCS_AHBM_CR_BURST_EN
2756 +       sw      t5, CCS_ALWAYS_LAST(t4)
2757 +
2758 +       /* Init abort condition for DRAM probe */
2759 +       move    t4, zero
2760 +
2761 +       /*
2762 +        * Put memory controller in active mode and start initialitation
2763 +        * sequence for connected DDR-SDRAM device
2764 +        */
2765 +mc_start:
2766 +       lw      t1, LTQ_MC_DDR_CCR_OFFSET(7)(t0)
2767 +       li      t2, LTQ_MC_DDR_START
2768 +       or      t1, t1, t2
2769 +       sw      t1, LTQ_MC_DDR_CCR_OFFSET(7)(t0)
2770 +
2771 +       /*
2772 +        * Wait until DLL has locked and core is ready for data transfers.
2773 +        * DLL lock indication is in register CCR47 and CCR48
2774 +        */
2775 +wait_ready:
2776 +       li      t1, LTQ_MC_DDR_DLL_LOCK_IND
2777 +       lw      t2, LTQ_MC_DDR_CCR_OFFSET(47)(t0)
2778 +       and     t2, t2, t1
2779 +       bne     t1, t2, wait_ready
2780 +
2781 +       lw      t2, LTQ_MC_DDR_CCR_OFFSET(48)(t0)
2782 +       and     t2, t2, t1
2783 +       bne     t1, t2, wait_ready
2784 +
2785 +#ifdef CONFIG_SYS_DRAM_PROBE
2786 +dram_probe:
2787 +       /* Initialization is finished after the second MC start */
2788 +       bnez    t4, mc_finished
2789 +
2790 +       /*
2791 +        * Preload register values for CCR03 and CCR11. Initial settings
2792 +        * are 8-bank mode enabled, 14 use address row bits, 10 used
2793 +        * column address bits.
2794 +        */
2795 +       li      t1, CONFIG_SYS_SDRAM_BASE_UC
2796 +       li      t5, MC_CCR03_VALUE
2797 +       li      t6, MC_CCR11_VALUE
2798 +       addi    t4, t4, 1
2799 +
2800 +       /*
2801 +        * Store test values to DRAM at offsets 0 and 2^13 (bit 2 in bank select
2802 +        * address BA[3]) and read back the value at offset 0. If the resulting
2803 +        * value is equal to 1 we can skip to the next test. Otherwise
2804 +        * the 8-bank mode does not work with the current DRAM device,
2805 +        * thus we need to clear the according bit in register CCR03.
2806 +        */
2807 +       li      t2, 1
2808 +       sw      t2, 0x0(t1)
2809 +       li      t3, (1 << 13)
2810 +       add     t3, t3, t1
2811 +       sw      zero, 0(t3)
2812 +       lw      t3, 0(t1)
2813 +       bnez    t3, row_col_test
2814 +
2815 +       /* Clear CCR03.EIGHT_BANK_MODE */
2816 +       li      t3, ~CCR03_EIGHT_BANK_MODE
2817 +       and     t5, t5, t3
2818 +
2819 +row_col_test:
2820 +       /*
2821 +        * Store test values to DRAM at offsets 0, 2^27 (bit 13 of row address
2822 +        * RA[14]) and 2^26 (bit 12 of RA[14]). The chosen test values
2823 +        * represent the difference between max. row address bits (14) and used
2824 +        * row address bits. Then the read back value at offset 0 indicates
2825 +        * the useable row address bits with the current DRAM device. This
2826 +        * value must be set in the CCR11 register.
2827 +        */
2828 +       sw      zero, 0(t1)
2829 +
2830 +       li      t2, 1
2831 +       li      t3, (1 << 27)
2832 +       add     t3, t3, t1
2833 +       sw      t2, 0(t3)
2834 +
2835 +       li      t2, 2
2836 +       li      t3, (1 << 26)
2837 +       add     t3, t3, t1
2838 +       sw      t2, 0(t3)
2839 +
2840 +       /* Update CCR11.ADDR_PINS */
2841 +       lw      t3, 0(t1)
2842 +       add     t6, t6, t3
2843 +
2844 +       /*
2845 +        * Store test values to DRAM at offsets 0, 2^10 (bit 9 of column address
2846 +        * CA[10]) and 2^9 (bit 8 of CA[10]). The chosen test values represent
2847 +        * the difference between max. column address bits (12) and used
2848 +        * column address bits. Then the read back value at offset 0 indicates
2849 +        * the useable column address bits with the current DRAM device. This
2850 +        * value must be set in the CCR11 register.
2851 +        */
2852 +       sw      zero, 0(t1)
2853 +
2854 +       li      t2, 1
2855 +       li      t3, (1 << 10)
2856 +       add     t3, t3, t1
2857 +       sw      t2, 0(t3)
2858 +
2859 +       li      t2, 2
2860 +       li      t3, (1 << 9)
2861 +       add     t3, t3, t1
2862 +       sw      t2, 0(t3)
2863 +
2864 +       /* Update CCR11.COLUMN_SIZE */
2865 +       lw      t3, 0(t1)
2866 +       sll     t3, t3, 24
2867 +       add     t6, t6, t3
2868 +
2869 +       /* Put memory controller in inactive mode */
2870 +       sw      zero, LTQ_MC_DDR_CCR_OFFSET(7)(t0)
2871 +
2872 +       /* Update CCR03 and CCR11 and restart memory controller initialiation */
2873 +       sw      t5, LTQ_MC_DDR_CCR_OFFSET(3)(t0)
2874 +       sw      t6, LTQ_MC_DDR_CCR_OFFSET(11)(t0)
2875 +       b       mc_start
2876 +
2877 +mc_finished:
2878 +#endif /* CONFIG_SYS_DRAM_PROBE */
2879 +
2880 +       jr      ra
2881 +
2882 +       END(ltq_mem_init)
2883 --- /dev/null
2884 +++ b/arch/mips/cpu/mips32/vrx200/pmu.c
2885 @@ -0,0 +1,130 @@
2886 +/*
2887 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
2888 + *
2889 + * SPDX-License-Identifier:    GPL-2.0+
2890 + */
2891 +
2892 +#include <common.h>
2893 +#include <asm/lantiq/io.h>
2894 +#include <asm/lantiq/pm.h>
2895 +#include <asm/arch/soc.h>
2896 +
2897 +#define LTQ_PMU_PWDCR_RESERVED         ((1 << 13) | (1 << 4))
2898 +
2899 +#define LTQ_PMU_PWDCR_PCIELOC_EN       (1 << 31)
2900 +#define LTQ_PMU_PWDCR_GPHY             (1 << 30)
2901 +#define LTQ_PMU_PWDCR_PPE_TOP          (1 << 29)
2902 +#define LTQ_PMU_PWDCR_SWITCH           (1 << 28)
2903 +#define LTQ_PMU_PWDCR_USB1             (1 << 27)
2904 +#define LTQ_PMU_PWDCR_USB1_PHY         (1 << 26)
2905 +#define LTQ_PMU_PWDCR_TDM              (1 << 25)
2906 +#define LTQ_PMU_PWDCR_PPE_DPLUS                (1 << 24)
2907 +#define LTQ_PMU_PWDCR_PPE_DPLUM                (1 << 23)
2908 +#define LTQ_PMU_PWDCR_PPE_EMA          (1 << 22)
2909 +#define LTQ_PMU_PWDCR_PPE_TC           (1 << 21)
2910 +#define LTQ_PMU_PWDCR_DEU              (1 << 20)
2911 +#define LTQ_PMU_PWDCR_PPE_SLL01                (1 << 19)
2912 +#define LTQ_PMU_PWDCR_PPE_QSB          (1 << 18)
2913 +#define LTQ_PMU_PWDCR_UART1            (1 << 17)
2914 +#define LTQ_PMU_PWDCR_SDIO             (1 << 16)
2915 +#define LTQ_PMU_PWDCR_AHBM             (1 << 15)
2916 +#define LTQ_PMU_PWDCR_FPIM             (1 << 14)
2917 +#define LTQ_PMU_PWDCR_GPTC             (1 << 12)
2918 +#define LTQ_PMU_PWDCR_LEDC             (1 << 11)
2919 +#define LTQ_PMU_PWDCR_EBU              (1 << 10)
2920 +#define LTQ_PMU_PWDCR_DSL              (1 << 9)
2921 +#define LTQ_PMU_PWDCR_SPI              (1 << 8)
2922 +#define LTQ_PMU_PWDCR_USIF             (1 << 7)
2923 +#define LTQ_PMU_PWDCR_USB0             (1 << 6)
2924 +#define LTQ_PMU_PWDCR_DMA              (1 << 5)
2925 +#define LTQ_PMU_PWDCR_DFEV1            (1 << 3)
2926 +#define LTQ_PMU_PWDCR_DFEV0            (1 << 2)
2927 +#define LTQ_PMU_PWDCR_FPIS             (1 << 1)
2928 +#define LTQ_PMU_PWDCR_USB0_PHY         (1 << 0)
2929 +
2930 +struct ltq_pmu_regs {
2931 +       u32     rsvd0[7];
2932 +       u32     pwdcr;          /* Power down control */
2933 +       u32     sr;             /* Power down status */
2934 +       u32     pwdcr1;         /* Power down control 1 */
2935 +       u32     sr1;            /* Power down status 1 */
2936 +};
2937 +
2938 +static struct ltq_pmu_regs *ltq_pmu_regs =
2939 +       (struct ltq_pmu_regs *) CKSEG1ADDR(LTQ_PMU_BASE);
2940 +
2941 +u32 ltq_pm_map(enum ltq_pm_modules module)
2942 +{
2943 +       u32 val;
2944 +
2945 +       switch (module) {
2946 +       case LTQ_PM_CORE:
2947 +               val = LTQ_PMU_PWDCR_UART1 | LTQ_PMU_PWDCR_FPIM |
2948 +                       LTQ_PMU_PWDCR_LEDC | LTQ_PMU_PWDCR_EBU;
2949 +               break;
2950 +       case LTQ_PM_DMA:
2951 +               val = LTQ_PMU_PWDCR_DMA;
2952 +               break;
2953 +       case LTQ_PM_ETH:
2954 +               val = LTQ_PMU_PWDCR_GPHY | LTQ_PMU_PWDCR_PPE_TOP |
2955 +                       LTQ_PMU_PWDCR_SWITCH | LTQ_PMU_PWDCR_PPE_DPLUS |
2956 +                       LTQ_PMU_PWDCR_PPE_DPLUM | LTQ_PMU_PWDCR_PPE_EMA |
2957 +                       LTQ_PMU_PWDCR_PPE_TC | LTQ_PMU_PWDCR_PPE_SLL01 |
2958 +                       LTQ_PMU_PWDCR_PPE_QSB;
2959 +               break;
2960 +       case LTQ_PM_SPI:
2961 +               val = LTQ_PMU_PWDCR_SPI;
2962 +               break;
2963 +       default:
2964 +               val = 0;
2965 +               break;
2966 +       }
2967 +
2968 +       return val;
2969 +}
2970 +
2971 +int ltq_pm_enable(enum ltq_pm_modules module)
2972 +{
2973 +       const unsigned long timeout = 1000;
2974 +       unsigned long timebase;
2975 +       u32 sr, val;
2976 +
2977 +       val = ltq_pm_map(module);
2978 +       if (unlikely(!val))
2979 +               return 1;
2980 +
2981 +       ltq_clrbits(&ltq_pmu_regs->pwdcr, val);
2982 +
2983 +       timebase = get_timer(0);
2984 +
2985 +       do {
2986 +               sr = ltq_readl(&ltq_pmu_regs->sr);
2987 +               if (~sr & val)
2988 +                       return 0;
2989 +       } while (get_timer(timebase) < timeout);
2990 +
2991 +       return 1;
2992 +}
2993 +
2994 +int ltq_pm_disable(enum ltq_pm_modules module)
2995 +{
2996 +       u32 val;
2997 +
2998 +       val = ltq_pm_map(module);
2999 +       if (unlikely(!val))
3000 +               return 1;
3001 +
3002 +       ltq_setbits(&ltq_pmu_regs->pwdcr, val);
3003 +
3004 +       return 0;
3005 +}
3006 +
3007 +void ltq_pmu_init(void)
3008 +{
3009 +       u32 set, clr;
3010 +
3011 +       clr = ltq_pm_map(LTQ_PM_CORE);
3012 +       set = ~(LTQ_PMU_PWDCR_RESERVED | clr);
3013 +
3014 +       ltq_clrsetbits(&ltq_pmu_regs->pwdcr, clr, set);
3015 +}
3016 --- /dev/null
3017 +++ b/arch/mips/cpu/mips32/vrx200/rcu.c
3018 @@ -0,0 +1,194 @@
3019 +/*
3020 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
3021 + *
3022 + * SPDX-License-Identifier:    GPL-2.0+
3023 + */
3024 +
3025 +#include <common.h>
3026 +#include <asm/lantiq/io.h>
3027 +#include <asm/lantiq/reset.h>
3028 +#include <asm/lantiq/cpu.h>
3029 +#include <asm/arch/soc.h>
3030 +
3031 +#define LTQ_RCU_RD_GPHY0       (1 << 31)       /* GPHY0 */
3032 +#define LTQ_RCU_RD_SRST                (1 << 30)       /* Global SW Reset */
3033 +#define LTQ_RCU_RD_GPHY1       (1 << 29)       /* GPHY1 */
3034 +#define LTQ_RCU_RD_ENMIP2      (1 << 28)       /* Enable NMI of PLL2 */
3035 +#define LTQ_RCU_RD_REG25_PD    (1 << 26)       /* Power down 2.5V regulator */
3036 +#define LTQ_RCU_RD_ENDINIT     (1 << 25)       /* FPI slave bus access */
3037 +#define LTQ_RCU_RD_PPE_ATM_TC  (1 << 23)       /* PPE ATM TC */
3038 +#define LTQ_RCU_RD_PCIE                (1 << 22)       /* PCI-E core */
3039 +#define LTQ_RCU_RD_ETHSW       (1 << 21)       /* Ethernet switch */
3040 +#define LTQ_RCU_RD_DSP_DEN     (1 << 20)       /* Enable DSP JTAG */
3041 +#define LTQ_RCU_RD_TDM         (1 << 19)       /* TDM module interface */
3042 +#define LTQ_RCU_RD_ENMIP1      (1 << 18)       /* Enable NMI of PLL1 */
3043 +#define LTQ_RCU_RD_SWBCK       (1 << 17)       /* Switch backward compat */
3044 +#define LTQ_RCU_RD_HSNAND      (1 << 16)       /* HSNAND controller */
3045 +#define LTQ_RCU_RD_ENMIP0      (1 << 15)       /* Enable NMI of PLL0 */
3046 +#define LTQ_RCU_RD_MC          (1 << 14)       /* Memory Controller */
3047 +#define LTQ_RCU_RD_PCI         (1 << 13)       /* PCI core */
3048 +#define LTQ_RCU_RD_PCIE_PHY    (1 << 12)       /* PCI-E Phy */
3049 +#define LTQ_RCU_RD_DFE_CORE    (1 << 11)       /* DFE core */
3050 +#define LTQ_RCU_RD_SDIO                (1 << 10)       /* SDIO core */
3051 +#define LTQ_RCU_RD_DMA         (1 << 9)        /* DMA core */
3052 +#define LTQ_RCU_RD_PPE         (1 << 8)        /* PPE core */
3053 +#define LTQ_RCU_RD_DFE         (1 << 7)        /* DFE core */
3054 +#define LTQ_RCU_RD_AHB         (1 << 6)        /* AHB bus */
3055 +#define LTQ_RCU_RD_HRST_CFG    (1 << 5)        /* HW reset configuration */
3056 +#define LTQ_RCU_RD_USB         (1 << 4)        /* USB and Phy core */
3057 +#define LTQ_RCU_RD_PPE_DSP     (1 << 3)        /* PPE DSP interface */
3058 +#define LTQ_RCU_RD_FPI         (1 << 2)        /* FPI bus */
3059 +#define LTQ_RCU_RD_CPU         (1 << 1)        /* CPU subsystem */
3060 +#define LTQ_RCU_RD_HRST                (1 << 0)        /* HW reset via HRST pin */
3061 +
3062 +#define LTQ_RCU_STAT_BOOT_SHIFT                17
3063 +#define LTQ_RCU_STAT_BOOT_MASK         (0xF << LTQ_RCU_STAT_BOOT_SHIFT)
3064 +#define LTQ_RCU_STAT_BOOT_H            (1 << 12)
3065 +
3066 +#define LTQ_RCU_GP_STRAP_CLOCKSOURCE   (1 << 15)
3067 +
3068 +struct ltq_rcu_regs {
3069 +       u32     rsvd0[4];
3070 +       u32     req;            /* Reset request */
3071 +       u32     stat;           /* Reset status */
3072 +       u32     usb0_cfg;       /* USB0 configure */
3073 +       u32     gp_strap;       /* GPIO strapping */
3074 +       u32     gfs_add0;       /* GPHY0 firmware base addr */
3075 +       u32     stat2;          /* SLIC and USB reset status */
3076 +       u32     pci_rdy;        /* PCI boot ready */
3077 +       u32     ppe_conf;       /* PPE ethernet config */
3078 +       u32     pcie_phy_con;   /* PCIE PHY config/status */
3079 +       u32     usb1_cfg;       /* USB1 configure */
3080 +       u32     usb_ana_cfg1a;  /* USB analog config 1a */
3081 +       u32     usb_ana_cfg1b;  /* USB analog config 1b */
3082 +       u32     rsvd1;
3083 +       u32     gf_mdio_add;    /* GPHY0/1 MDIO address */
3084 +       u32     req2;           /* SLIC and USB reset request */
3085 +       u32     ahb_endian;     /* AHB bus endianess */
3086 +       u32     rsvd2[4];
3087 +       u32     gcc;            /* General CPU config */
3088 +       u32     rsvd3;
3089 +       u32     gfs_add1;       /* GPHY1 firmware base addr */
3090 +};
3091 +
3092 +static struct ltq_rcu_regs *ltq_rcu_regs =
3093 +       (struct ltq_rcu_regs *) CKSEG1ADDR(LTQ_RCU_BASE);
3094 +
3095 +u32 ltq_reset_map(enum ltq_reset_modules module)
3096 +{
3097 +       u32 val;
3098 +
3099 +       switch (module) {
3100 +       case LTQ_RESET_CORE:
3101 +       case LTQ_RESET_SOFT:
3102 +               val = LTQ_RCU_RD_SRST | LTQ_RCU_RD_CPU | LTQ_RCU_RD_ENMIP2 |
3103 +                       LTQ_RCU_RD_GPHY1 | LTQ_RCU_RD_GPHY0;
3104 +               break;
3105 +       case LTQ_RESET_DMA:
3106 +               val = LTQ_RCU_RD_DMA;
3107 +               break;
3108 +       case LTQ_RESET_ETH:
3109 +               val = LTQ_RCU_RD_PPE | LTQ_RCU_RD_ETHSW;
3110 +               break;
3111 +       case LTQ_RESET_PHY:
3112 +               val = LTQ_RCU_RD_GPHY1 | LTQ_RCU_RD_GPHY0;
3113 +               break;
3114 +       case LTQ_RESET_HARD:
3115 +               val = LTQ_RCU_RD_HRST;
3116 +               break;
3117 +       default:
3118 +               val = 0;
3119 +               break;
3120 +       }
3121 +
3122 +       return val;
3123 +}
3124 +
3125 +int ltq_reset_activate(enum ltq_reset_modules module)
3126 +{
3127 +       u32 val;
3128 +
3129 +       val = ltq_reset_map(module);
3130 +       if (unlikely(!val))
3131 +               return 1;
3132 +
3133 +       ltq_setbits(&ltq_rcu_regs->req, val);
3134 +
3135 +       return 0;
3136 +}
3137 +
3138 +int ltq_reset_deactivate(enum ltq_reset_modules module)
3139 +{
3140 +       u32 val;
3141 +
3142 +       val = ltq_reset_map(module);
3143 +       if (unlikely(!val))
3144 +               return 1;
3145 +
3146 +       ltq_clrbits(&ltq_rcu_regs->req, val);
3147 +
3148 +       return 0;
3149 +}
3150 +
3151 +enum ltq_boot_select ltq_boot_select(void)
3152 +{
3153 +       u32 stat;
3154 +       unsigned int bootstrap;
3155 +
3156 +       /*
3157 +        * Boot select value is built from bits 20-17 and bit 12.
3158 +        * The bit sequence is read as 4-2-1-0-3.
3159 +        */
3160 +       stat = ltq_readl(&ltq_rcu_regs->stat);
3161 +       bootstrap = ((stat & LTQ_RCU_STAT_BOOT_H) << 4) |
3162 +               ((stat & LTQ_RCU_STAT_BOOT_MASK) >> LTQ_RCU_STAT_BOOT_SHIFT);
3163 +
3164 +       switch (bootstrap) {
3165 +       case 0:
3166 +               return BOOT_NOR_NO_BOOTROM;
3167 +       case 1:
3168 +               return BOOT_RGMII1;
3169 +       case 2:
3170 +               return BOOT_NOR;
3171 +       case 4:
3172 +               return BOOT_UART_NO_EEPROM;
3173 +       case 6:
3174 +               return BOOT_PCI;
3175 +       case 8:
3176 +               return BOOT_UART;
3177 +       case 10:
3178 +               return BOOT_SPI;
3179 +       case 12:
3180 +               return BOOT_NAND;
3181 +       default:
3182 +               return BOOT_UNKNOWN;
3183 +       }
3184 +}
3185 +
3186 +void ltq_rcu_gphy_boot(unsigned int id, ulong addr)
3187 +{
3188 +       u32 module;
3189 +       void *gfs_add;
3190 +
3191 +       switch (id) {
3192 +       case 0:
3193 +               module = LTQ_RCU_RD_GPHY0;
3194 +               gfs_add = &ltq_rcu_regs->gfs_add0;
3195 +               break;
3196 +       case 1:
3197 +               module = LTQ_RCU_RD_GPHY1;
3198 +               gfs_add = &ltq_rcu_regs->gfs_add1;
3199 +               break;
3200 +       default:
3201 +               BUG();
3202 +       }
3203 +
3204 +       /* Stop and reset GPHY */
3205 +       ltq_setbits(&ltq_rcu_regs->req, module);
3206 +
3207 +       /* Configure firmware and boot address */
3208 +       ltq_writel(gfs_add, CPHYSADDR(addr & 0xFFFFC000));
3209 +
3210 +       /* Start GPHY by releasing reset */
3211 +       ltq_clrbits(&ltq_rcu_regs->req, module);
3212 +}
3213 --- /dev/null
3214 +++ b/arch/mips/include/asm/arch-danube/config.h
3215 @@ -0,0 +1,163 @@
3216 +/*
3217 + * Copyright (C) 2007-2010 Lantiq Deutschland GmbH
3218 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
3219 + *
3220 + * SPDX-License-Identifier:    GPL-2.0+
3221 + *
3222 + * Common board configuration for Lantiq XWAY Danube family
3223 + *
3224 + * Use following defines in your board config to enable specific features
3225 + * and drivers for this SoC:
3226 + *
3227 + * CONFIG_LTQ_SUPPORT_UART
3228 + * - support the Danube ASC/UART interface and console
3229 + *
3230 + * CONFIG_LTQ_SUPPORT_NOR_FLASH
3231 + * - support a parallel NOR flash via the CFI interface in flash bank 0
3232 + *
3233 + * CONFIG_LTQ_SUPPORT_ETHERNET
3234 + * - support the Danube ETOP and MAC interface
3235 + *
3236 + * CONFIG_LTQ_SUPPORT_SPI_FLASH
3237 + * - support the Danube SPI interface and serial flash drivers
3238 + * - specific SPI flash drivers must be configured separately
3239 + */
3240 +
3241 +#ifndef __DANUBE_CONFIG_H__
3242 +#define __DANUBE_CONFIG_H__
3243 +
3244 +/* CPU and SoC type */
3245 +#define CONFIG_SOC_LANTIQ
3246 +#define CONFIG_SOC_XWAY_DANUBE
3247 +
3248 +/* Cache configuration */
3249 +#define CONFIG_SYS_MIPS_CACHE_MODE     CONF_CM_CACHABLE_NONCOHERENT
3250 +#define CONFIG_SYS_DCACHE_SIZE         (16 * 1024)
3251 +#define CONFIG_SYS_ICACHE_SIZE         (16 * 1024)
3252 +#define CONFIG_SYS_CACHELINE_SIZE      32
3253 +#define CONFIG_SYS_MIPS_CACHE_EXT_INIT
3254 +
3255 +/*
3256 + * Supported clock modes
3257 + * PLL0 clock output is 333 MHz
3258 + * PLL1 clock output is 262.144 MHz
3259 + */
3260 +#define LTQ_CLK_CPU_333_DDR_167                0       /* Base PLL0, OCP 2 */
3261 +#define LTQ_CLK_CPU_111_DDR_111                1       /* Base PLL0, OCP 1 */
3262 +
3263 +/* CPU speed */
3264 +#define CONFIG_SYS_CLOCK_MODE          LTQ_CLK_CPU_333_DDR_167
3265 +#define CONFIG_SYS_MIPS_TIMER_FREQ     166666667
3266 +#define CONFIG_SYS_HZ                  1000
3267 +
3268 +/* RAM */
3269 +#define CONFIG_NR_DRAM_BANKS           1
3270 +#define CONFIG_SYS_SDRAM_BASE          0x80000000
3271 +#define CONFIG_SYS_MEMTEST_START       0x81000000
3272 +#define CONFIG_SYS_MEMTEST_END         0x82000000
3273 +#define CONFIG_SYS_LOAD_ADDR           0x81000000
3274 +#define CONFIG_SYS_INIT_SP_OFFSET      0x4000
3275 +
3276 +/* SRAM */
3277 +#define CONFIG_SYS_SRAM_BASE           0xBE1A0000
3278 +#define CONFIG_SYS_SRAM_SIZE           0x10000
3279 +
3280 +/* ASC/UART driver and console */
3281 +#define CONFIG_LANTIQ_SERIAL
3282 +#define CONFIG_SYS_BAUDRATE_TABLE      { 9600, 19200, 38400, 57600, 115200 }
3283 +
3284 +/* GPIO */
3285 +#define CONFIG_LANTIQ_GPIO
3286 +#define CONFIG_LTQ_GPIO_MAX_BANKS      2
3287 +
3288 +/* FLASH driver */
3289 +#if defined(CONFIG_LTQ_SUPPORT_NOR_FLASH)
3290 +#define CONFIG_SYS_MAX_FLASH_BANKS     1
3291 +#define CONFIG_SYS_MAX_FLASH_SECT      256
3292 +#define CONFIG_SYS_FLASH_BASE          0xB0000000
3293 +#define CONFIG_FLASH_16BIT
3294 +#define CONFIG_SYS_FLASH_CFI
3295 +#define CONFIG_FLASH_CFI_DRIVER
3296 +#define CONFIG_SYS_FLASH_CFI_WIDTH     FLASH_CFI_16BIT
3297 +#define CONFIG_SYS_FLASH_USE_BUFFER_WRITE
3298 +#define CONFIG_FLASH_SHOW_PROGRESS     50
3299 +#define CONFIG_SYS_FLASH_PROTECTION
3300 +#define CONFIG_CFI_FLASH_USE_WEAK_ADDR_SWAP
3301 +
3302 +#define CONFIG_CMD_FLASH
3303 +#else
3304 +#define CONFIG_SYS_NO_FLASH
3305 +#endif /* CONFIG_NOR_FLASH */
3306 +
3307 +#if defined(CONFIG_LTQ_SUPPORT_SPI_FLASH)
3308 +#define CONFIG_LANTIQ_SPI
3309 +#define CONFIG_SPI_FLASH
3310 +
3311 +#define CONFIG_CMD_SF
3312 +#define CONFIG_CMD_SPI
3313 +#endif
3314 +
3315 +#if defined(CONFIG_LTQ_SUPPORT_NAND_FLASH)
3316 +#define CONFIG_NAND_LANTIQ
3317 +#define CONFIG_SYS_MAX_NAND_DEVICE     1
3318 +#define CONFIG_SYS_NAND_BASE           0xB4000000
3319 +
3320 +#define CONFIG_CMD_NAND
3321 +#endif
3322 +
3323 +#if defined(CONFIG_LTQ_SUPPORT_ETHERNET)
3324 +#define CONFIG_LANTIQ_DMA
3325 +#define CONFIG_LANTIQ_DANUBE_ETOP
3326 +
3327 +#define CONFIG_PHYLIB
3328 +#define CONFIG_MII
3329 +
3330 +#define CONFIG_CMD_MII
3331 +#define CONFIG_CMD_NET
3332 +#endif
3333 +
3334 +#define CONFIG_SPL_MAX_SIZE            (32 * 1024)
3335 +#define CONFIG_SPL_BSS_MAX_SIZE                (8 * 1024)
3336 +#define CONFIG_SPL_STACK_MAX_SIZE      (8 * 1024)
3337 +#define CONFIG_SPL_MALLOC_MAX_SIZE     (32 * 1024)
3338 +/*#define CONFIG_SPL_STACK_BSS_IN_SRAM*/
3339 +
3340 +#if defined(CONFIG_SPL_STACK_BSS_IN_SRAM)
3341 +#define CONFIG_SPL_STACK_BASE          (CONFIG_SYS_SRAM_BASE + \
3342 +                                       CONFIG_SPL_MAX_SIZE + \
3343 +                                       CONFIG_SPL_STACK_MAX_SIZE - 1)
3344 +#define CONFIG_SPL_BSS_BASE            (CONFIG_SPL_STACK_BASE + 1)
3345 +#define CONFIG_SPL_MALLOC_BASE         (CONFIG_SYS_SDRAM_BASE + \
3346 +                                       CONFIG_SYS_INIT_SP_OFFSET)
3347 +#else
3348 +#define CONFIG_SPL_STACK_BASE          (CONFIG_SYS_SDRAM_BASE + \
3349 +                                       CONFIG_SYS_INIT_SP_OFFSET + \
3350 +                                       CONFIG_SPL_STACK_MAX_SIZE - 1)
3351 +#define CONFIG_SPL_BSS_BASE            (CONFIG_SPL_STACK_BASE + 1)
3352 +#define CONFIG_SPL_MALLOC_BASE         (CONFIG_SPL_BSS_BASE + \
3353 +                                       CONFIG_SPL_BSS_MAX_SIZE)
3354 +#endif
3355 +
3356 +#if defined(CONFIG_SYS_BOOT_RAM)
3357 +#define CONFIG_SYS_TEXT_BASE           0xa0100000
3358 +#define CONFIG_SKIP_LOWLEVEL_INIT
3359 +#define CONFIG_SYS_DISABLE_CACHE
3360 +#endif
3361 +
3362 +#if defined(CONFIG_SYS_BOOT_NOR)
3363 +#define CONFIG_SYS_TEXT_BASE           0xB0000000
3364 +#endif
3365 +
3366 +#if defined(CONFIG_SYS_BOOT_NORSPL)
3367 +#define CONFIG_SYS_TEXT_BASE           0x80100000
3368 +#define CONFIG_SPL_TEXT_BASE           0xB0000000
3369 +#endif
3370 +
3371 +#if defined(CONFIG_SYS_BOOT_NOR) || defined(CONFIG_SYS_BOOT_NORSPL)
3372 +#define CONFIG_SYS_XWAY_EBU_BOOTCFG    0x688C688C
3373 +#define CONFIG_XWAY_SWAP_BYTES
3374 +#endif
3375 +
3376 +#define        CONFIG_SYS_MONITOR_BASE         CONFIG_SYS_TEXT_BASE
3377 +
3378 +#endif /* __DANUBE_CONFIG_H__ */
3379 --- /dev/null
3380 +++ b/arch/mips/include/asm/arch-danube/gpio.h
3381 @@ -0,0 +1,12 @@
3382 +/*
3383 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
3384 + *
3385 + * SPDX-License-Identifier:    GPL-2.0+
3386 + */
3387 +
3388 +#ifndef __DANUBE_GPIO_H__
3389 +#define __DANUBE_GPIO_H__
3390 +
3391 +#include <asm/lantiq/gpio.h>
3392 +
3393 +#endif /* __DANUBE_GPIO_H__ */
3394 --- /dev/null
3395 +++ b/arch/mips/include/asm/arch-danube/nand.h
3396 @@ -0,0 +1,13 @@
3397 +/*
3398 + * Copyright (C) 2012-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
3399 + *
3400 + * SPDX-License-Identifier:    GPL-2.0+
3401 + */
3402 +
3403 +#ifndef __DANUBE_NAND_H__
3404 +#define __DANUBE_NAND_H__
3405 +
3406 +struct nand_chip;
3407 +int ltq_nand_init(struct nand_chip *nand);
3408 +
3409 +#endif /* __DANUBE_NAND_H__ */
3410 --- /dev/null
3411 +++ b/arch/mips/include/asm/arch-danube/soc.h
3412 @@ -0,0 +1,38 @@
3413 +/*
3414 + * Copyright (C) 2007-2010 Lantiq Deutschland GmbH
3415 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
3416 + *
3417 + * SPDX-License-Identifier:    GPL-2.0+
3418 + */
3419 +
3420 +#ifndef __DANUBE_SOC_H__
3421 +#define __DANUBE_SOC_H__
3422 +
3423 +#define LTQ_ASC0_BASE                  0x1E100400
3424 +#define LTQ_SPI_BASE                   0x1E100800
3425 +#define LTQ_GPIO_BASE                  0x1E100B00
3426 +#define LTQ_SSIO_BASE                  0x1E100BB0
3427 +#define LTQ_ASC1_BASE                  0x1E100C00
3428 +#define LTQ_DMA_BASE                   0x1E104100
3429 +
3430 +#define LTQ_EBU_BASE                   0x1E105300
3431 +#define LTQ_EBU_REGION0_BASE           0x10000000
3432 +#define LTQ_EBU_REGION1_BASE           0x14000000
3433 +#define LTQ_EBU_NAND_BASE              (LTQ_EBU_BASE + 0xB0)
3434 +
3435 +#define LTQ_PPE_BASE                   0x1E180000
3436 +#define LTQ_PPE_ETOP_BASE              (LTQ_PPE_BASE + 0x11800)
3437 +#define LTQ_PPE_ENET0_BASE             (LTQ_PPE_BASE + 0x11840)
3438 +
3439 +#define LTQ_PMU_BASE                   0x1F102000
3440 +#define LTQ_CGU_BASE                   0x1F103000
3441 +#define LTQ_MPS_BASE                   0x1F107000
3442 +#define LTQ_CHIPID_BASE                        (LTQ_MPS_BASE + 0x340)
3443 +#define LTQ_RCU_BASE                   0x1F203000
3444 +
3445 +#define LTQ_MC_GEN_BASE                        0x1F800000
3446 +#define LTQ_MC_SDR_BASE                        0x1F800200
3447 +#define LTQ_MC_DDR_BASE                        0x1F801000
3448 +#define LTQ_MC_DDR_DC_OFFSET(x)                (x * 0x10)
3449 +
3450 +#endif /* __DANUBE_SOC_H__ */
3451 --- /dev/null
3452 +++ b/arch/mips/include/asm/arch-vrx200/config.h
3453 @@ -0,0 +1,184 @@
3454 +/*
3455 + * Copyright (C) 2010 Lantiq Deutschland GmbH
3456 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
3457 + *
3458 + * SPDX-License-Identifier:    GPL-2.0+
3459 + *
3460 + * Common board configuration for Lantiq XWAY VRX200 family
3461 + *
3462 + * Use following defines in your board config to enable specific features
3463 + * and drivers for this SoC:
3464 + *
3465 + * CONFIG_LTQ_SUPPORT_UART
3466 + * - support the VRX200 ASC/UART interface and console
3467 + *
3468 + * CONFIG_LTQ_SUPPORT_NOR_FLASH
3469 + * - support a parallel NOR flash via the CFI interface in flash bank 0
3470 + *
3471 + * CONFIG_LTQ_SUPPORT_ETHERNET
3472 + * - support the VRX200 internal switch
3473 + *
3474 + * CONFIG_LTQ_SUPPORT_SPI_FLASH
3475 + * - support the VRX200 SPI interface and serial flash drivers
3476 + * - specific SPI flash drivers must be configured separately
3477 + *
3478 + * CONFIG_LTQ_SUPPORT_SPL_SPI_FLASH
3479 + * - build a preloader that runs in the internal SRAM and loads
3480 + *   the U-Boot from SPI flash into RAM
3481 + */
3482 +
3483 +#ifndef __VRX200_CONFIG_H__
3484 +#define __VRX200_CONFIG_H__
3485 +
3486 +/* CPU and SoC type */
3487 +#define CONFIG_SOC_LANTIQ
3488 +#define CONFIG_SOC_XWAY_VRX200
3489 +
3490 +/* Cache configuration */
3491 +#define CONFIG_SYS_MIPS_CACHE_MODE     CONF_CM_CACHABLE_NONCOHERENT
3492 +#define CONFIG_SYS_DCACHE_SIZE         (32 * 1024)
3493 +#define CONFIG_SYS_ICACHE_SIZE         (32 * 1024)
3494 +#define CONFIG_SYS_CACHELINE_SIZE      32
3495 +#define CONFIG_SYS_MIPS_CACHE_EXT_INIT
3496 +
3497 +/*
3498 + * Supported clock modes
3499 + * PLL0 clock output is 1000 MHz
3500 + * PLL1 clock output is 393.219 MHz
3501 + */
3502 +#define LTQ_CLK_CPU_600_DDR_300        0       /* Base PLL0, OCP 2 */
3503 +#define LTQ_CLK_CPU_600_DDR_200        1       /* Base PLL0, OCP 3 */
3504 +#define LTQ_CLK_CPU_500_DDR_250        2       /* Base PLL0, OCP 2 */
3505 +#define LTQ_CLK_CPU_500_DDR_200        3       /* Base PLL0, OCP 2.5 */
3506 +#define LTQ_CLK_CPU_333_DDR_167        4       /* Base PLL0, OCP 2 */
3507 +#define LTQ_CLK_CPU_167_DDR_167        5       /* Base PLL0, OCP 1 */
3508 +#define LTQ_CLK_CPU_125_DDR_125        6       /* Base PLL0, OCP 1 */
3509 +#define LTQ_CLK_CPU_393_DDR_197        7       /* Base PLL1, OCP 2 */
3510 +#define LTQ_CLK_CPU_197_DDR_197        8       /* Base PLL1, OCP 1 */
3511 +
3512 +/* CPU speed */
3513 +#define CONFIG_SYS_CLOCK_MODE          LTQ_CLK_CPU_500_DDR_250
3514 +#define CONFIG_SYS_MIPS_TIMER_FREQ     250000000
3515 +#define CONFIG_SYS_HZ                  1000
3516 +
3517 +/* RAM */
3518 +#define CONFIG_NR_DRAM_BANKS           1
3519 +#define CONFIG_SYS_SDRAM_BASE          0x80000000
3520 +#define CONFIG_SYS_SDRAM_BASE_UC       0xa0000000
3521 +#define CONFIG_SYS_MEMTEST_START       0x81000000
3522 +#define CONFIG_SYS_MEMTEST_END         0x82000000
3523 +#define CONFIG_SYS_LOAD_ADDR           0x81000000
3524 +#define CONFIG_SYS_INIT_SP_OFFSET      (32 * 1024)
3525 +
3526 +/* SRAM */
3527 +#define CONFIG_SYS_SRAM_BASE           0xBE220000
3528 +#define CONFIG_SYS_SRAM_SIZE           0x10000
3529 +
3530 +/* ASC/UART driver and console */
3531 +#define CONFIG_LANTIQ_SERIAL
3532 +#define CONFIG_SYS_BAUDRATE_TABLE      { 9600, 19200, 38400, 57600, 115200 }
3533 +
3534 +/* GPIO */
3535 +#define CONFIG_LANTIQ_GPIO
3536 +#define CONFIG_LTQ_GPIO_MAX_BANKS      3
3537 +#define CONFIG_LTQ_HAS_GPIO_BANK3
3538 +
3539 +/* FLASH driver */
3540 +#if defined(CONFIG_LTQ_SUPPORT_NOR_FLASH)
3541 +#define CONFIG_SYS_MAX_FLASH_BANKS     1
3542 +#define CONFIG_SYS_MAX_FLASH_SECT      256
3543 +#define CONFIG_SYS_FLASH_BASE          0xB0000000
3544 +#define CONFIG_FLASH_16BIT
3545 +#define CONFIG_SYS_FLASH_CFI
3546 +#define CONFIG_FLASH_CFI_DRIVER
3547 +#define CONFIG_SYS_FLASH_CFI_WIDTH     FLASH_CFI_16BIT
3548 +#define CONFIG_SYS_FLASH_USE_BUFFER_WRITE
3549 +#define CONFIG_FLASH_SHOW_PROGRESS     50
3550 +#define CONFIG_SYS_FLASH_PROTECTION
3551 +#define CONFIG_CFI_FLASH_USE_WEAK_ADDR_SWAP
3552 +
3553 +#define CONFIG_CMD_FLASH
3554 +#else
3555 +#define CONFIG_SYS_NO_FLASH
3556 +#endif /* CONFIG_NOR_FLASH */
3557 +
3558 +#if defined(CONFIG_LTQ_SUPPORT_SPI_FLASH)
3559 +#define CONFIG_LANTIQ_SPI
3560 +#define CONFIG_SPI_FLASH
3561 +
3562 +#define CONFIG_CMD_SF
3563 +#define CONFIG_CMD_SPI
3564 +#endif
3565 +
3566 +#if defined(CONFIG_LTQ_SUPPORT_NAND_FLASH)
3567 +#define CONFIG_NAND_LANTIQ
3568 +#define CONFIG_SYS_MAX_NAND_DEVICE     1
3569 +#define CONFIG_SYS_NAND_BASE           0xB4000000
3570 +
3571 +#define CONFIG_CMD_NAND
3572 +#endif
3573 +
3574 +#if defined(CONFIG_LTQ_SUPPORT_ETHERNET)
3575 +#define CONFIG_LANTIQ_DMA
3576 +#define CONFIG_LANTIQ_VRX200_SWITCH
3577 +#define CONFIG_PHY_LANTIQ
3578 +
3579 +#define CONFIG_SYS_RX_ETH_BUFFER       8
3580 +#define CONFIG_PHYLIB
3581 +#define CONFIG_MII
3582 +#define CONFIG_UDP_CHECKSUM
3583 +
3584 +#define CONFIG_CMD_MII
3585 +#define CONFIG_CMD_NET
3586 +#endif
3587 +
3588 +#define CONFIG_SPL_MAX_SIZE            (32 * 1024)
3589 +#define CONFIG_SPL_BSS_MAX_SIZE                (8 * 1024)
3590 +#define CONFIG_SPL_STACK_MAX_SIZE      (8 * 1024)
3591 +#define CONFIG_SPL_MALLOC_MAX_SIZE     (32 * 1024)
3592 +#define CONFIG_SPL_STACK_BSS_IN_SRAM
3593 +
3594 +#if defined(CONFIG_SPL_STACK_BSS_IN_SRAM)
3595 +#define CONFIG_SPL_STACK_BASE          (CONFIG_SYS_SRAM_BASE + \
3596 +                                       CONFIG_SPL_MAX_SIZE + \
3597 +                                       CONFIG_SPL_STACK_MAX_SIZE - 1)
3598 +#define CONFIG_SPL_BSS_BASE            (CONFIG_SPL_STACK_BASE + 1)
3599 +#define CONFIG_SPL_MALLOC_BASE         (CONFIG_SYS_SDRAM_BASE + \
3600 +                                       CONFIG_SYS_INIT_SP_OFFSET)
3601 +#else
3602 +#define CONFIG_SPL_STACK_BASE          (CONFIG_SYS_SDRAM_BASE + \
3603 +                                       CONFIG_SYS_INIT_SP_OFFSET + \
3604 +                                       CONFIG_SPL_STACK_MAX_SIZE - 1)
3605 +#define CONFIG_SPL_BSS_BASE            (CONFIG_SPL_STACK_BASE + 1)
3606 +#define CONFIG_SPL_MALLOC_BASE         (CONFIG_SPL_BSS_BASE + \
3607 +                                       CONFIG_SPL_BSS_MAX_SIZE)
3608 +#endif
3609 +
3610 +#if defined(CONFIG_SYS_BOOT_RAM)
3611 +#define CONFIG_SYS_TEXT_BASE           0xA0100000
3612 +#define CONFIG_SKIP_LOWLEVEL_INIT
3613 +#define CONFIG_SYS_DISABLE_CACHE
3614 +#endif
3615 +
3616 +#if defined(CONFIG_SYS_BOOT_NOR)
3617 +#define CONFIG_SYS_TEXT_BASE           0xB0000000
3618 +#endif
3619 +
3620 +#if defined(CONFIG_SYS_BOOT_SFSPL)
3621 +#define CONFIG_SYS_TEXT_BASE           0x80100000
3622 +#define CONFIG_SPL_TEXT_BASE           0xBE220000
3623 +#endif
3624 +
3625 +#if defined(CONFIG_SYS_BOOT_NORSPL)
3626 +#define CONFIG_SYS_TEXT_BASE           0x80100000
3627 +#define CONFIG_SPL_TEXT_BASE           0xB0000000
3628 +#endif
3629 +
3630 +#if defined(CONFIG_SYS_BOOT_NOR) || defined(CONFIG_SYS_BOOT_NORSPL)
3631 +#define CONFIG_SYS_XWAY_EBU_BOOTCFG    0x688C688C
3632 +#define CONFIG_XWAY_SWAP_BYTES
3633 +#endif
3634 +
3635 +#define        CONFIG_SYS_MONITOR_BASE         CONFIG_SYS_TEXT_BASE
3636 +
3637 +#endif /* __VRX200_CONFIG_H__ */
3638 --- /dev/null
3639 +++ b/arch/mips/include/asm/arch-vrx200/gphy.h
3640 @@ -0,0 +1,65 @@
3641 +/*
3642 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
3643 + *
3644 + * SPDX-License-Identifier:    GPL-2.0+
3645 + */
3646 +
3647 +#ifndef __VRX200_GPHY_H__
3648 +#define __VRX200_GPHY_H__
3649 +
3650 +enum ltq_gphy_clk {
3651 +       /* XTAL 36 MHz input */
3652 +       LTQ_GPHY_CLK_36MHZ_XTAL = 1,
3653 +       /* 25 MHz from PLL0 with divider */
3654 +       LTQ_GPHY_CLK_25MHZ_PLL0 = 2,
3655 +       /* derived from PLL2 output (XTAL is 36 MHz) */
3656 +       LTQ_GPHY_CLK_24MHZ_PLL2 = 3,
3657 +       /* 25 MHz Clock from Pin GPIO3 */
3658 +       LTQ_GPHY_CLK_25MHZ_GPIO3 = 4,
3659 +};
3660 +
3661 +/*
3662 + * Load PHY11G firmware for VRX200 v1.1 to given RAM address
3663 + *
3664 + * Address must be 16k aligned!
3665 + */
3666 +extern void ltq_gphy_phy11g_a1x_load(ulong addr);
3667 +
3668 +/*
3669 + * Load PHY11G firmware for VRX200 v1.2 to given RAM address
3670 + *
3671 + * Address must be 16k aligned!
3672 + */
3673 +extern void ltq_gphy_phy11g_a2x_load(ulong addr);
3674 +
3675 +/*
3676 + * Load PHY22F firmware for VRX200 v1.1 to given RAM address
3677 + *
3678 + * Address must be 16k aligned!
3679 + */
3680 +extern void ltq_gphy_phy22f_a1x_load(ulong addr);
3681 +
3682 +/*
3683 + * Load PHY22F firmware for VRX200 v1.2 to given RAM address
3684 + *
3685 + * Address must be 16k aligned!
3686 + */
3687 +extern void ltq_gphy_phy22f_a2x_load(ulong addr);
3688 +
3689 +/*
3690 + * Set clock source of internal GPHYs
3691 + *
3692 + * According registers resides in CGU address space. Thus this function
3693 + * is implemented by the CGU driver.
3694 + */
3695 +extern void ltq_cgu_gphy_clk_src(enum ltq_gphy_clk clk);
3696 +
3697 +/*
3698 + * Boot internal GPHY with id from given RAM address
3699 + *
3700 + * According registers resides in RCU address space. Thus this function
3701 + * is implemented by the RCU driver.
3702 + */
3703 +extern void ltq_rcu_gphy_boot(unsigned int id, ulong addr);
3704 +
3705 +#endif /* __VRX200_GPHY_H__ */
3706 --- /dev/null
3707 +++ b/arch/mips/include/asm/arch-vrx200/gpio.h
3708 @@ -0,0 +1,12 @@
3709 +/*
3710 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
3711 + *
3712 + * SPDX-License-Identifier:    GPL-2.0+
3713 + */
3714 +
3715 +#ifndef __VRX200_GPIO_H__
3716 +#define __VRX200_GPIO_H__
3717 +
3718 +#include <asm/lantiq/gpio.h>
3719 +
3720 +#endif /* __VRX200_GPIO_H__ */
3721 --- /dev/null
3722 +++ b/arch/mips/include/asm/arch-vrx200/nand.h
3723 @@ -0,0 +1,13 @@
3724 +/*
3725 + * Copyright (C) 2012-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
3726 + *
3727 + * SPDX-License-Identifier:    GPL-2.0+
3728 + */
3729 +
3730 +#ifndef __VRX200_NAND_H__
3731 +#define __VRX200_NAND_H__
3732 +
3733 +struct nand_chip;
3734 +int ltq_nand_init(struct nand_chip *nand);
3735 +
3736 +#endif /* __VRX200_NAND_H__ */
3737 --- /dev/null
3738 +++ b/arch/mips/include/asm/arch-vrx200/soc.h
3739 @@ -0,0 +1,45 @@
3740 +/*
3741 + * Copyright (C) 2010 Lantiq Deutschland GmbH
3742 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
3743 + *
3744 + * SPDX-License-Identifier:    GPL-2.0+
3745 + */
3746 +
3747 +#ifndef __VRX200_SOC_H__
3748 +#define __VRX200_SOC_H__
3749 +
3750 +#define LTQ_ASC0_BASE                  0x1E100400
3751 +#define LTQ_SPI_BASE                   0x1E100800
3752 +#define LTQ_GPIO_BASE                  0x1E100B00
3753 +#define LTQ_SSIO_BASE                  0x1E100BB0
3754 +#define LTQ_ASC1_BASE                  0x1E100C00
3755 +#define LTQ_DMA_BASE                   0x1E104100
3756 +
3757 +#define LTQ_EBU_BASE                   0x1E105300
3758 +#define LTQ_EBU_REGION0_BASE           0x10000000
3759 +#define LTQ_EBU_REGION1_BASE           0x14000000
3760 +#define LTQ_EBU_NAND_BASE              (LTQ_EBU_BASE + 0xB0)
3761 +
3762 +#define LTQ_SWITCH_BASE                        0x1E108000
3763 +#define LTQ_SWITCH_CORE_BASE           LTQ_SWITCH_BASE
3764 +#define LTQ_SWITCH_TOP_PDI_BASE                LTQ_SWITCH_CORE_BASE
3765 +#define LTQ_SWITCH_BM_PDI_BASE         (LTQ_SWITCH_CORE_BASE + 4 * 0x40)
3766 +#define LTQ_SWITCH_MAC_PDI_0_BASE      (LTQ_SWITCH_CORE_BASE + 4 * 0x900)
3767 +#define LTQ_SWITCH_MAC_PDI_X_BASE(x)   (LTQ_SWITCH_MAC_PDI_0_BASE + x * 0x30)
3768 +#define LTQ_SWITCH_TOPLEVEL_BASE       (LTQ_SWITCH_BASE + 4 * 0xC40)
3769 +#define LTQ_SWITCH_MDIO_PDI_BASE       (LTQ_SWITCH_TOPLEVEL_BASE)
3770 +#define LTQ_SWITCH_MII_PDI_BASE                (LTQ_SWITCH_TOPLEVEL_BASE + 4 * 0x36)
3771 +#define LTQ_SWITCH_PMAC_PDI_BASE       (LTQ_SWITCH_TOPLEVEL_BASE + 4 * 0x82)
3772 +
3773 +#define LTQ_PMU_BASE                   0x1F102000
3774 +#define LTQ_CGU_BASE                   0x1F103000
3775 +#define LTQ_DCDC_BASE                  0x1F106A00
3776 +#define LTQ_MPS_BASE                   0x1F107000
3777 +#define LTQ_CHIPID_BASE                        (LTQ_MPS_BASE + 0x340)
3778 +#define LTQ_RCU_BASE                   0x1F203000
3779 +
3780 +#define LTQ_MC_GLOBAL_BASE             0x1F400000
3781 +#define LTQ_MC_DDR_BASE                        0x1F401000
3782 +#define LTQ_MC_DDR_CCR_OFFSET(x)       (x * 0x10)
3783 +
3784 +#endif /* __VRX200_SOC_H__ */
3785 --- /dev/null
3786 +++ b/arch/mips/include/asm/arch-vrx200/switch.h
3787 @@ -0,0 +1,502 @@
3788 +/*
3789 + *   Copyright (C) 2012-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
3790 + *
3791 + *   SPDX-License-Identifier:  GPL-2.0+
3792 + */
3793 +
3794 +#ifndef __VRX200_SWITCH_H__
3795 +#define __VRX200_SWITCH_H__
3796 +
3797 +/* Switch core registers */
3798 +struct vr9_switch_core_regs {
3799 +       __be32 swres;
3800 +       /* TODO: implement registers */
3801 +       __be32 rsvd0[0x3f];
3802 +};
3803 +
3804 +/* Switch buffer management registers */
3805 +struct vr9_switch_bm_regs {
3806 +       struct bm_core {
3807 +               __be32 ram_val3;        /* RAM value 3 */
3808 +               __be32 ram_val2;        /* RAM value 2 */
3809 +               __be32 ram_val1;        /* RAM value 1 */
3810 +               __be32 ram_val0;        /* RAM value 0 */
3811 +               __be32 ram_addr;        /* RAM address */
3812 +               __be32 ram_ctrl;        /* RAM access control */
3813 +               __be32 fsqm_gctrl;      /* Free segment queue global control */
3814 +               __be32 cons_sel;        /* Number of consumed segments */
3815 +               __be32 cons_pkt;        /* Number of consumed packet pointers */
3816 +               __be32 gctrl;           /* Global control */
3817 +               __be32 queue_gctrl;     /* Queue manager global control */
3818 +               /* TODO: implement registers */
3819 +               __be32 rsvd0[0x35];
3820 +       } core;
3821 +
3822 +       struct bm_port {
3823 +               __be32 pcfg;            /* Port config */
3824 +               __be32 rmon_ctrl;       /* RMON control */
3825 +       } port[13];
3826 +
3827 +       __be32 rsvd0[0x66];
3828 +
3829 +       struct bm_queue {
3830 +               __be32 rsvd0;
3831 +               __be32 pqm_rs;          /* Packet queue manager rate shape assignment */
3832 +       } queue[32];
3833 +
3834 +       struct bm_shaper {
3835 +               __be32 ctrl;            /* Rate shaper control */
3836 +               __be32 cbs;             /* Rate shaper committed burst size */
3837 +               __be32 ibs;             /* Rate shaper instantaneous burst size */
3838 +               __be32 cir_ext;         /* Rate shaper rate exponent */
3839 +               __be32 cir_mant;        /* Rate shaper rate mantissa */
3840 +       } shaper[16];
3841 +
3842 +       __be32 rsvd1[0x2a8];
3843 +};
3844 +
3845 +/* Switch parser and classification engine registers */
3846 +struct vr9_switch_pce_regs {
3847 +       struct pce_core {
3848 +               __be32 tbl_key[16];     /* Table key data */
3849 +               __be32 tbl_mask;        /* Table mask */
3850 +               __be32 tbl_val[5];      /* Table value */
3851 +               __be32 tbl_addr;        /* Table entry address */
3852 +               __be32 tbl_ctrl;        /* Table access control */
3853 +               __be32 tbl_stat;        /* Table general status */
3854 +               __be32 age_0;           /* Aging counter config 0 */
3855 +               __be32 age_1;           /* Aging counter config 1 */
3856 +               __be32 pmap_1;          /* Port map (monitoring) */
3857 +               __be32 pmap_2;          /* Port map (multicast) */
3858 +               __be32 pmap_3;          /* Port map (unknown unicast) */
3859 +               __be32 gctrl_0;         /* Global control 0 */
3860 +               __be32 gctrl_1;         /* Global control 1 */
3861 +               __be32 tcm_gctrl;       /* Three-color marker global control */
3862 +               __be32 igmp_ctrl;       /* IGMP control */
3863 +               __be32 igmp_drpm;       /* IGMP default router port map */
3864 +               __be32 igmp_age_0;      /* IGMP aging 0 */
3865 +               __be32 igmp_age_1;      /* IGMP aging 1 */
3866 +               __be32 igmp_stat;       /* IGMP status */
3867 +               __be32 wol_gctrl;       /* Wake-on-LAN control */
3868 +               __be32 wol_da_0;        /* Wake-on-LAN destination address 0 */
3869 +               __be32 wol_da_1;        /* Wake-on-LAN destination address 1 */
3870 +               __be32 wol_da_2;        /* Wake-on-LAN destination address 2 */
3871 +               __be32 wol_pw_0;        /* Wake-on-LAN password 0 */
3872 +               __be32 wol_pw_1;        /* Wake-on-LAN password 1 */
3873 +               __be32 wol_pw_2;        /* Wake-on-LAN password 2 */
3874 +               __be32 ier_0;           /* PCE global interrupt enable 0 */
3875 +               __be32 ier_1;           /* PCE global interrupt enable 1 */
3876 +               __be32 isr_0;           /* PCE global interrupt status 0 */
3877 +               __be32 isr_1;           /* PCE global interrupt status 1 */
3878 +               __be32 parser_stat;     /* Parser status */
3879 +               __be32 rsvd0[0x6];
3880 +       } core;
3881 +
3882 +       __be32 rsvd0[0x10];
3883 +
3884 +       struct pce_port {
3885 +               __be32 pctrl_0;         /* Port control 0 */
3886 +               __be32 pctrl_1;         /* Port control 1 */
3887 +               __be32 pctrl_2;         /* Port control 2 */
3888 +               __be32 pctrl_3;         /* Port control 3 */
3889 +               __be32 wol_ctrl;        /* Wake-on-LAN control */
3890 +               __be32 vlan_ctrl;       /* VLAN control */
3891 +               __be32 def_pvid;        /* Default port VID */
3892 +               __be32 pstat;           /* Port status */
3893 +               __be32 pier;            /* Interrupt enable */
3894 +               __be32 pisr;            /* Interrupt status */
3895 +       } port[13];
3896 +
3897 +       __be32 rsvd1[0x7e];
3898 +
3899 +       struct pce_meter {
3900 +               /* TODO: implement registers */
3901 +               __be32 rsvd0[0x7];
3902 +       } meter[8];
3903 +
3904 +       __be32 rsvd2[0x308];
3905 +};
3906 +
3907 +static inline unsigned int to_pce_tbl_key_id(unsigned int id)
3908 +{
3909 +       BUG_ON(id > 15);
3910 +
3911 +       return 15 - id;
3912 +}
3913 +
3914 +static inline unsigned int to_pce_tbl_value_id(unsigned int id)
3915 +{
3916 +       BUG_ON(id > 4);
3917 +
3918 +       return 4 - id;
3919 +}
3920 +
3921 +/* Switch ethernet MAC registers */
3922 +struct vr9_switch_mac_regs {
3923 +       struct mac_core {
3924 +               __be32 test;            /* MAC test */
3925 +               __be32 pfad_cfg;        /* Pause frame source address config */
3926 +               __be32 pfsa_0;          /* Pause frame source address 0 */
3927 +               __be32 pfsa_1;          /* Pause frame source address 1 */
3928 +               __be32 pfsa_2;          /* Pause frame source address 2 */
3929 +               __be32 flen;            /* Frame length */
3930 +               __be32 vlan_etype_0;    /* VLAN ethertype 0 */
3931 +               __be32 vlan_etype_1;    /* VLAN ethertype 1 */
3932 +               __be32 ier;             /* Interrupt enable */
3933 +               __be32 isr;             /* Interrupt status */
3934 +               __be32 rsvd0[0x36];
3935 +       } core;
3936 +
3937 +       struct mac_port {
3938 +               __be32 pstat;           /* Port status */
3939 +               __be32 pisr;            /* Interrupt status */
3940 +               __be32 pier;            /* Interrupt enable */
3941 +               __be32 ctrl_0;          /* Control 0 */
3942 +               __be32 ctrl_1;          /* Control 1 */
3943 +               __be32 ctrl_2;          /* Control 2 */
3944 +               __be32 ctrl_3;          /* Control 3 */
3945 +               __be32 ctrl_4;          /* Control 4 */
3946 +               __be32 ctrl_5;          /* Control 5 */
3947 +               __be32 rsvd0[0x2];
3948 +               __be32 testen;          /* Test enable */
3949 +       } port[13];
3950 +
3951 +       __be32 rsvd0[0xa4];
3952 +};
3953 +
3954 +/* Switch Fetch DMA registers */
3955 +struct vr9_switch_fdma_regs {
3956 +       struct fdma_core {
3957 +               __be32 ctrl;            /* FDMA control */
3958 +               __be32 stetype;         /* Special tag ethertype control */
3959 +               __be32 vtetype;         /* VLAN tag ethertype control */
3960 +               __be32 stat;            /* FDMA status */
3961 +               __be32 ier;             /* FDMA interrupt enable */
3962 +               __be32 isr;             /* FDMA interrupt status */
3963 +       } core;
3964 +
3965 +       __be32 rsvd0[0x3a];
3966 +
3967 +       struct fdma_port {
3968 +               __be32 pctrl;           /* Port control */
3969 +               __be32 prio;            /* Port priority */
3970 +               __be32 pstat_0;         /* Port status 0 */
3971 +               __be32 pstat_1;         /* Port status 1 */
3972 +               __be32 tstamp_0;        /* Egress time stamp 0 */
3973 +               __be32 tstamp_1;        /* Egress time stamp 1 */
3974 +       } port[13];
3975 +
3976 +       __be32 rsvd1[0x72];
3977 +};
3978 +
3979 +/* Switch Store DMA registers */
3980 +struct vr9_switch_sdma_regs {
3981 +       struct sdma_core {
3982 +               __be32 ctrl;            /* SDMA Control */
3983 +               __be32 fcthr_1;         /* Flow control threshold 1 */
3984 +               __be32 rsvd0;
3985 +               __be32 fcthr_3;         /* Flow control threshold 3 */
3986 +               __be32 fcthr_4;         /* Flow control threshold 4 */
3987 +               __be32 fcthr_5;         /* Flow control threshold 5 */
3988 +               __be32 fcthr_6;         /* Flow control threshold 6 */
3989 +               __be32 fcthr_7;         /* Flow control threshold 7 */
3990 +               __be32 stat_0;          /* SDMA status 0 */
3991 +               __be32 stat_1;          /* SDMA status 1 */
3992 +               __be32 stat_2;          /* SDMA status 2 */
3993 +               __be32 ier;             /* SDMA interrupt enable */
3994 +               __be32 isr;             /* SDMA interrupt status */
3995 +       } core;
3996 +
3997 +       __be32 rsvd0[0x73];
3998 +
3999 +       struct sdma_port {
4000 +               __be32 pctrl;           /* Port control */
4001 +               __be32 prio;            /* Port priority */
4002 +               __be32 pstat_0;         /* Port status 0 */
4003 +               __be32 pstat_1;         /* Port status 1 */
4004 +               __be32 tstamp_0;        /* Ingress time stamp 0 */
4005 +               __be32 tstamp_1;        /* Ingress time stamp 1 */
4006 +       } port[13];
4007 +
4008 +       __be32 rsvd1[0x32];
4009 +};
4010 +
4011 +/* Switch MDIO control and status registers */
4012 +struct vr9_switch_mdio_regs {
4013 +       __be32 glob_ctrl;       /* Global control 0 */
4014 +       __be32 rsvd0[7];
4015 +       __be32 mdio_ctrl;       /* MDIO control */
4016 +       __be32 mdio_read;       /* MDIO read data */
4017 +       __be32 mdio_write;      /* MDIO write data */
4018 +       __be32 mdc_cfg_0;       /* MDC clock configuration 0 */
4019 +       __be32 mdc_cfg_1;       /* MDC clock configuration 1 */
4020 +       __be32 rsvd1[0x3];
4021 +       __be32 phy_addr[6];     /* PHY address port 5..0 */
4022 +       __be32 mdio_stat[6];    /* MDIO PHY polling status port 0..5 */
4023 +       __be32 aneg_eee[6];     /* EEE auto-neg overrides port 0..5 */
4024 +       __be32 rsvd2[0x14];
4025 +};
4026 +
4027 +static inline unsigned int to_mdio_phyaddr_id(unsigned int id)
4028 +{
4029 +       BUG_ON(id > 5);
4030 +
4031 +       return 5 - id;
4032 +}
4033 +
4034 +/* Switch xMII control registers */
4035 +struct vr9_switch_mii_regs {
4036 +       __be32 mii_cfg0;        /* xMII port 0 configuration */
4037 +       __be32 pcdu0;           /* Port 0 clock delay configuration */
4038 +       __be32 mii_cfg1;        /* xMII port 1 configuration */
4039 +       __be32 pcdu1;           /* Port 1 clock delay configuration */
4040 +       __be32 rsvd0[0x6];
4041 +       __be32 mii_cfg5;        /* xMII port 5 configuration */
4042 +       __be32 pcdu5;           /* Port 5 clock delay configuration */
4043 +       __be32 rsvd1[0x14];
4044 +       __be32 rxb_ctl_0;       /* Port 0 receive buffer control */
4045 +       __be32 rxb_ctl_1;       /* Port 1 receive buffer control */
4046 +       __be32 rxb_ctl_5;       /* Port 5 receive buffer control */
4047 +       __be32 rsvd2[0x28];
4048 +       __be32 dbg_ctl;         /* Debug control */
4049 +};
4050 +
4051 +/* Switch Pseudo-MAC registers */
4052 +struct vr9_switch_pmac_regs {
4053 +       __be32 hd_ctl;          /* PMAC header control */
4054 +       __be32 tl;              /* PMAC type/length */
4055 +       __be32 sa1;             /* PMAC source address 1 */
4056 +       __be32 sa2;             /* PMAC source address 2 */
4057 +       __be32 sa3;             /* PMAC source address 3 */
4058 +       __be32 da1;             /* PMAC destination address 1 */
4059 +       __be32 da2;             /* PMAC destination address 2 */
4060 +       __be32 da3;             /* PMAC destination address 3 */
4061 +       __be32 vlan;            /* PMAC VLAN */
4062 +       __be32 rx_ipg;          /* PMAC interpacket gap in RX direction */
4063 +       __be32 st_etype;        /* PMAC special tag ethertype */
4064 +       __be32 ewan;            /* PMAC ethernet WAN group */
4065 +       __be32 ctl;             /* PMAC control */
4066 +       __be32 rsvd0[0x2];
4067 +};
4068 +
4069 +struct vr9_switch_regs {
4070 +       struct vr9_switch_core_regs core;
4071 +       struct vr9_switch_bm_regs bm;
4072 +       struct vr9_switch_pce_regs pce;
4073 +       struct vr9_switch_mac_regs mac;
4074 +       struct vr9_switch_fdma_regs fdma;
4075 +       struct vr9_switch_sdma_regs sdma;
4076 +       struct vr9_switch_mdio_regs mdio;
4077 +       struct vr9_switch_mii_regs mii;
4078 +       struct vr9_switch_pmac_regs pmac;
4079 +};
4080 +
4081 +static inline void *to_pce_tbl_key(struct vr9_switch_regs *regs,
4082 +                                               unsigned int id)
4083 +{
4084 +       return &regs->pce.core.tbl_key[to_pce_tbl_key_id(id)];
4085 +}
4086 +
4087 +static inline void *to_pce_tbl_value(struct vr9_switch_regs *regs,
4088 +                                               unsigned int id)
4089 +{
4090 +       return &regs->pce.core.tbl_val[to_pce_tbl_value_id(id)];
4091 +}
4092 +
4093 +static inline void *to_mac_ctrl(struct vr9_switch_regs *regs,
4094 +                                       unsigned int id, unsigned int ctrl)
4095 +{
4096 +       struct mac_port *mac = &regs->mac.port[id];
4097 +
4098 +       switch (ctrl) {
4099 +       case 0:
4100 +               return &mac->ctrl_0;
4101 +       case 1:
4102 +               return &mac->ctrl_1;
4103 +       case 2:
4104 +               return &mac->ctrl_2;
4105 +       case 3:
4106 +               return &mac->ctrl_3;
4107 +       case 4:
4108 +               return &mac->ctrl_4;
4109 +       case 5:
4110 +               return &mac->ctrl_5;
4111 +       default:
4112 +               return NULL;
4113 +       }
4114 +}
4115 +
4116 +static inline void *to_mdio_phyaddr(struct vr9_switch_regs *regs,
4117 +                                       unsigned int id)
4118 +{
4119 +       return &regs->mdio.phy_addr[to_mdio_phyaddr_id(id)];
4120 +}
4121 +
4122 +static inline void *to_mii_miicfg(struct vr9_switch_regs *regs,
4123 +                                       unsigned int id)
4124 +{
4125 +       switch (id) {
4126 +       case 0:
4127 +               return &regs->mii.mii_cfg0;
4128 +       case 1:
4129 +               return &regs->mii.mii_cfg1;
4130 +       case 5:
4131 +               return &regs->mii.mii_cfg5;
4132 +       default:
4133 +               return NULL;
4134 +       }
4135 +}
4136 +
4137 +static inline void *to_mii_pcdu(struct vr9_switch_regs *regs,
4138 +                                       unsigned int id)
4139 +{
4140 +       switch (id) {
4141 +       case 0:
4142 +               return &regs->mii.pcdu0;
4143 +       case 1:
4144 +               return &regs->mii.pcdu1;
4145 +       case 5:
4146 +               return &regs->mii.pcdu5;
4147 +       default:
4148 +               return NULL;
4149 +       }
4150 +}
4151 +
4152 +#define VR9_SWITCH_REG_OFFSET(reg)     (4 * (reg))
4153 +
4154 +#define BUILD_CHECK_VR9_REG(name, offset)      \
4155 +       BUILD_BUG_ON(offsetof(struct vr9_switch_regs, name) != (4 * offset))
4156 +
4157 +static inline void build_check_vr9_registers(void)
4158 +{
4159 +       BUILD_CHECK_VR9_REG(core, 0x0);
4160 +       BUILD_CHECK_VR9_REG(bm.core, 0x40);
4161 +       BUILD_CHECK_VR9_REG(bm.core.queue_gctrl, 0x4a);
4162 +       BUILD_CHECK_VR9_REG(bm.port[0], 0x80);
4163 +       BUILD_CHECK_VR9_REG(bm.queue, 0x100);
4164 +       BUILD_CHECK_VR9_REG(bm.shaper, 0x140);
4165 +       BUILD_CHECK_VR9_REG(pce.core, 0x438);
4166 +       BUILD_CHECK_VR9_REG(pce.core.tbl_ctrl, 0x44f);
4167 +       BUILD_CHECK_VR9_REG(pce.core.parser_stat, 0x469);
4168 +       BUILD_CHECK_VR9_REG(pce.port[0], 0x480);
4169 +       BUILD_CHECK_VR9_REG(pce.meter[0], 0x580);
4170 +       BUILD_CHECK_VR9_REG(mac.core, 0x8c0);
4171 +       BUILD_CHECK_VR9_REG(mac.port[0].pstat, 0x900);
4172 +       BUILD_CHECK_VR9_REG(mac.port[0].ctrl_0, 0x903);
4173 +       BUILD_CHECK_VR9_REG(mac.port[1].pstat, 0x90c);
4174 +       BUILD_CHECK_VR9_REG(mac.port[1].ctrl_0, 0x90f);
4175 +       BUILD_CHECK_VR9_REG(mac.port[2].pstat, 0x918);
4176 +       BUILD_CHECK_VR9_REG(mac.port[2].ctrl_0, 0x91b);
4177 +       BUILD_CHECK_VR9_REG(fdma.core, 0xa40);
4178 +       BUILD_CHECK_VR9_REG(fdma.port[0], 0xa80);
4179 +       BUILD_CHECK_VR9_REG(sdma.core, 0xb40);
4180 +       BUILD_CHECK_VR9_REG(sdma.port[0], 0xbc0);
4181 +       BUILD_CHECK_VR9_REG(mdio, 0xc40);
4182 +       BUILD_CHECK_VR9_REG(mii, (0xc40 + 0x36));
4183 +       BUILD_CHECK_VR9_REG(pmac, (0xc40 + 0x82));
4184 +}
4185 +
4186 +#define BM_GCTRL_F_SRES                1
4187 +
4188 +#define MAC_CTRL0_BM           (1 << 12)
4189 +#define MAC_CTRL0_APADEN       (1 << 11)
4190 +#define MAC_CTRL0_VPAD2EN      (1 << 10)
4191 +#define MAC_CTRL0_VPADEN       (1 << 9)
4192 +#define MAC_CTRL0_PADEN                (1 << 8)
4193 +#define MAC_CTRL0_FCS          (1 << 7)
4194 +#define MAC_CTRL0_FCON_SHIFT   4
4195 +#define MAC_CTRL0_FCON_AUTO    (0x0 << MAC_CTRL0_FCON_SHIFT)
4196 +#define MAC_CTRL0_FCON_RX      (0x1 << MAC_CTRL0_FCON_SHIFT)
4197 +#define MAC_CTRL0_FCON_TX      (0x2 << MAC_CTRL0_FCON_SHIFT)
4198 +#define MAC_CTRL0_FCON_RXTX    (0x3 << MAC_CTRL0_FCON_SHIFT)
4199 +#define MAC_CTRL0_FCON_NONE    (0x4 << MAC_CTRL0_FCON_SHIFT)
4200 +#define MAC_CTRL0_FDUP_SHIFT   2
4201 +#define MAC_CTRL0_FDUP_AUTO    (0x0 << MAC_CTRL0_FDUP_SHIFT)
4202 +#define MAC_CTRL0_FDUP_EN      (0x1 << MAC_CTRL0_FDUP_SHIFT)
4203 +#define MAC_CTRL0_FDUP_DIS     (0x3 << MAC_CTRL0_FDUP_SHIFT)
4204 +#define MAC_CTRL0_GMII_AUTO    0x0
4205 +#define MAC_CTRL0_GMII_MII     0x1
4206 +#define MAC_CTRL0_GMII_GMII    0x2
4207 +#define MAC_CTRL0_GMII_GMII_2G 0x3
4208 +
4209 +#define MAC_CTRL1_DEFERMODE    (1 << 15)
4210 +#define MAC_CTRL1_SHORTPRE     (1 << 8)
4211 +
4212 +#define MAC_CTRL2_MLEN         (1 << 3)
4213 +#define MAC_CTRL2_LCHKL                (1 << 2)
4214 +#define MAC_CTRL2_LCHKS_DIS    0x0
4215 +#define MAC_CTRL2_LCHKS_UNTAG  0x1
4216 +#define MAC_CTRL2_LCHKS_TAG    0x2
4217 +
4218 +#define PHY_ADDR_LNKST_SHIFT   13
4219 +#define PHY_ADDR_LNKST_AUTO    (0x0 << PHY_ADDR_LNKST_SHIFT)
4220 +#define PHY_ADDR_LNKST_UP      (0x1 << PHY_ADDR_LNKST_SHIFT)
4221 +#define PHY_ADDR_LNKST_DOWN    (0x2 << PHY_ADDR_LNKST_SHIFT)
4222 +#define PHY_ADDR_SPEED_SHIFT   11
4223 +#define PHY_ADDR_SPEED_M10     (0x0 << PHY_ADDR_SPEED_SHIFT)
4224 +#define PHY_ADDR_SPEED_M100    (0x1 << PHY_ADDR_SPEED_SHIFT)
4225 +#define PHY_ADDR_SPEED_G1      (0x2 << PHY_ADDR_SPEED_SHIFT)
4226 +#define PHY_ADDR_SPEED_AUTO    (0x3 << PHY_ADDR_SPEED_SHIFT)
4227 +#define PHY_ADDR_FDUP_SHIFT    9
4228 +#define PHY_ADDR_FDUP_AUTO     (0x0 << PHY_ADDR_FDUP_SHIFT)
4229 +#define PHY_ADDR_FDUP_EN       (0x1 << PHY_ADDR_FDUP_SHIFT)
4230 +#define PHY_ADDR_FDUP_DIS      (0x3 << PHY_ADDR_FDUP_SHIFT)
4231 +#define PHY_ADDR_FCONTX_SHIFT  7
4232 +#define PHY_ADDR_FCONTX_AUTO   (0x0 << PHY_ADDR_FCONTX_SHIFT)
4233 +#define PHY_ADDR_FCONTX_EN     (0x1 << PHY_ADDR_FCONTX_SHIFT)
4234 +#define PHY_ADDR_FCONTX_DIS    (0x3 << PHY_ADDR_FCONTX_SHIFT)
4235 +#define PHY_ADDR_FCONRX_SHIFT  5
4236 +#define PHY_ADDR_FCONRX_AUTO   (0x0 << PHY_ADDR_FCONRX_SHIFT)
4237 +#define PHY_ADDR_FCONRX_EN     (0x1 << PHY_ADDR_FCONRX_SHIFT)
4238 +#define PHY_ADDR_FCONRX_DIS    (0x3 << PHY_ADDR_FCONRX_SHIFT)
4239 +
4240 +#define MII_CFG_RES            (1 << 15)
4241 +#define MII_CFG_EN             (1 << 14)
4242 +#define MII_CFG_LDCLKDIS       (1 << 12)
4243 +#define MII_CFG_MIIRATE_SHIFT  4
4244 +#define MII_CFG_MIIRATE_MASK   (0x7 << MII_CFG_MIIRATE_SHIFT)
4245 +#define MII_CFG_MIIRATE_M2P5   (0x0 << MII_CFG_MIIRATE_SHIFT)
4246 +#define MII_CFG_MIIRATE_M25    (0x1 << MII_CFG_MIIRATE_SHIFT)
4247 +#define MII_CFG_MIIRATE_M125   (0x2 << MII_CFG_MIIRATE_SHIFT)
4248 +#define MII_CFG_MIIRATE_M50    (0x3 << MII_CFG_MIIRATE_SHIFT)
4249 +#define MII_CFG_MIIRATE_AUTO   (0x4 << MII_CFG_MIIRATE_SHIFT)
4250 +#define MII_CFG_MIIMODE_MASK   0xf
4251 +#define MII_CFG_MIIMODE_MIIP   0x0
4252 +#define MII_CFG_MIIMODE_MIIM   0x1
4253 +#define MII_CFG_MIIMODE_RMIIP  0x2
4254 +#define MII_CFG_MIIMODE_RMIIM  0x3
4255 +#define MII_CFG_MIIMODE_RGMII  0x4
4256 +
4257 +#define PCDU_RXDLY_SHIFT       7
4258 +#define PCDU_RXDLY_MASK                (0x7 << PCDU_RXDLY_SHIFT)
4259 +#define PCDU_TXDLY_MASK                0x7
4260 +
4261 +#define PMAC_HD_CTL_FC         (1 << 10)
4262 +#define PMAC_HD_CTL_CCRC       (1 << 9)
4263 +#define PMAC_HD_CTL_RST                (1 << 8)
4264 +#define PMAC_HD_CTL_AST                (1 << 7)
4265 +#define PMAC_HD_CTL_RXSH       (1 << 6)
4266 +#define PMAC_HD_CTL_RC         (1 << 4)
4267 +#define PMAC_HD_CTL_AS         (1 << 3)
4268 +#define PMAC_HD_CTL_AC         (1 << 2)
4269 +
4270 +#define PCE_PCTRL_0_IGSTEN     (1 << 11)
4271 +
4272 +#define FDMA_PCTRL_STEN                (1 << 1)
4273 +#define FDMA_PCTRL_EN          (1 << 0)
4274 +
4275 +#define SDMA_PCTRL_EN          (1 << 0)
4276 +
4277 +#define MDIO_GLOB_CTRL_SE      (1 << 15)
4278 +
4279 +#define MDIO_MDC_CFG1_RES      (1 << 15)
4280 +#define MDIO_MDC_CFG1_MCEN     (1 << 8)
4281 +
4282 +#define MDIO_CTRL_MBUSY                (1 << 12)
4283 +#define MDIO_CTRL_OP_READ      (1 << 11)
4284 +#define MDIO_CTRL_OP_WRITE     (1 << 10)
4285 +#define MDIO_CTRL_PHYAD_SHIFT  5
4286 +#define MDIO_CTRL_PHYAD_MASK   (0x1f << MDIO_CTRL_PHYAD_SHIFT)
4287 +#define MDIO_CTRL_REGAD_MASK   0x1f
4288 +
4289 +#endif /* __VRX200_SWITCH_H__ */
4290 --- a/arch/mips/include/asm/asm.h
4291 +++ b/arch/mips/include/asm/asm.h
4292 @@ -53,6 +53,7 @@
4293                 .align  2;                              \
4294                 .type   symbol, @function;              \
4295                 .ent    symbol, 0;                      \
4296 +               .section .text.symbol,"x";              \
4297  symbol:                .frame  sp, 0, ra
4298  
4299  /*
4300 @@ -62,7 +63,8 @@ symbol:               .frame  sp, 0, ra
4301                 .globl  symbol;                         \
4302                 .align  2;                              \
4303                 .type   symbol, @function;              \
4304 -               .ent    symbol, 0;                       \
4305 +               .ent    symbol, 0;                      \
4306 +               .section .text.symbol,"x";              \
4307  symbol:                .frame  sp, framesize, rpc
4308  
4309  /*
4310 --- /dev/null
4311 +++ b/arch/mips/include/asm/gpio.h
4312 @@ -0,0 +1,6 @@
4313 +/*
4314 + * SPDX-License-Identifier:    GPL-2.0+
4315 + */
4316 +
4317 +#include <asm/arch/gpio.h>
4318 +#include <asm-generic/gpio.h>
4319 --- /dev/null
4320 +++ b/arch/mips/include/asm/lantiq/chipid.h
4321 @@ -0,0 +1,73 @@
4322 +/*
4323 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
4324 + *
4325 + * SPDX-License-Identifier:    GPL-2.0+
4326 + */
4327 +
4328 +#ifndef __LANTIQ_CHIPID_H__
4329 +#define __LANTIQ_CHIPID_H__
4330 +
4331 +enum ltq_chip_partnum {
4332 +       LTQ_SOC_UNKNOWN = 0,
4333 +       LTQ_SOC_VRX288_2 = 0x000B,      /* VRX288 v1.2 */
4334 +       LTQ_SOC_VRX268_2 = 0x000C,      /* VRX268 v1.2 */
4335 +       LTQ_SOC_GRX288_2 = 0x000D,      /* GRX288 v1.2 */
4336 +       LTQ_SOC_DANUBE = 0x0129,
4337 +       LTQ_SOC_DANUBE_S = 0x012B,
4338 +       LTQ_SOC_TWINPASS = 0x012D,
4339 +       LTQ_SOC_VRX288 = 0x01C0,        /* VRX288 v1.1 */
4340 +       LTQ_SOC_VRX268 = 0x01C2,        /* VRX268 v1.1 */
4341 +       LTQ_SOC_GRX288 = 0x01C9,        /* GRX288 v1.1 */
4342 +};
4343 +
4344 +extern unsigned int ltq_chip_version_get(void);
4345 +extern unsigned int ltq_chip_partnum_get(void);
4346 +extern const char *ltq_chip_partnum_str(void);
4347 +
4348 +extern void ltq_chip_print_info(void);
4349 +
4350 +#ifdef CONFIG_SOC_XWAY_DANUBE
4351 +static inline int ltq_soc_is_danube(void)
4352 +{
4353 +       return 1;
4354 +}
4355 +#else
4356 +static inline int ltq_soc_is_danube(void)
4357 +{
4358 +       return 0;
4359 +}
4360 +#endif
4361 +
4362 +#ifdef CONFIG_SOC_XWAY_VRX200
4363 +static inline int ltq_soc_is_vrx200(void)
4364 +{
4365 +       return 1;
4366 +}
4367 +
4368 +static inline int ltq_soc_is_vrx200_v1(void)
4369 +{
4370 +       return ltq_chip_version_get() == 1;
4371 +}
4372 +
4373 +static inline int ltq_soc_is_vrx200_v2(void)
4374 +{
4375 +       return ltq_chip_version_get() == 2;
4376 +}
4377 +#else
4378 +static inline int ltq_soc_is_vrx200(void)
4379 +{
4380 +       return 0;
4381 +}
4382 +
4383 +static inline int ltq_soc_is_vrx200_v1(void)
4384 +{
4385 +       return 0;
4386 +}
4387 +
4388 +static inline int ltq_soc_is_vrx200_v2(void)
4389 +{
4390 +       return 0;
4391 +}
4392 +#endif
4393 +
4394 +#endif /* __LANTIQ_CHIPID_H__ */
4395 --- /dev/null
4396 +++ b/arch/mips/include/asm/lantiq/clk.h
4397 @@ -0,0 +1,30 @@
4398 +/*
4399 + * Copyright (C) 2007-2010 Lantiq Deutschland GmbH
4400 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
4401 + * *
4402 + * SPDX-License-Identifier:    GPL-2.0+
4403 + */
4404 +
4405 +#ifndef __LANTIQ_CLK_H__
4406 +#define __LANTIQ_CLK_H__
4407 +
4408 +/* Symbolic clock speeds */
4409 +enum ltq_clk {
4410 +       CLOCK_83_MHZ = 83333333,
4411 +       CLOCK_111_MHZ = 111111111,
4412 +       CLOCK_125_MHZ = 125000000,
4413 +       CLOCK_133_MHZ = 133333333,
4414 +       CLOCK_166_MHZ = 166666667,
4415 +       CLOCK_197_MHZ = 197000000,
4416 +       CLOCK_333_MHZ = 333333333,
4417 +       CLOCK_393_MHZ = 393219000,
4418 +       CLOCK_500_MHZ = 500000000,
4419 +       CLOCK_600_MHZ = 600000000,
4420 +       CLOCK_1000_MHZ = 1000000000,
4421 +};
4422 +
4423 +extern unsigned long ltq_get_cpu_clock(void);
4424 +extern unsigned long ltq_get_bus_clock(void);
4425 +extern unsigned long ltq_get_io_region_clock(void);
4426 +
4427 +#endif /* __LANTIQ_CLK_H__ */
4428 --- /dev/null
4429 +++ b/arch/mips/include/asm/lantiq/config.h
4430 @@ -0,0 +1,164 @@
4431 +/*
4432 + * Copyright (C) 2007-2010 Lantiq Deutschland GmbH
4433 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
4434 + *
4435 + * SPDX-License-Identifier:    GPL-2.0+
4436 + */
4437 +
4438 +#ifndef __LANTIQ_CONFIG_H__
4439 +#define __LANTIQ_CONFIG_H__
4440 +
4441 +/* Memory usage */
4442 +#define CONFIG_SYS_MAXARGS             24
4443 +#define CONFIG_SYS_MALLOC_LEN          1024*1024
4444 +#define CONFIG_SYS_BOOTPARAMS_LEN      128*1024
4445 +
4446 +/* Command line */
4447 +#define CONFIG_SYS_PROMPT              CONFIG_MACH_TYPE " # "
4448 +#define CONFIG_SYS_CBSIZE              512
4449 +#define CONFIG_SYS_PBSIZE              (CONFIG_SYS_CBSIZE + \
4450 +                                       sizeof(CONFIG_SYS_PROMPT)+16)
4451 +
4452 +#define CONFIG_SYS_HUSH_PARSER
4453 +#define CONFIG_SYS_PROMPT_HUSH_PS2     "> "
4454 +
4455 +/*
4456 + * Enable advanced console features on demand to reduce
4457 + * flash and RAM footprint
4458 + */
4459 +#if defined(CONFIG_LTQ_ADVANCED_CONSOLE)
4460 +#define CONFIG_SYS_LONGHELP
4461 +#define CONFIG_AUTO_COMPLETE
4462 +#define CONFIG_CMDLINE_EDITING
4463 +#endif
4464 +
4465 +/* SPI flash SPL */
4466 +#if defined(CONFIG_LTQ_SUPPORT_SPL_SPI_FLASH) && defined(CONFIG_SYS_BOOT_SFSPL)
4467 +#define CONFIG_SPL
4468 +#define CONFIG_SPL_SPI_SUPPORT
4469 +#define CONFIG_SPL_SPI_FLASH_SUPPORT
4470 +#define CONFIG_SPI_SPL_SIMPLE
4471 +#endif
4472 +
4473 +#if defined(CONFIG_LTQ_SUPPORT_SPL_NOR_FLASH) && defined(CONFIG_SYS_BOOT_NORSPL)
4474 +#define CONFIG_SPL
4475 +#endif
4476 +
4477 +/* Common SPL */
4478 +#if defined(CONFIG_SPL)
4479 +#define CONFIG_SKIP_LOWLEVEL_INIT
4480 +#define CONFIG_SPL_LIBGENERIC_SUPPORT
4481 +#define CONFIG_SPL_GPIO_SUPPORT
4482 +#define CONFIG_SPL_START_S_PATH                \
4483 +               "arch/mips/cpu/mips32/lantiq-common"
4484 +#define CONFIG_SPL_LDSCRIPT            \
4485 +               "arch/mips/cpu/mips32/lantiq-common/u-boot-spl.lds"
4486 +#endif
4487 +
4488 +#if defined(CONFIG_LTQ_SPL_CONSOLE)
4489 +#define CONFIG_SPL_SERIAL_SUPPORT
4490 +#define CONFIG_SPL_LIBCOMMON_SUPPORT
4491 +#endif
4492 +
4493 +#if defined(CONFIG_LTQ_SPL_COMP_LZMA)
4494 +#define CONFIG_LZMA
4495 +#define CONFIG_SPL_LZMA_SUPPORT
4496 +#endif
4497 +
4498 +#if defined(CONFIG_LTQ_SPL_COMP_LZO)
4499 +#define CONFIG_LZO
4500 +#define CONFIG_SPL_LZO_SUPPORT
4501 +#endif
4502 +
4503 +/* Basic commands */
4504 +#define CONFIG_CMD_BDI
4505 +#define CONFIG_CMD_EDITENV
4506 +#define CONFIG_CMD_IMI
4507 +#define CONFIG_CMD_MEMORY
4508 +#define CONFIG_CMD_RUN
4509 +#define CONFIG_CMD_SAVEENV
4510 +#define CONFIG_CMD_LOADB
4511 +
4512 +/* Other U-Boot settings */
4513 +#define CONFIG_TIMESTAMP
4514 +
4515 +/* Default environment */
4516 +#define CONFIG_ENV_CONSOLEDEV                                  \
4517 +       "consoledev=" CONFIG_CONSOLE_DEV "\0"
4518 +
4519 +#define CONFIG_ENV_ADDCONSOLE                                  \
4520 +       "addconsole=setenv bootargs $bootargs"                  \
4521 +       " console=$consoledev,$baudrate\0"
4522 +
4523 +#if defined(CONFIG_NET_DEV)
4524 +#define CONFIG_ENV_NETDEV                                      \
4525 +       "netdev=" CONFIG_NET_DEV "\0"
4526 +#else
4527 +#define CONFIG_ENV_NETDEV                                      \
4528 +       "netdev=eth0\0"
4529 +#endif
4530 +
4531 +#define CONFIG_ENV_ADDIP                                       \
4532 +       "addip=setenv bootargs $bootargs"                       \
4533 +       " ip=$ipaddr:$serverip::::$netdev:off\0"
4534 +
4535 +#define CONFIG_ENV_ADDETH                                      \
4536 +       "addeth=setenv bootargs $bootargs"                      \
4537 +       " ethaddr=$ethaddr\0"
4538 +
4539 +#define CONFIG_ENV_ADDMACHTYPE                                 \
4540 +       "addmachtype=setenv bootargs $bootargs"                 \
4541 +       " machtype=" CONFIG_MACH_TYPE "\0"
4542 +
4543 +#if defined(CONFIG_LTQ_SUPPORT_NOR_FLASH)
4544 +#define CONFIG_ENV_WRITE_UBOOT_NOR                                     \
4545 +       "write-uboot-nor="                                              \
4546 +       "protect off " __stringify(CONFIG_SYS_FLASH_BASE) " +$filesize && " \
4547 +       "erase " __stringify(CONFIG_SYS_FLASH_BASE) " +$filesize && "   \
4548 +       "cp.b $fileaddr " __stringify(CONFIG_SYS_FLASH_BASE) " $filesize\0"
4549 +
4550 +#define CONFIG_ENV_LOAD_UBOOT_NOR                                      \
4551 +       "load-uboot-nor=tftpboot u-boot.bin\0"                          \
4552 +       "load-uboot-norspl=tftpboot u-boot.ltq.norspl\0"                \
4553 +       "load-uboot-norspl-lzo=tftpboot u-boot.ltq.lzo.norspl\0"        \
4554 +       "load-uboot-norspl-lzma=tftpboot u-boot.ltq.lzma.norspl\0"
4555 +#else
4556 +#define CONFIG_ENV_WRITE_UBOOT_NOR
4557 +#define CONFIG_ENV_LOAD_UBOOT_NOR
4558 +#endif
4559 +
4560 +#if defined(CONFIG_LTQ_SUPPORT_SPI_FLASH)
4561 +#define CONFIG_ENV_SF_PROBE                                    \
4562 +       "sf-probe=sf probe " __stringify(CONFIG_ENV_SPI_CS) " " \
4563 +       __stringify(CONFIG_ENV_SPI_MAX_HZ) " "                  \
4564 +       __stringify(CONFIG_ENV_SPI_MODE) " \0"
4565 +
4566 +#define CONFIG_ENV_WRITE_UBOOT_SF                              \
4567 +       "write-uboot-sf="                                       \
4568 +       "run sf-probe && sf erase 0 +$filesize && "             \
4569 +       "sf write $fileaddr 0 $filesize\0"
4570 +
4571 +#define CONFIG_ENV_LOAD_UBOOT_SF                                       \
4572 +       "load-uboot-sfspl=tftpboot u-boot.ltq.sfspl\0"                  \
4573 +       "load-uboot-sfspl-lzo=tftpboot u-boot.ltq.lzo.sfspl\0"          \
4574 +       "load-uboot-sfspl-lzma=tftpboot u-boot.ltq.lzma.sfspl\0"
4575 +#else
4576 +#define CONFIG_ENV_SF_PROBE
4577 +#define CONFIG_ENV_WRITE_UBOOT_SF
4578 +#define CONFIG_ENV_LOAD_UBOOT_SF
4579 +#endif
4580 +
4581 +#define CONFIG_ENV_LANTIQ_DEFAULTS     \
4582 +       CONFIG_ENV_CONSOLEDEV           \
4583 +       CONFIG_ENV_ADDCONSOLE           \
4584 +       CONFIG_ENV_NETDEV               \
4585 +       CONFIG_ENV_ADDIP                \
4586 +       CONFIG_ENV_ADDETH               \
4587 +       CONFIG_ENV_ADDMACHTYPE          \
4588 +       CONFIG_ENV_WRITE_UBOOT_NOR      \
4589 +       CONFIG_ENV_LOAD_UBOOT_NOR       \
4590 +       CONFIG_ENV_SF_PROBE             \
4591 +       CONFIG_ENV_WRITE_UBOOT_SF       \
4592 +       CONFIG_ENV_LOAD_UBOOT_SF
4593 +
4594 +#endif /* __LANTIQ_CONFIG_H__ */
4595 --- /dev/null
4596 +++ b/arch/mips/include/asm/lantiq/cpu.h
4597 @@ -0,0 +1,34 @@
4598 +/*
4599 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
4600 + *
4601 + * SPDX-License-Identifier:    GPL-2.0+
4602 + */
4603 +
4604 +#ifndef __LANTIQ_CPU_H__
4605 +#define __LANTIQ_CPU_H__
4606 +
4607 +enum ltq_boot_select {
4608 +       BOOT_NOR,
4609 +       BOOT_NOR_NO_BOOTROM,
4610 +       BOOT_UART,
4611 +       BOOT_UART_NO_EEPROM,
4612 +       BOOT_SPI,
4613 +       BOOT_NAND,
4614 +       BOOT_PCI,
4615 +       BOOT_MII0,
4616 +       BOOT_RMII0,
4617 +       BOOT_RGMII1,
4618 +       BOOT_UNKNOWN,
4619 +};
4620 +
4621 +enum ltq_boot_select ltq_boot_select(void);
4622 +const char *ltq_boot_select_str(void);
4623 +
4624 +void ltq_pmu_init(void);
4625 +void ltq_ebu_init(void);
4626 +void ltq_gpio_init(void);
4627 +
4628 +void ltq_pll_init(void);
4629 +void ltq_dcdc_init(unsigned int dig_ref);
4630 +
4631 +#endif /* __LANTIQ_CPU_H__ */
4632 --- /dev/null
4633 +++ b/arch/mips/include/asm/lantiq/dma.h
4634 @@ -0,0 +1,94 @@
4635 +/*
4636 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
4637 + *
4638 + * SPDX-License-Identifier:    GPL-2.0+
4639 + */
4640 +
4641 +#ifndef __LANTIQ_DMA_H__
4642 +#define __LANTIQ_DMA_H__
4643 +
4644 +enum ltq_dma_endianess {
4645 +       LTQ_DMA_ENDIANESS_B0_B1_B2_B3,  /* No byte swapping */
4646 +       LTQ_DMA_ENDIANESS_B1_B0_B3_B2,  /* B0B1B2B3 => B1B0B3B2 */
4647 +       LTQ_DMA_ENDIANESS_B2_B3_B0_B1,  /* B0B1B2B3 => B2B3B0B1 */
4648 +       LTQ_DMA_ENDIANESS_B3_B2_B1_B0,  /* B0B1B2B3 => B3B2B1B0 */
4649 +};
4650 +
4651 +enum ltq_dma_burst_len {
4652 +       LTQ_DMA_BURST_2WORDS = 1,
4653 +       LTQ_DMA_BURST_4WORDS = 2,
4654 +       LTQ_DMA_BURST_8WORDS = 3,
4655 +};
4656 +
4657 +struct ltq_dma_desc {
4658 +       u32 ctl;
4659 +       u32 addr;
4660 +};
4661 +
4662 +struct ltq_dma_channel {
4663 +       struct ltq_dma_device *dev;
4664 +       u8 chan_no;
4665 +       u8 class;
4666 +       u16 num_desc;
4667 +       struct ltq_dma_desc *desc_base;
4668 +       void *mem_base;
4669 +       u32 dma_addr;
4670 +};
4671 +
4672 +struct ltq_dma_device {
4673 +       enum ltq_dma_endianess rx_endian_swap;
4674 +       enum ltq_dma_endianess tx_endian_swap;
4675 +       enum ltq_dma_burst_len rx_burst_len;
4676 +       enum ltq_dma_burst_len tx_burst_len;
4677 +       struct ltq_dma_channel rx_chan;
4678 +       struct ltq_dma_channel tx_chan;
4679 +       u8 port;
4680 +};
4681 +
4682 +/**
4683 + * Initialize DMA hardware and driver
4684 + */
4685 +void ltq_dma_init(void);
4686 +
4687 +/**
4688 + * Register given DMA client context
4689 + *
4690 + * @returns 0 on success, negative value otherwise
4691 + */
4692 +int ltq_dma_register(struct ltq_dma_device *dev);
4693 +
4694 +/**
4695 + * Reset and halt all channels related to given DMA client
4696 + */
4697 +void ltq_dma_reset(struct ltq_dma_device *dev);
4698 +void ltq_dma_enable(struct ltq_dma_device *dev);
4699 +void ltq_dma_disable(struct ltq_dma_device *dev);
4700 +
4701 +/**
4702 + * Map RX DMA descriptor to memory region
4703 + *
4704 + * @returns 0 on success, negative value otherwise
4705 + */
4706 +int ltq_dma_rx_map(struct ltq_dma_device *dev, int index, void *data, int len);
4707 +
4708 +/**
4709 + * Check if new data is available.
4710 + *
4711 + * @returns length of received data, 0 otherwise
4712 + */
4713 +int ltq_dma_rx_poll(struct ltq_dma_device *dev, int index);
4714 +
4715 +int ltq_dma_rx_length(struct ltq_dma_device *dev, int index);
4716 +
4717 +/**
4718 + * Map TX DMA descriptor to memory region
4719 + *
4720 + * @returns 0 on success, negative value otherwise
4721 + */
4722 +int ltq_dma_tx_map(struct ltq_dma_device *dev, int index, void *data, int len,
4723 +                       unsigned long timeout);
4724 +
4725 +int ltq_dma_tx_wait(struct ltq_dma_device *dev, int index,
4726 +                       unsigned long timeout);
4727 +
4728 +#endif /* __LANTIQ_DMA_H__ */
4729 --- /dev/null
4730 +++ b/arch/mips/include/asm/lantiq/eth.h
4731 @@ -0,0 +1,35 @@
4732 +/*
4733 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
4734 + *
4735 + * SPDX-License-Identifier:    GPL-2.0+
4736 + */
4737 +
4738 +#ifndef __LANTIQ_ETH_H__
4739 +#define __LANTIQ_ETH_H__
4740 +
4741 +#include <phy.h>
4742 +
4743 +enum LTQ_ETH_PORT_FLAGS {
4744 +       LTQ_ETH_PORT_NONE       = 0,
4745 +       LTQ_ETH_PORT_PHY        = 1,
4746 +       LTQ_ETH_PORT_SWITCH     = (1 << 1),
4747 +       LTQ_ETH_PORT_MAC        = (1 << 2),
4748 +};
4749 +
4750 +struct ltq_eth_port_config {
4751 +       u8 num;
4752 +       u8 phy_addr;
4753 +       u16 flags;
4754 +       phy_interface_t phy_if;
4755 +       u8 rgmii_rx_delay;
4756 +       u8 rgmii_tx_delay;
4757 +};
4758 +
4759 +struct ltq_eth_board_config {
4760 +       const struct ltq_eth_port_config *ports;
4761 +       int num_ports;
4762 +};
4763 +
4764 +extern int ltq_eth_initialize(const struct ltq_eth_board_config *board_config);
4765 +
4766 +#endif /* __LANTIQ_ETH_H__ */
4767 --- /dev/null
4768 +++ b/arch/mips/include/asm/lantiq/gpio.h
4769 @@ -0,0 +1,50 @@
4770 +/*
4771 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
4772 + *
4773 + * SPDX-License-Identifier:    GPL-2.0+
4774 + */
4775 +
4776 +#ifndef __LANTIQ_GPIO_H__
4777 +#define __LANTIQ_GPIO_H__
4778 +
4779 +enum ltq_gpio_dir {
4780 +       GPIO_DIR_IN = 0,
4781 +       GPIO_DIR_OUT
4782 +};
4783 +
4784 +enum ltq_gpio_od {
4785 +       GPIO_OD_ACTIVE = 0,
4786 +       GPIO_OD_NORMAL
4787 +};
4788 +
4789 +enum ltq_gpio_altsel {
4790 +       GPIO_ALTSEL_CLR = 0,
4791 +       GPIO_ALTSEL_SET
4792 +};
4793 +
4794 +extern int gpio_set_altfunc(unsigned gpio, int altsel0, int altsel1, int dir);
4795 +extern int gpio_set_opendrain(unsigned gpio, int od);
4796 +
4797 +static inline int gpio_to_port(unsigned gpio)
4798 +{
4799 +       return gpio >> 4;
4800 +}
4801 +
4802 +static inline int gpio_to_pin(unsigned gpio)
4803 +{
4804 +       return gpio & 0xF;
4805 +}
4806 +
4807 +static inline int gpio_to_bit(unsigned gpio)
4808 +{
4809 +       return 1 << gpio_to_pin(gpio);
4810 +}
4811 +
4812 +static inline int gpio_to_gpio(unsigned port, unsigned pin)
4813 +{
4814 +       return (port << 4) | (pin & 0xF);
4815 +}
4816 +
4817 +#include <asm-generic/gpio.h>
4818 +
4819 +#endif /* __LANTIQ_GPIO_H__ */
4820 --- /dev/null
4821 +++ b/arch/mips/include/asm/lantiq/io.h
4822 @@ -0,0 +1,37 @@
4823 +/*
4824 + * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
4825 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
4826 + *
4827 + * SPDX-License-Identifier:    GPL-2.0+
4828 + */
4829 +
4830 +#ifndef __LANTIQ_IO_H__
4831 +#define __LANTIQ_IO_H__
4832 +
4833 +#include <asm/io.h>
4834 +
4835 +#define ltq_readb(a)           __raw_readb(a)
4836 +#define ltq_writeb(a, v)       __raw_writeb(v, a)
4837 +
4838 +#define ltq_readl(a)           __raw_readl(a)
4839 +#define ltq_writel(a, v)       __raw_writel(v, a)
4840 +
4841 +#define ltq_clrbits(a, clear) \
4842 +       ltq_writel(a, ltq_readl(a) & ~(clear))
4843 +
4844 +#define ltq_setbits(a, set) \
4845 +       ltq_writel(a, ltq_readl(a) | (set))
4846 +
4847 +#define ltq_clrsetbits(a, clear, set) \
4848 +       ltq_writel(a, (ltq_readl(a) & ~(clear)) | (set))
4849 +
4850 +static inline void ltq_reg_dump(const void *addr, const char *desc)
4851 +{
4852 +       u32 data;
4853 +
4854 +       data = ltq_readl(addr);
4855 +       printf("ltq_reg_dump: %s 0x%p = 0x%08x\n",
4856 +               desc, addr, data);
4857 +}
4858 +
4859 +#endif /* __LANTIQ_IO_H__ */
4860 --- /dev/null
4861 +++ b/arch/mips/include/asm/lantiq/pm.h
4862 @@ -0,0 +1,21 @@
4863 +/*
4864 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
4865 + *
4866 + * SPDX-License-Identifier:    GPL-2.0+
4867 + */
4868 +
4869 +#ifndef __LANTIQ_PM_H__
4870 +#define __LANTIQ_PM_H__
4871 +
4872 +enum ltq_pm_modules {
4873 +       LTQ_PM_CORE,
4874 +       LTQ_PM_DMA,
4875 +       LTQ_PM_ETH,
4876 +       LTQ_PM_SPI,
4877 +};
4878 +
4879 +u32 ltq_pm_map(enum ltq_pm_modules module);
4880 +int ltq_pm_enable(enum ltq_pm_modules module);
4881 +int ltq_pm_disable(enum ltq_pm_modules module);
4882 +
4883 +#endif /* __LANTIQ_PM_H__ */
4884 --- /dev/null
4885 +++ b/arch/mips/include/asm/lantiq/reset.h
4886 @@ -0,0 +1,37 @@
4887 +/*
4888 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
4889 + *
4890 + * SPDX-License-Identifier:    GPL-2.0+
4891 + */
4892 +
4893 +#ifndef __LANTIQ_RESET_H__
4894 +#define __LANTIQ_RESET_H__
4895 +
4896 +enum ltq_reset_modules {
4897 +       LTQ_RESET_CORE,
4898 +       LTQ_RESET_DMA,
4899 +       LTQ_RESET_ETH,
4900 +       LTQ_RESET_PHY,
4901 +       LTQ_RESET_HARD,
4902 +       LTQ_RESET_SOFT,
4903 +};
4904 +
4905 +extern u32 ltq_reset_map(enum ltq_reset_modules module);
4906 +extern int ltq_reset_activate(enum ltq_reset_modules module);
4907 +extern int ltq_reset_deactivate(enum ltq_reset_modules module);
4908 +
4909 +static inline int ltq_reset_once(enum ltq_reset_modules module, ulong usec)
4910 +{
4911 +       int ret;
4912 +
4913 +       ret = ltq_reset_activate(module);
4914 +       if (ret)
4915 +               return ret;
4916 +
4917 +       __udelay(usec);
4918 +       ret = ltq_reset_deactivate(module);
4919 +
4920 +       return ret;
4921 +}
4922 +
4923 +#endif /* __LANTIQ_RESET_H__ */
4924 --- a/arch/mips/include/asm/mipsregs.h
4925 +++ b/arch/mips/include/asm/mipsregs.h
4926 @@ -46,7 +46,10 @@
4927  #define CP0_ENTRYLO1 $3
4928  #define CP0_CONF $3
4929  #define CP0_CONTEXT $4
4930 +#define CP0_CONTEXTCONFIG $4,1
4931 +#define CP0_USERLOCAL $4,1
4932  #define CP0_PAGEMASK $5
4933 +#define CP0_PAGEGRAIN $5,1
4934  #define CP0_WIRED $6
4935  #define CP0_INFO $7
4936  #define CP0_BADVADDR $8
4937 @@ -54,10 +57,19 @@
4938  #define CP0_ENTRYHI $10
4939  #define CP0_COMPARE $11
4940  #define CP0_STATUS $12
4941 +#define CP0_INTCTL $12,1
4942 +#define CP0_SRSCTL $12,2
4943 +#define CP0_SRSMAP $12,3
4944 +#define CP0_SRSHIGH $12,4
4945  #define CP0_CAUSE $13
4946  #define CP0_EPC $14
4947  #define CP0_PRID $15
4948 +#define CP0_EBASE $15,1
4949  #define CP0_CONFIG $16
4950 +#define CP0_CONFIG1 $16,1
4951 +#define CP0_CONFIG2 $16,2
4952 +#define CP0_CONFIG3 $16,3
4953 +#define CP0_CONFIG7 $16,7
4954  #define CP0_LLADDR $17
4955  #define CP0_WATCHLO $18
4956  #define CP0_WATCHHI $19
4957 @@ -70,7 +82,17 @@
4958  #define CP0_ECC $26
4959  #define CP0_CACHEERR $27
4960  #define CP0_TAGLO $28
4961 +#define CP0_ITAGLO $28
4962 +#define CP0_IDATALO $28,1
4963 +#define CP0_DTAGLO $28,2
4964 +#define CP0_DDATALO $28,3
4965 +#define CP0_L23TAGLO $28,4
4966 +#define CP0_L23DATALO $28,5
4967  #define CP0_TAGHI $29
4968 +#define CP0_IDATAHI $29,1
4969 +#define CP0_DTAGHI $29,2
4970 +#define CP0_L23TAGHI $29,4
4971 +#define CP0_L23DATAHI $29,5
4972  #define CP0_ERROREPC $30
4973  #define CP0_DESAVE $31
4974  
4975 @@ -395,6 +417,12 @@
4976  #define  CAUSEF_BD             (_ULCAST_(1)   << 31)
4977  
4978  /*
4979 + * Bits in the coprocessor 0 EBase register.
4980 + */
4981 +#define EBASEB_CPUNUM          0
4982 +#define EBASEF_CPUNUM          (_ULCAST_(1023))
4983 +
4984 +/*
4985   * Bits in the coprocessor 0 config register.
4986   */
4987  /* Generic bits.  */
4988 --- a/arch/mips/include/asm/u-boot-mips.h
4989 +++ b/arch/mips/include/asm/u-boot-mips.h
4990 @@ -23,3 +23,4 @@ static inline unsigned long image_copy_e
4991  }
4992  
4993  extern int incaip_set_cpuclk(void);
4994 +extern int arch_cpu_init(void);
4995 --- a/arch/mips/lib/board.c
4996 +++ b/arch/mips/lib/board.c
4997 @@ -33,6 +33,16 @@ static char *failed = "*** failed ***\n"
4998   */
4999  const unsigned long mips_io_port_base = -1;
5000  
5001 +int __arch_cpu_init(void)
5002 +{
5003 +       /*
5004 +        * Nothing to do in this dummy implementation
5005 +        */
5006 +       return 0;
5007 +}
5008 +int arch_cpu_init(void)
5009 +       __attribute__((weak, alias("__arch_cpu_init")));
5010 +
5011  int __board_early_init_f(void)
5012  {
5013         /*
5014 @@ -106,6 +116,7 @@ static int init_baudrate(void)
5015  typedef int (init_fnc_t)(void);
5016  
5017  init_fnc_t *init_sequence[] = {
5018 +       arch_cpu_init,
5019         board_early_init_f,
5020         timer_init,
5021         env_init,               /* initialize environment */
5022 --- /dev/null
5023 +++ b/board/lantiq/easy50712/Makefile
5024 @@ -0,0 +1,27 @@
5025 +#
5026 +# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de
5027 +#
5028 +# SPDX-License-Identifier:     GPL-2.0+
5029 +#
5030 +
5031 +include $(TOPDIR)/config.mk
5032 +
5033 +LIB    = $(obj)lib$(BOARD).o
5034 +
5035 +COBJS  = $(BOARD).o
5036 +
5037 +SRCS   := $(SOBJS:.o=.S) $(COBJS:.o=.c)
5038 +OBJS   := $(addprefix $(obj),$(COBJS))
5039 +SOBJS  := $(addprefix $(obj),$(SOBJS))
5040 +
5041 +$(LIB):        $(obj).depend $(OBJS) $(SOBJS)
5042 +       $(call cmd_link_o_target, $(OBJS) $(SOBJS))
5043 +
5044 +#########################################################################
5045 +
5046 +# defines $(obj).depend target
5047 +include $(SRCTREE)/rules.mk
5048 +
5049 +sinclude $(obj).depend
5050 +
5051 +#########################################################################
5052 --- /dev/null
5053 +++ b/board/lantiq/easy50712/config.mk
5054 @@ -0,0 +1,7 @@
5055 +#
5056 +# Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
5057 +#
5058 +# SPDX-License-Identifier:     GPL-2.0+
5059 +#
5060 +
5061 +PLATFORM_CPPFLAGS += -I$(TOPDIR)/board/$(BOARDDIR)
5062 --- /dev/null
5063 +++ b/board/lantiq/easy50712/ddr_settings.h
5064 @@ -0,0 +1,54 @@
5065 +/*
5066 + * Copyright (C) 2007-2010 Lantiq Deutschland GmbH
5067 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
5068 + *
5069 + * SPDX-License-Identifier:    GPL-2.0+
5070 + */
5071 +
5072 +#define MC_DC00_VALUE  0x1B1B
5073 +#define MC_DC01_VALUE  0x0
5074 +#define MC_DC02_VALUE  0x0
5075 +#define MC_DC03_VALUE  0x0
5076 +#define MC_DC04_VALUE  0x0
5077 +#define MC_DC05_VALUE  0x200
5078 +#define MC_DC06_VALUE  0x605
5079 +#define MC_DC07_VALUE  0x303
5080 +#define MC_DC08_VALUE  0x102
5081 +#define MC_DC09_VALUE  0x70a
5082 +#define MC_DC10_VALUE  0x203
5083 +#define MC_DC11_VALUE  0xc02
5084 +#define MC_DC12_VALUE  0x1C8
5085 +#define MC_DC13_VALUE  0x1
5086 +#define MC_DC14_VALUE  0x0
5087 +#define MC_DC15_VALUE  0x13c
5088 +#define MC_DC16_VALUE  0xC800
5089 +#define MC_DC17_VALUE  0xd
5090 +#define MC_DC18_VALUE  0x300
5091 +#define MC_DC19_VALUE  0x200
5092 +#define MC_DC20_VALUE  0xA04
5093 +#define MC_DC21_VALUE  0xd00
5094 +#define MC_DC22_VALUE  0xd0d
5095 +#define MC_DC23_VALUE  0x0
5096 +#define MC_DC24_VALUE  0x62
5097 +#define MC_DC25_VALUE  0x0
5098 +#define MC_DC26_VALUE  0x0
5099 +#define MC_DC27_VALUE  0x0
5100 +#define MC_DC28_VALUE  0x510
5101 +#define MC_DC29_VALUE  0x2d89
5102 +#define MC_DC30_VALUE  0x8300
5103 +#define MC_DC31_VALUE  0x0
5104 +#define MC_DC32_VALUE  0x0
5105 +#define MC_DC33_VALUE  0x0
5106 +#define MC_DC34_VALUE  0x0
5107 +#define MC_DC35_VALUE  0x0
5108 +#define MC_DC36_VALUE  0x0
5109 +#define MC_DC37_VALUE  0x0
5110 +#define MC_DC38_VALUE  0x0
5111 +#define MC_DC39_VALUE  0x0
5112 +#define MC_DC40_VALUE  0x0
5113 +#define MC_DC41_VALUE  0x0
5114 +#define MC_DC42_VALUE  0x0
5115 +#define MC_DC43_VALUE  0x0
5116 +#define MC_DC44_VALUE  0x0
5117 +#define MC_DC45_VALUE  0x500
5118 +#define MC_DC46_VALUE  0x0
5119 --- /dev/null
5120 +++ b/board/lantiq/easy50712/easy50712.c
5121 @@ -0,0 +1,112 @@
5122 +/*
5123 + * Copyright (C) 2010 Thomas Langer <thomas.langer@lantiq.com>
5124 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
5125 + *
5126 + * SPDX-License-Identifier:    GPL-2.0+
5127 + */
5128 +
5129 +#include <common.h>
5130 +#include <switch.h>
5131 +#include <spi.h>
5132 +#include <asm/gpio.h>
5133 +#include <asm/lantiq/eth.h>
5134 +#include <asm/lantiq/reset.h>
5135 +#include <asm/lantiq/chipid.h>
5136 +
5137 +static void gpio_init(void)
5138 +{
5139 +       /* SPI/CS output (low-active) for serial flash */
5140 +       gpio_direction_output(22, 1);
5141 +
5142 +       /* EBU.FL_CS1 as output for NAND CE */
5143 +       gpio_set_altfunc(23, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT);
5144 +       /* EBU.FL_A23 as output for NAND CLE */
5145 +       gpio_set_altfunc(24, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT);
5146 +       /* EBU.FL_A24 as output for NAND ALE */
5147 +       gpio_set_altfunc(13, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT);
5148 +
5149 +       /* enable CLK_OUT2 for external switch */
5150 +       gpio_set_altfunc(3, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT);
5151 +}
5152 +
5153 +int board_early_init_f(void)
5154 +{
5155 +       gpio_init();
5156 +
5157 +       return 0;
5158 +}
5159 +
5160 +int checkboard(void)
5161 +{
5162 +       puts("Board: " CONFIG_BOARD_NAME "\n");
5163 +       ltq_chip_print_info();
5164 +
5165 +       return 0;
5166 +}
5167 +
5168 +static const struct ltq_eth_port_config eth_port_config[] = {
5169 +       /* MAC0: Lantiq ADM6996I switch */
5170 +       { 0, 0x0, LTQ_ETH_PORT_SWITCH, PHY_INTERFACE_MODE_RMII },
5171 +};
5172 +
5173 +static const struct ltq_eth_board_config eth_board_config = {
5174 +       .ports = eth_port_config,
5175 +       .num_ports = ARRAY_SIZE(eth_port_config),
5176 +};
5177 +
5178 +int board_eth_init(bd_t *bis)
5179 +{
5180 +       return ltq_eth_initialize(&eth_board_config);
5181 +}
5182 +
5183 +static struct switch_device adm6996i_dev = {
5184 +       .name = "adm6996i",
5185 +       .cpu_port = 5,
5186 +       .port_mask = 0xF,
5187 +};
5188 +
5189 +int board_switch_init(void)
5190 +{
5191 +       /* Deactivate HRST line to release reset of ADM6996I switch */
5192 +       ltq_reset_once(LTQ_RESET_HARD, 200000);
5193 +
5194 +       /* ADM6996I needs some time to come out of reset */
5195 +       __udelay(50000);
5196 +
5197 +       return switch_device_register(&adm6996i_dev);
5198 +}
5199 +
5200 +int spi_cs_is_valid(unsigned int bus, unsigned int cs)
5201 +{
5202 +       if (bus)
5203 +               return 0;
5204 +
5205 +       switch (cs) {
5206 +       case 2:
5207 +               return 1;
5208 +       default:
5209 +               return 0;
5210 +       }
5211 +}
5212 +
5213 +void spi_cs_activate(struct spi_slave *slave)
5214 +{
5215 +       switch (slave->cs) {
5216 +       case 2:
5217 +               gpio_set_value(22, 0);
5218 +               break;
5219 +       default:
5220 +               break;
5221 +       }
5222 +}
5223 +
5224 +void spi_cs_deactivate(struct spi_slave *slave)
5225 +{
5226 +       switch (slave->cs) {
5227 +       case 2:
5228 +               gpio_set_value(22, 1);
5229 +               break;
5230 +       default:
5231 +               break;
5232 +       }
5233 +}
5234 --- /dev/null
5235 +++ b/board/lantiq/easy80920/Makefile
5236 @@ -0,0 +1,27 @@
5237 +#
5238 +# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de
5239 +#
5240 +# SPDX-License-Identifier:     GPL-2.0+
5241 +#
5242 +
5243 +include $(TOPDIR)/config.mk
5244 +
5245 +LIB    = $(obj)lib$(BOARD).o
5246 +
5247 +COBJS  = $(BOARD).o
5248 +
5249 +SRCS   := $(SOBJS:.o=.S) $(COBJS:.o=.c)
5250 +OBJS   := $(addprefix $(obj),$(COBJS))
5251 +SOBJS  := $(addprefix $(obj),$(SOBJS))
5252 +
5253 +$(LIB):        $(obj).depend $(OBJS) $(SOBJS)
5254 +       $(call cmd_link_o_target, $(OBJS) $(SOBJS))
5255 +
5256 +#########################################################################
5257 +
5258 +# defines $(obj).depend target
5259 +include $(SRCTREE)/rules.mk
5260 +
5261 +sinclude $(obj).depend
5262 +
5263 +#########################################################################
5264 --- /dev/null
5265 +++ b/board/lantiq/easy80920/config.mk
5266 @@ -0,0 +1,7 @@
5267 +#
5268 +# Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
5269 +#
5270 +# SPDX-License-Identifier:     GPL-2.0+
5271 +#
5272 +
5273 +PLATFORM_CPPFLAGS += -I$(TOPDIR)/board/$(BOARDDIR)
5274 --- /dev/null
5275 +++ b/board/lantiq/easy80920/ddr_settings.h
5276 @@ -0,0 +1,69 @@
5277 +/*
5278 + * Copyright (C) 2007-2010 Lantiq Deutschland GmbH
5279 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
5280 + *
5281 + * SPDX-License-Identifier:    GPL-2.0+
5282 + */
5283 +
5284 +#define        MC_CCR00_VALUE  0x101
5285 +#define        MC_CCR01_VALUE  0x1000100
5286 +#define        MC_CCR02_VALUE  0x1010000
5287 +#define        MC_CCR03_VALUE  0x101
5288 +#define        MC_CCR04_VALUE  0x1000000
5289 +#define        MC_CCR05_VALUE  0x1000101
5290 +#define        MC_CCR06_VALUE  0x1000100
5291 +#define        MC_CCR07_VALUE  0x1010000
5292 +#define        MC_CCR08_VALUE  0x1000101
5293 +#define        MC_CCR09_VALUE  0x0
5294 +#define        MC_CCR10_VALUE  0x2000100
5295 +#define        MC_CCR11_VALUE  0x2000300
5296 +#define        MC_CCR12_VALUE  0x30000
5297 +#define        MC_CCR13_VALUE  0x202
5298 +#define        MC_CCR14_VALUE  0x7080A0F
5299 +#define        MC_CCR15_VALUE  0x2040F
5300 +#define        MC_CCR16_VALUE  0x40000
5301 +#define        MC_CCR17_VALUE  0x70102
5302 +#define        MC_CCR18_VALUE  0x4020002
5303 +#define        MC_CCR19_VALUE  0x30302
5304 +#define        MC_CCR20_VALUE  0x8000700
5305 +#define        MC_CCR21_VALUE  0x40F020A
5306 +#define        MC_CCR22_VALUE  0x0
5307 +#define        MC_CCR23_VALUE  0xC020000
5308 +#define        MC_CCR24_VALUE  0x4401B04
5309 +#define        MC_CCR25_VALUE  0x0
5310 +#define        MC_CCR26_VALUE  0x0
5311 +#define        MC_CCR27_VALUE  0x6420000
5312 +#define        MC_CCR28_VALUE  0x0
5313 +#define        MC_CCR29_VALUE  0x0
5314 +#define        MC_CCR30_VALUE  0x798
5315 +#define        MC_CCR31_VALUE  0x0
5316 +#define        MC_CCR32_VALUE  0x0
5317 +#define        MC_CCR33_VALUE  0x650000
5318 +#define        MC_CCR34_VALUE  0x200C8
5319 +#define        MC_CCR35_VALUE  0x1D445D
5320 +#define        MC_CCR36_VALUE  0xC8
5321 +#define        MC_CCR37_VALUE  0xC351
5322 +#define        MC_CCR38_VALUE  0x0
5323 +#define        MC_CCR39_VALUE  0x141F04
5324 +#define        MC_CCR40_VALUE  0x142704
5325 +#define        MC_CCR41_VALUE  0x141b42
5326 +#define        MC_CCR42_VALUE  0x141b42
5327 +#define        MC_CCR43_VALUE  0x566504
5328 +#define        MC_CCR44_VALUE  0x566504
5329 +#define        MC_CCR45_VALUE  0x565F17
5330 +#define        MC_CCR46_VALUE  0x565F17
5331 +#define        MC_CCR47_VALUE  0x0
5332 +#define        MC_CCR48_VALUE  0x0
5333 +#define        MC_CCR49_VALUE  0x0
5334 +#define        MC_CCR50_VALUE  0x0
5335 +#define        MC_CCR51_VALUE  0x0
5336 +#define        MC_CCR52_VALUE  0x133
5337 +#define        MC_CCR53_VALUE  0xF3014B27
5338 +#define        MC_CCR54_VALUE  0xF3014B27
5339 +#define        MC_CCR55_VALUE  0xF3014B27
5340 +#define        MC_CCR56_VALUE  0xF3014B27
5341 +#define        MC_CCR57_VALUE  0x7800301
5342 +#define        MC_CCR58_VALUE  0x7800301
5343 +#define        MC_CCR59_VALUE  0x7800301
5344 +#define        MC_CCR60_VALUE  0x7800301
5345 +#define        MC_CCR61_VALUE  0x4
5346 --- /dev/null
5347 +++ b/board/lantiq/easy80920/easy80920.c
5348 @@ -0,0 +1,138 @@
5349 +/*
5350 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
5351 + *
5352 + * SPDX-License-Identifier:    GPL-2.0+
5353 + */
5354 +
5355 +#include <common.h>
5356 +#include <spi.h>
5357 +#include <asm/gpio.h>
5358 +#include <asm/lantiq/eth.h>
5359 +#include <asm/lantiq/chipid.h>
5360 +#include <asm/lantiq/cpu.h>
5361 +#include <asm/arch/gphy.h>
5362 +
5363 +#if defined(CONFIG_SPL_BUILD)
5364 +#define do_gpio_init   1
5365 +#define do_pll_init    1
5366 +#define do_dcdc_init   0
5367 +#elif defined(CONFIG_SYS_BOOT_RAM)
5368 +#define do_gpio_init   1
5369 +#define do_pll_init    0
5370 +#define do_dcdc_init   1
5371 +#elif defined(CONFIG_SYS_BOOT_NOR)
5372 +#define do_gpio_init   1
5373 +#define do_pll_init    1
5374 +#define do_dcdc_init   1
5375 +#else
5376 +#define do_gpio_init   0
5377 +#define do_pll_init    0
5378 +#define do_dcdc_init   1
5379 +#endif
5380 +
5381 +static void gpio_init(void)
5382 +{
5383 +       /* SPI CS 0.4 to serial flash */
5384 +       gpio_direction_output(10, 1);
5385 +
5386 +       /* EBU.FL_CS1 as output for NAND CE */
5387 +       gpio_set_altfunc(23, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT);
5388 +       /* EBU.FL_A23 as output for NAND CLE */
5389 +       gpio_set_altfunc(24, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT);
5390 +       /* EBU.FL_A24 as output for NAND ALE */
5391 +       gpio_set_altfunc(13, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT);
5392 +       /* GPIO 3.0 as input for NAND Ready Busy */
5393 +       gpio_set_altfunc(48, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_IN);
5394 +       /* GPIO 3.1 as output for NAND Read */
5395 +       gpio_set_altfunc(49, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT);
5396 +}
5397 +
5398 +int board_early_init_f(void)
5399 +{
5400 +       if (do_gpio_init)
5401 +               gpio_init();
5402 +
5403 +       if (do_pll_init)
5404 +               ltq_pll_init();
5405 +
5406 +       if (do_dcdc_init)
5407 +               ltq_dcdc_init(0x7F);
5408 +
5409 +       return 0;
5410 +}
5411 +
5412 +int checkboard(void)
5413 +{
5414 +       puts("Board: " CONFIG_BOARD_NAME "\n");
5415 +       ltq_chip_print_info();
5416 +
5417 +       return 0;
5418 +}
5419 +
5420 +static const struct ltq_eth_port_config eth_port_config[] = {
5421 +       /* GMAC0: external Lantiq PEF7071 10/100/1000 PHY for LAN port 0 */
5422 +       { 0, 0x0, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_RGMII },
5423 +       /* GMAC1: external Lantiq PEF7071 10/100/1000 PHY for LAN port 1 */
5424 +       { 1, 0x1, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_RGMII },
5425 +       /* GMAC2: internal GPHY0 with 10/100/1000 firmware for LAN port 2 */
5426 +       { 2, 0x11, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_GMII },
5427 +       /* GMAC3: unused */
5428 +       { 3, 0x0, LTQ_ETH_PORT_NONE, PHY_INTERFACE_MODE_NONE },
5429 +       /* GMAC4: internal GPHY1 with 10/100/1000 firmware for LAN port 3 */
5430 +       { 4, 0x13, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_GMII },
5431 +       /* GMAC5: external Lantiq PEF7071 10/100/1000 PHY for WANoE port */
5432 +       { 5, 0x5, LTQ_ETH_PORT_PHY, PHY_INTERFACE_MODE_RGMII },
5433 +};
5434 +
5435 +static const struct ltq_eth_board_config eth_board_config = {
5436 +       .ports = eth_port_config,
5437 +       .num_ports = ARRAY_SIZE(eth_port_config),
5438 +};
5439 +
5440 +int board_eth_init(bd_t * bis)
5441 +{
5442 +       const enum ltq_gphy_clk clk = LTQ_GPHY_CLK_25MHZ_PLL0;
5443 +       const ulong fw_addr = 0x80FF0000;
5444 +
5445 +       ltq_gphy_phy11g_a1x_load(fw_addr);
5446 +
5447 +       ltq_cgu_gphy_clk_src(clk);
5448 +
5449 +       ltq_rcu_gphy_boot(0, fw_addr);
5450 +       ltq_rcu_gphy_boot(1, fw_addr);
5451 +
5452 +       return ltq_eth_initialize(&eth_board_config);
5453 +}
5454 +
5455 +int spi_cs_is_valid(unsigned int bus, unsigned int cs)
5456 +{
5457 +       if (bus)
5458 +               return 0;
5459 +
5460 +       if (cs == 4)
5461 +               return 1;
5462 +
5463 +       return 0;
5464 +}
5465 +
5466 +void spi_cs_activate(struct spi_slave *slave)
5467 +{
5468 +       switch (slave->cs) {
5469 +       case 4:
5470 +               gpio_set_value(10, 0);
5471 +               break;
5472 +       default:
5473 +               break;
5474 +       }
5475 +}
5476 +
5477 +void spi_cs_deactivate(struct spi_slave *slave)
5478 +{
5479 +       switch (slave->cs) {
5480 +       case 4:
5481 +               gpio_set_value(10, 1);
5482 +               break;
5483 +       default:
5484 +               break;
5485 +       }
5486 +}
5487 --- a/boards.cfg
5488 +++ b/boards.cfg
5489 @@ -502,10 +502,17 @@ Active  mips        mips32         au1x0
5490  Active  mips        mips32         au1x00      -               dbau1x00            dbau1550                             dbau1x00:DBAU1550                                                                                                                 Thomas Lange <thomas@corelatus.se>
5491  Active  mips        mips32         au1x00      -               dbau1x00            dbau1550_el                          dbau1x00:DBAU1550,SYS_LITTLE_ENDIAN                                                                                               Thomas Lange <thomas@corelatus.se>
5492  Active  mips        mips32         au1x00      -               pb1x00              pb1000                               pb1x00:PB1000                                                                                                                     -
5493 +Active  mips        mips32         danube      lantiq          easy50712           easy50712_nor                        easy50712:SYS_BOOT_NOR                                                                                                            Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
5494 +Active  mips        mips32         danube      lantiq          easy50712           easy50712_norspl                     easy50712:SYS_BOOT_NORSPL                                                                                                         Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
5495 +Active  mips        mips32         danube      lantiq          easy50712           easy50712_ram                        easy50712:SYS_BOOT_RAM                                                                                                            Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
5496  Active  mips        mips32         incaip      -               incaip              incaip                               -                                                                                                                                 Wolfgang Denk <wd@denx.de>
5497  Active  mips        mips32         incaip      -               incaip              incaip_100MHz                        incaip:CPU_CLOCK_RATE=100000000                                                                                                   Wolfgang Denk <wd@denx.de>
5498  Active  mips        mips32         incaip      -               incaip              incaip_133MHz                        incaip:CPU_CLOCK_RATE=133000000                                                                                                   Wolfgang Denk <wd@denx.de>
5499  Active  mips        mips32         incaip      -               incaip              incaip_150MHz                        incaip:CPU_CLOCK_RATE=150000000                                                                                                   Wolfgang Denk <wd@denx.de>
5500 +Active  mips        mips32         vrx200      lantiq          easy80920           easy80920_nor                        easy80920:SYS_BOOT_NOR                                                                                                            Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
5501 +Active  mips        mips32         vrx200      lantiq          easy80920           easy80920_norspl                     easy80920:SYS_BOOT_NORSPL                                                                                                         Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
5502 +Active  mips        mips32         vrx200      lantiq          easy80920           easy80920_ram                        easy80920:SYS_BOOT_RAM                                                                                                            Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
5503 +Active  mips        mips32         vrx200      lantiq          easy80920           easy80920_sfspl                      easy80920:SYS_BOOT_SFSPL                                                                                                          Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
5504  Active  mips        mips64         -           -               qemu-mips           qemu_mips64                          qemu-mips64:SYS_BIG_ENDIAN                                                                                                        -
5505  Active  mips        mips64         -           -               qemu-mips           qemu_mips64el                        qemu-mips64:SYS_LITTLE_ENDIAN                                                                                                     -
5506  Active  nds32       n1213          ag101       AndesTech       adp-ag101           adp-ag101                            -                                                                                                                                 Andes <uboot@andestech.com>
5507 --- a/drivers/dma/Makefile
5508 +++ b/drivers/dma/Makefile
5509 @@ -12,6 +12,7 @@ LIB   := $(obj)libdma.o
5510  COBJS-$(CONFIG_FSLDMAFEC) += MCD_tasksInit.o MCD_dmaApi.o MCD_tasks.o
5511  COBJS-$(CONFIG_APBH_DMA) += apbh_dma.o
5512  COBJS-$(CONFIG_FSL_DMA) += fsl_dma.o
5513 +COBJS-$(CONFIG_LANTIQ_DMA) += lantiq_dma.o
5514  COBJS-$(CONFIG_OMAP3_DMA) += omap3_dma.o
5515  
5516  COBJS  := $(COBJS-y)
5517 --- /dev/null
5518 +++ b/drivers/dma/lantiq_dma.c
5519 @@ -0,0 +1,387 @@
5520 +/*
5521 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
5522 + *
5523 + * SPDX-License-Identifier:    GPL-2.0+
5524 + */
5525 +
5526 +#include <common.h>
5527 +#include <malloc.h>
5528 +#include <watchdog.h>
5529 +#include <linux/compiler.h>
5530 +#include <asm/lantiq/io.h>
5531 +#include <asm/lantiq/dma.h>
5532 +#include <asm/lantiq/pm.h>
5533 +#include <asm/lantiq/reset.h>
5534 +#include <asm/arch/soc.h>
5535 +#include <asm/processor.h>
5536 +
5537 +#define DMA_CTRL_PKTARB                        (1 << 31)
5538 +#define DMA_CTRL_MBRSTARB              (1 << 30)
5539 +#define DMA_CTRL_MBRSTCNT_SHIFT                16
5540 +#define DMA_CTRL_MBRSTCNT_MASK         (0x3ff << DMA_CTRL_MBRSTCNT_SHIFT)
5541 +#define DMA_CTRL_DRB                   (1 << 8)
5542 +#define DMA_CTRL_RESET                 (1 << 0)
5543 +
5544 +#define DMA_CPOLL_EN                   (1 << 31)
5545 +#define DMA_CPOLL_CNT_SHIFT            4
5546 +#define DMA_CPOLL_CNT_MASK             (0xFFF << DMA_CPOLL_CNT_SHIFT)
5547 +
5548 +#define DMA_CCTRL_TXWGT_SHIFT          16
5549 +#define DMA_CCTRL_TXWGT_MASK           (0x3 << DMA_CCTRL_TXWGT_SHIFT)
5550 +#define DMA_CCTRL_CLASS_SHIFT          9
5551 +#define DMA_CCTRL_CLASS_MASK           (0x3 << DMA_CCTRL_CLASS_SHIFT)
5552 +#define DMA_CCTRL_RST                  (1 << 1)
5553 +#define DMA_CCTRL_ONOFF                        (1 << 0)
5554 +
5555 +#define DMA_PCTRL_TXBL_SHIFT           4
5556 +#define DMA_PCTRL_TXBL_2WORDS          (1 << DMA_PCTRL_TXBL_SHIFT)
5557 +#define DMA_PCTRL_TXBL_4WORDS          (2 << DMA_PCTRL_TXBL_SHIFT)
5558 +#define DMA_PCTRL_TXBL_8WORDS          (3 << DMA_PCTRL_TXBL_SHIFT)
5559 +#define DMA_PCTRL_RXBL_SHIFT           2
5560 +#define DMA_PCTRL_RXBL_2WORDS          (1 << DMA_PCTRL_RXBL_SHIFT)
5561 +#define DMA_PCTRL_RXBL_4WORDS          (2 << DMA_PCTRL_RXBL_SHIFT)
5562 +#define DMA_PCTRL_RXBL_8WORDS          (3 << DMA_PCTRL_RXBL_SHIFT)
5563 +#define DMA_PCTRL_TXENDI_SHIFT         10
5564 +#define DMA_PCTRL_TXENDI_MASK          (0x3 << DMA_PCTRL_TXENDI_SHIFT)
5565 +#define DMA_PCTRL_RXENDI_SHIFT         8
5566 +#define DMA_PCTRL_RXENDI_MASK          (0x3 << DMA_PCTRL_RXENDI_SHIFT)
5567 +
5568 +#define DMA_DESC_OWN                   (1 << 31)
5569 +#define DMA_DESC_C                     (1 << 30)
5570 +#define DMA_DESC_SOP                   (1 << 29)
5571 +#define DMA_DESC_EOP                   (1 << 28)
5572 +#define DMA_DESC_TX_OFFSET(x)          ((x & 0x1f) << 23)
5573 +#define DMA_DESC_RX_OFFSET(x)          ((x & 0x3) << 23)
5574 +#define DMA_DESC_LENGTH(x)             (x & 0xffff)
5575 +
5576 +#define PTR_ALIGN(p, a)                ((typeof(p))ALIGN((unsigned long)(p), (a)))
5577 +
5578 +struct ltq_dma_regs {
5579 +       u32     clc;            /* Clock control */
5580 +       u32     rsvd0;
5581 +       u32     id;             /* Identification */
5582 +       u32     rsvd1;
5583 +       u32     ctrl;           /* Control */
5584 +       u32     cpoll;          /* Channel polling */
5585 +       u32     cs;             /* Channel select */
5586 +       u32     cctrl;          /* Channel control */
5587 +       u32     cdba;           /* Channel descriptor base address */
5588 +       u32     cdlen;          /* Channel descriptor length */
5589 +       u32     cis;            /* Channel interrupt status */
5590 +       u32     cie;            /* Channel interrupt enable */
5591 +       u32     cgbl;           /* Channel global buffer length */
5592 +       u32     cdptnrd;        /* Current descriptor pointer */
5593 +       u32     rsvd2[2];
5594 +       u32     ps;             /* Port select */
5595 +       u32     pctrl;          /* Port control */
5596 +       u32     rsvd3[43];
5597 +       u32     irnen;          /* Interrupt node enable */
5598 +       u32     irncr;          /* Interrupt node control */
5599 +       u32     irnicr;         /* Interrupt capture */
5600 +};
5601 +
5602 +static struct ltq_dma_regs *ltq_dma_regs =
5603 +       (struct ltq_dma_regs *) CKSEG1ADDR(LTQ_DMA_BASE);
5604 +
5605 +static inline unsigned long ltq_dma_addr_to_virt(u32 dma_addr)
5606 +{
5607 +       return KSEG0ADDR(dma_addr);
5608 +}
5609 +
5610 +static inline u32 ltq_virt_to_dma_addr(void *addr)
5611 +{
5612 +       return CPHYSADDR(addr);
5613 +}
5614 +
5615 +static inline int ltq_dma_burst_align(enum ltq_dma_burst_len burst_len)
5616 +{
5617 +       switch (burst_len) {
5618 +       case LTQ_DMA_BURST_2WORDS:
5619 +               return 2 * 4;
5620 +       case LTQ_DMA_BURST_4WORDS:
5621 +               return 4 * 4;
5622 +       case LTQ_DMA_BURST_8WORDS:
5623 +               return 8 * 4;
5624 +       }
5625 +
5626 +       return 0;
5627 +}
5628 +
5629 +static inline void ltq_dma_sync(void)
5630 +{
5631 +       __asm__ __volatile__("sync");
5632 +}
5633 +
5634 +static inline void ltq_dma_dcache_wb_inv(const void *ptr, size_t size)
5635 +{
5636 +       unsigned long addr = (unsigned long) ptr;
5637 +
5638 +       flush_dcache_range(addr, addr + size);
5639 +       ltq_dma_sync();
5640 +}
5641 +
5642 +static inline void ltq_dma_dcache_inv(const void *ptr, size_t size)
5643 +{
5644 +       unsigned long addr = (unsigned long) ptr;
5645 +
5646 +       invalidate_dcache_range(addr, addr + size);
5647 +}
5648 +
5649 +void ltq_dma_init(void)
5650 +{
5651 +       /* Power up DMA */
5652 +       ltq_pm_enable(LTQ_PM_DMA);
5653 +
5654 +       /* Reset DMA */
5655 +       ltq_setbits(&ltq_dma_regs->ctrl, DMA_CTRL_RESET);
5656 +
5657 +       /* Disable and clear all interrupts */
5658 +       ltq_writel(&ltq_dma_regs->irnen, 0);
5659 +       ltq_writel(&ltq_dma_regs->irncr, 0xFFFFF);
5660 +
5661 +#if 0
5662 +       /* Enable packet arbitration */
5663 +       ltq_setbits(&ltq_dma_regs->ctrl, DMA_CTRL_PKTARB);
5664 +#endif
5665 +
5666 +#if 0
5667 +       /* Enable descriptor read back */
5668 +       ltq_setbits(&ltq_dma_regs->ctrl, DMA_CTRL_DRB);
5669 +#endif
5670 +
5671 +       /* Enable polling for descriptor fetching for all channels */
5672 +       ltq_writel(&ltq_dma_regs->cpoll, DMA_CPOLL_EN |
5673 +               (4 << DMA_CPOLL_CNT_SHIFT));
5674 +}
5675 +
5676 +static void ltq_dma_channel_reset(struct ltq_dma_channel *chan)
5677 +{
5678 +       ltq_writel(&ltq_dma_regs->cs, chan->chan_no);
5679 +       ltq_setbits(&ltq_dma_regs->cctrl, DMA_CCTRL_RST);
5680 +}
5681 +
5682 +static void ltq_dma_channel_enable(struct ltq_dma_channel *chan)
5683 +{
5684 +       ltq_writel(&ltq_dma_regs->cs, chan->chan_no);
5685 +       ltq_setbits(&ltq_dma_regs->cctrl, DMA_CCTRL_ONOFF);
5686 +}
5687 +
5688 +static void ltq_dma_channel_disable(struct ltq_dma_channel *chan)
5689 +{
5690 +       ltq_writel(&ltq_dma_regs->cs, chan->chan_no);
5691 +       ltq_clrbits(&ltq_dma_regs->cctrl, DMA_CCTRL_ONOFF);
5692 +}
5693 +
5694 +static void ltq_dma_port_init(struct ltq_dma_device *dev)
5695 +{
5696 +       u32 pctrl;
5697 +
5698 +       pctrl = dev->tx_endian_swap << DMA_PCTRL_TXENDI_SHIFT;
5699 +       pctrl |= dev->rx_endian_swap << DMA_PCTRL_RXENDI_SHIFT;
5700 +       pctrl |= dev->tx_burst_len << DMA_PCTRL_TXBL_SHIFT;
5701 +       pctrl |= dev->rx_burst_len << DMA_PCTRL_RXBL_SHIFT;
5702 +
5703 +       ltq_writel(&ltq_dma_regs->ps, dev->port);
5704 +       ltq_writel(&ltq_dma_regs->pctrl, pctrl);
5705 +}
5706 +
5707 +static int ltq_dma_alloc_descriptors(struct ltq_dma_device *dev,
5708 +                                       struct ltq_dma_channel *chan)
5709 +{
5710 +       size_t size;
5711 +       void *desc_base;
5712 +
5713 +       size = ALIGN(sizeof(struct ltq_dma_desc) * chan->num_desc +
5714 +                       ARCH_DMA_MINALIGN, ARCH_DMA_MINALIGN);
5715 +
5716 +       chan->mem_base = malloc(size);
5717 +       if (!chan->mem_base)
5718 +               return 1;
5719 +
5720 +       memset(chan->mem_base, 0, size);
5721 +       ltq_dma_dcache_wb_inv(chan->mem_base, size);
5722 +
5723 +       desc_base = PTR_ALIGN(chan->mem_base, ARCH_DMA_MINALIGN);
5724 +
5725 +       debug("DMA: mem %p, desc %p\n", chan->mem_base, desc_base);
5726 +
5727 +       /* Align descriptor base to 8 bytes */
5728 +       chan->desc_base = (void *) CKSEG1ADDR(desc_base);
5729 +       chan->dma_addr = CPHYSADDR(desc_base);
5730 +       chan->dev = dev;
5731 +
5732 +       debug("DMA: desc_base %p, size %u\n", chan->desc_base, size);
5733 +
5734 +       /* Configure hardware with location of descriptor list */
5735 +       ltq_writel(&ltq_dma_regs->cs, chan->chan_no);
5736 +       ltq_writel(&ltq_dma_regs->cdba, chan->dma_addr);
5737 +       ltq_writel(&ltq_dma_regs->cdlen, chan->num_desc);
5738 +       ltq_writel(&ltq_dma_regs->cctrl, (3 << DMA_CCTRL_TXWGT_SHIFT) |
5739 +               (chan->class << DMA_CCTRL_CLASS_SHIFT));
5740 +       ltq_writel(&ltq_dma_regs->cctrl, DMA_CCTRL_RST);
5741 +
5742 +       return 0;
5743 +}
5744 +
5745 +static void ltq_dma_free_descriptors(struct ltq_dma_channel *chan)
5746 +{
5747 +       ltq_writel(&ltq_dma_regs->cs, chan->chan_no);
5748 +       ltq_writel(&ltq_dma_regs->cdba, 0);
5749 +       ltq_writel(&ltq_dma_regs->cdlen, 0);
5750 +
5751 +       ltq_dma_channel_reset(chan);
5752 +
5753 +       free(chan->mem_base);
5754 +}
5755 +
5756 +int ltq_dma_register(struct ltq_dma_device *dev)
5757 +{
5758 +       int ret;
5759 +
5760 +       ltq_dma_port_init(dev);
5761 +
5762 +       ret = ltq_dma_alloc_descriptors(dev, &dev->rx_chan);
5763 +       if (ret)
5764 +               return ret;
5765 +
5766 +       ret = ltq_dma_alloc_descriptors(dev, &dev->tx_chan);
5767 +       if (ret) {
5768 +               ltq_dma_free_descriptors(&dev->rx_chan);
5769 +               return ret;
5770 +       }
5771 +
5772 +       return 0;
5773 +}
5774 +
5775 +void ltq_dma_reset(struct ltq_dma_device *dev)
5776 +{
5777 +       ltq_dma_channel_reset(&dev->rx_chan);
5778 +       ltq_dma_channel_reset(&dev->tx_chan);
5779 +}
5780 +
5781 +void ltq_dma_enable(struct ltq_dma_device *dev)
5782 +{
5783 +       ltq_dma_channel_enable(&dev->rx_chan);
5784 +       ltq_dma_channel_enable(&dev->tx_chan);
5785 +}
5786 +
5787 +void ltq_dma_disable(struct ltq_dma_device *dev)
5788 +{
5789 +       ltq_dma_channel_disable(&dev->rx_chan);
5790 +       ltq_dma_channel_disable(&dev->tx_chan);
5791 +}
5792 +
5793 +int ltq_dma_rx_map(struct ltq_dma_device *dev, int index, void *data, int len)
5794 +{
5795 +       struct ltq_dma_channel *chan = &dev->rx_chan;
5796 +       struct ltq_dma_desc *desc = &chan->desc_base[index];
5797 +       u32 dma_addr = ltq_virt_to_dma_addr(data);
5798 +       unsigned int offset;
5799 +
5800 +       offset = dma_addr % ltq_dma_burst_align(dev->rx_burst_len);
5801 +
5802 +       ltq_dma_dcache_inv(data, len);
5803 +
5804 +#if 0
5805 +       printf("%s: index %d, data %p, dma_addr %08x, offset %u, len %d\n",
5806 +               __func__, index, data, dma_addr, offset, len);
5807 +#endif
5808 +
5809 +
5810 +       desc->addr = dma_addr - offset;
5811 +       desc->ctl = DMA_DESC_OWN | DMA_DESC_RX_OFFSET(offset) |
5812 +                       DMA_DESC_LENGTH(len);
5813 +
5814 +#if 0
5815 +       printf("%s: index %d, desc %p, desc->ctl %08x\n",
5816 +               __func__, index, desc, desc->ctl);
5817 +#endif
5818 +
5819 +       return 0;
5820 +}
5821 +
5822 +int ltq_dma_rx_poll(struct ltq_dma_device *dev, int index)
5823 +{
5824 +       struct ltq_dma_channel *chan = &dev->rx_chan;
5825 +       struct ltq_dma_desc *desc = &chan->desc_base[index];
5826 +
5827 +#if 0
5828 +       printf("%s: index %d, desc %p, desc->ctl %08x\n",
5829 +               __func__, index, desc, desc->ctl);
5830 +#endif
5831 +
5832 +       if (desc->ctl & DMA_DESC_OWN)
5833 +               return 0;
5834 +
5835 +       if (desc->ctl & DMA_DESC_C)
5836 +               return 1;
5837 +
5838 +       return 0;
5839 +}
5840 +
5841 +int ltq_dma_rx_length(struct ltq_dma_device *dev, int index)
5842 +{
5843 +       struct ltq_dma_channel *chan = &dev->rx_chan;
5844 +       struct ltq_dma_desc *desc = &chan->desc_base[index];
5845 +
5846 +       return DMA_DESC_LENGTH(desc->ctl);
5847 +}
5848 +
5849 +int ltq_dma_tx_map(struct ltq_dma_device *dev, int index, void *data, int len,
5850 +                       unsigned long timeout)
5851 +{
5852 +       struct ltq_dma_channel *chan = &dev->tx_chan;
5853 +       struct ltq_dma_desc *desc = &chan->desc_base[index];
5854 +       unsigned int offset;
5855 +       unsigned long timebase = get_timer(0);
5856 +       u32 dma_addr = ltq_virt_to_dma_addr(data);
5857 +
5858 +       while (desc->ctl & DMA_DESC_OWN) {
5859 +               WATCHDOG_RESET();
5860 +
5861 +               if (get_timer(timebase) >= timeout) {
5862 +#if 0
5863 +                       printf("%s: timeout: index %d, desc %p, desc->ctl %08x\n",
5864 +                               __func__, index, desc, desc->ctl);
5865 +#endif
5866 +                       return -1;
5867 +               }
5868 +       }
5869 +
5870 +       offset = dma_addr % ltq_dma_burst_align(dev->rx_burst_len);
5871 +
5872 +#if 0
5873 +       printf("%s: index %d, desc %p, data %p, dma_addr %08x, offset %u, len %d\n",
5874 +               __func__, index, desc, data, dma_addr, offset, len);
5875 +#endif
5876 +
5877 +       ltq_dma_dcache_wb_inv(data, len);
5878 +
5879 +       desc->addr = dma_addr - offset;
5880 +       desc->ctl = DMA_DESC_OWN | DMA_DESC_SOP | DMA_DESC_EOP |
5881 +                       DMA_DESC_TX_OFFSET(offset) | DMA_DESC_LENGTH(len);
5882 +
5883 +#if 0
5884 +       printf("%s: index %d, desc %p, desc->ctl %08x\n",
5885 +               __func__, index, desc, desc->ctl);
5886 +#endif
5887 +
5888 +       return 0;
5889 +}
5890 +
5891 +int ltq_dma_tx_wait(struct ltq_dma_device *dev, int index,
5892 +                       unsigned long timeout)
5893 +{
5894 +       struct ltq_dma_channel *chan = &dev->tx_chan;
5895 +       struct ltq_dma_desc *desc = &chan->desc_base[index];
5896 +       unsigned long timebase = get_timer(0);
5897 +
5898 +       while ((desc->ctl & (DMA_DESC_OWN | DMA_DESC_C)) != DMA_DESC_C) {
5899 +               WATCHDOG_RESET();
5900 +
5901 +               if (get_timer(timebase) >= timeout)
5902 +                       return -1;
5903 +       }
5904 +
5905 +       return 0;
5906 +}
5907 --- a/drivers/gpio/Makefile
5908 +++ b/drivers/gpio/Makefile
5909 @@ -12,6 +12,7 @@ LIB   := $(obj)libgpio.o
5910  COBJS-$(CONFIG_AT91_GPIO)      += at91_gpio.o
5911  COBJS-$(CONFIG_INTEL_ICH6_GPIO)        += intel_ich6_gpio.o
5912  COBJS-$(CONFIG_KIRKWOOD_GPIO)  += kw_gpio.o
5913 +COBJS-$(CONFIG_LANTIQ_GPIO)    += lantiq_gpio.o
5914  COBJS-$(CONFIG_MARVELL_GPIO)   += mvgpio.o
5915  COBJS-$(CONFIG_MARVELL_MFP)    += mvmfp.o
5916  COBJS-$(CONFIG_MXC_GPIO)       += mxc_gpio.o
5917 --- /dev/null
5918 +++ b/drivers/gpio/lantiq_gpio.c
5919 @@ -0,0 +1,329 @@
5920 +/*
5921 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
5922 + *
5923 + * SPDX-License-Identifier:    GPL-2.0+
5924 + */
5925 +
5926 +#include <common.h>
5927 +#include <asm/arch/soc.h>
5928 +#include <asm/arch/gpio.h>
5929 +#include <asm/lantiq/io.h>
5930 +
5931 +#define SSIO_GPIO_BASE         64
5932 +
5933 +#define SSIO_CON0_SWU          (1 << 31)
5934 +#define SSIO_CON0_RZFL         (1 << 26)
5935 +#define SSIO_CON0_GPHY1_SHIFT  27
5936 +#define SSIO_CON0_GPHY1_CONFIG ((CONFIG_LTQ_SSIO_GPHY1_MODE & 0x7) << 27)
5937 +
5938 +#define SSIO_CON1_US_FPI       (2 << 30)
5939 +#define SSIO_CON1_FPID_2HZ     (0 << 23)
5940 +#define SSIO_CON1_FPID_4HZ     (1 << 23)
5941 +#define SSIO_CON1_FPID_8HZ     (2 << 23)
5942 +#define SSIO_CON1_FPID_10HZ    (3 << 23)
5943 +#define SSIO_CON1_FPIS_1_2     (1 << 20)
5944 +#define SSIO_CON1_FPIS_1_32    (2 << 20)
5945 +#define SSIO_CON1_FPIS_1_64    (3 << 20)
5946 +
5947 +#define SSIO_CON1_GPHY2_SHIFT  15
5948 +#define SSIO_CON1_GPHY2_CONFIG ((CONFIG_LTQ_SSIO_GPHY2_MODE & 0x7) << 15)
5949 +
5950 +#define SSIO_CON1_GROUP2       (1 << 2)
5951 +#define SSIO_CON1_GROUP1       (1 << 1)
5952 +#define SSIO_CON1_GROUP0       (1 << 0)
5953 +#define SSIO_CON1_GROUP_CONFIG (0x3)
5954 +
5955 +#ifdef CONFIG_LTQ_SSIO_SHIFT_REGS
5956 +#define enable_ssio    1
5957 +#else
5958 +#define enable_ssio    0
5959 +
5960 +#define CONFIG_LTQ_SSIO_GPHY1_MODE     0
5961 +#define CONFIG_LTQ_SSIO_GPHY2_MODE     0
5962 +#define CONFIG_LTQ_SSIO_INIT_VALUE     0
5963 +#endif
5964 +
5965 +#ifdef CONFIG_LTQ_SSIO_EDGE_FALLING
5966 +#define SSIO_RZFL_CONFIG       SSIO_CON0_RZFL
5967 +#else
5968 +#define SSIO_RZFL_CONFIG       0
5969 +#endif
5970 +
5971 +struct ltq_gpio_port_regs {
5972 +       __be32  out;
5973 +       __be32  in;
5974 +       __be32  dir;
5975 +       __be32  altsel0;
5976 +       __be32  altsel1;
5977 +       __be32  od;
5978 +       __be32  stoff;
5979 +       __be32  pudsel;
5980 +       __be32  puden;
5981 +       __be32  rsvd1[3];
5982 +};
5983 +
5984 +struct ltq_gpio_regs {
5985 +       u32                             rsvd[4];
5986 +       struct ltq_gpio_port_regs       ports[CONFIG_LTQ_GPIO_MAX_BANKS];
5987 +};
5988 +
5989 +struct ltq_gpio3_regs {
5990 +       u32     rsvd0[13];
5991 +       __be32  od;
5992 +       __be32  pudsel;
5993 +       __be32  puden;
5994 +       u32     rsvd1[9];
5995 +       __be32  altsel1;
5996 +       u32     rsvd2[14];
5997 +       __be32  out;
5998 +       __be32  in;
5999 +       __be32  dir;
6000 +       __be32  altsel0;
6001 +};
6002 +
6003 +struct ltq_ssio_regs {
6004 +       __be32  con0;
6005 +       __be32  con1;
6006 +       __be32  cpu0;
6007 +       __be32  cpu1;
6008 +       __be32  ar;
6009 +};
6010 +
6011 +static struct ltq_gpio_regs *ltq_gpio_regs =
6012 +       (struct ltq_gpio_regs *) CKSEG1ADDR(LTQ_GPIO_BASE);
6013 +
6014 +static struct ltq_gpio3_regs *ltq_gpio3_regs =
6015 +       (struct ltq_gpio3_regs *) CKSEG1ADDR(LTQ_GPIO_BASE);
6016 +
6017 +static struct ltq_ssio_regs *ltq_ssio_regs =
6018 +       (struct ltq_ssio_regs *) CKSEG1ADDR(LTQ_SSIO_BASE);
6019 +
6020 +static int is_gpio_bank3(unsigned int port)
6021 +{
6022 +#ifdef CONFIG_LTQ_HAS_GPIO_BANK3
6023 +       return port == 3;
6024 +#else
6025 +       return 0;
6026 +#endif
6027 +}
6028 +
6029 +static int is_gpio_ssio(unsigned int gpio)
6030 +{
6031 +#ifdef CONFIG_LTQ_SSIO_SHIFT_REGS
6032 +       return gpio >= SSIO_GPIO_BASE;
6033 +#else
6034 +       return 0;
6035 +#endif
6036 +}
6037 +
6038 +static inline int ssio_gpio_to_bit(unsigned gpio)
6039 +{
6040 +       return 1 << (gpio - SSIO_GPIO_BASE);
6041 +}
6042 +
6043 +int ltq_gpio_init(void)
6044 +{
6045 +       ltq_writel(&ltq_ssio_regs->ar, 0);
6046 +       ltq_writel(&ltq_ssio_regs->cpu0, CONFIG_LTQ_SSIO_INIT_VALUE);
6047 +       ltq_writel(&ltq_ssio_regs->cpu1, 0);
6048 +       ltq_writel(&ltq_ssio_regs->con0, SSIO_CON0_SWU);
6049 +
6050 +       if (enable_ssio) {
6051 +               ltq_writel(&ltq_ssio_regs->con0, SSIO_CON0_GPHY1_CONFIG |
6052 +                       SSIO_RZFL_CONFIG);
6053 +               ltq_writel(&ltq_ssio_regs->con1, SSIO_CON1_US_FPI |
6054 +                       SSIO_CON1_FPID_8HZ | SSIO_CON1_GPHY2_CONFIG |
6055 +                       SSIO_CON1_GROUP_CONFIG);
6056 +       }
6057 +
6058 +       return 0;
6059 +}
6060 +
6061 +int gpio_request(unsigned gpio, const char *label)
6062 +{
6063 +       return 0;
6064 +}
6065 +
6066 +int gpio_free(unsigned gpio)
6067 +{
6068 +       return 0;
6069 +}
6070 +
6071 +int gpio_direction_input(unsigned gpio)
6072 +{
6073 +       unsigned port = gpio_to_port(gpio);
6074 +       const void *gpio_od = &ltq_gpio_regs->ports[port].od;
6075 +       const void *gpio_altsel0 = &ltq_gpio_regs->ports[port].altsel0;
6076 +       const void *gpio_altsel1 = &ltq_gpio_regs->ports[port].altsel1;
6077 +       const void *gpio_dir = &ltq_gpio_regs->ports[port].dir;
6078 +
6079 +       if (is_gpio_ssio(gpio))
6080 +               return 0;
6081 +
6082 +       if (is_gpio_bank3(port)) {
6083 +               gpio_od = &ltq_gpio3_regs->od;
6084 +               gpio_altsel0 = &ltq_gpio3_regs->altsel0;
6085 +               gpio_altsel1 = &ltq_gpio3_regs->altsel1;
6086 +               gpio_dir = &ltq_gpio3_regs->dir;
6087 +       }
6088 +
6089 +       /*
6090 +        * Reset open drain and altsel configs to workaround improper
6091 +        * reset values or unwanted modifications by BootROM
6092 +        */
6093 +       ltq_clrbits(gpio_od, gpio_to_bit(gpio));
6094 +       ltq_clrbits(gpio_altsel0, gpio_to_bit(gpio));
6095 +       ltq_clrbits(gpio_altsel1, gpio_to_bit(gpio));
6096 +
6097 +       /* Switch to input */
6098 +       ltq_clrbits(gpio_dir, gpio_to_bit(gpio));
6099 +
6100 +       return 0;
6101 +}
6102 +
6103 +int gpio_direction_output(unsigned gpio, int value)
6104 +{
6105 +       unsigned port = gpio_to_port(gpio);
6106 +       const void *gpio_od = &ltq_gpio_regs->ports[port].od;
6107 +       const void *gpio_altsel0 = &ltq_gpio_regs->ports[port].altsel0;
6108 +       const void *gpio_altsel1 = &ltq_gpio_regs->ports[port].altsel1;
6109 +       const void *gpio_dir = &ltq_gpio_regs->ports[port].dir;
6110 +       const void *gpio_out = &ltq_gpio_regs->ports[port].out;
6111 +       u32 data = gpio_to_bit(gpio);
6112 +
6113 +       if (is_gpio_ssio(gpio)) {
6114 +               data = ssio_gpio_to_bit(gpio);
6115 +               if (value)
6116 +                       ltq_setbits(&ltq_ssio_regs->cpu0, data);
6117 +               else
6118 +                       ltq_clrbits(&ltq_ssio_regs->cpu0, data);
6119 +
6120 +               return 0;
6121 +       }
6122 +
6123 +       if (is_gpio_bank3(port)) {
6124 +               gpio_od = &ltq_gpio3_regs->od;
6125 +               gpio_altsel0 = &ltq_gpio3_regs->altsel0;
6126 +               gpio_altsel1 = &ltq_gpio3_regs->altsel1;
6127 +               gpio_dir = &ltq_gpio3_regs->dir;
6128 +               gpio_out = &ltq_gpio3_regs->out;
6129 +       }
6130 +
6131 +       /*
6132 +        * Reset open drain and altsel configs to workaround improper
6133 +        * reset values or unwanted modifications by BootROM
6134 +        */
6135 +       ltq_setbits(gpio_od, data);
6136 +       ltq_clrbits(gpio_altsel0, data);
6137 +       ltq_clrbits(gpio_altsel1, data);
6138 +
6139 +       if (value)
6140 +               ltq_setbits(gpio_out, data);
6141 +       else
6142 +               ltq_clrbits(gpio_out, data);
6143 +
6144 +       /* Switch to output */
6145 +       ltq_setbits(gpio_dir, data);
6146 +
6147 +       return 0;
6148 +}
6149 +
6150 +int gpio_get_value(unsigned gpio)
6151 +{
6152 +       unsigned port = gpio_to_port(gpio);
6153 +       const void *gpio_in = &ltq_gpio_regs->ports[port].in;
6154 +       u32 data = gpio_to_bit(gpio);
6155 +       u32 val;
6156 +
6157 +       if (is_gpio_ssio(gpio)) {
6158 +               gpio_in = &ltq_ssio_regs->cpu0;
6159 +               data = ssio_gpio_to_bit(gpio);
6160 +       }
6161 +
6162 +       if (is_gpio_bank3(port))
6163 +               gpio_in = &ltq_gpio3_regs->in;
6164 +
6165 +       val = ltq_readl(gpio_in);
6166 +
6167 +       return !!(val & data);
6168 +}
6169 +
6170 +int gpio_set_value(unsigned gpio, int value)
6171 +{
6172 +       unsigned port = gpio_to_port(gpio);
6173 +       const void *gpio_out = &ltq_gpio_regs->ports[port].out;
6174 +       u32 data = gpio_to_bit(gpio);
6175 +
6176 +       if (is_gpio_ssio(gpio)) {
6177 +               gpio_out = &ltq_ssio_regs->cpu0;
6178 +               data = ssio_gpio_to_bit(gpio);
6179 +       }
6180 +
6181 +       if (is_gpio_bank3(port))
6182 +               gpio_out = &ltq_gpio3_regs->out;
6183 +
6184 +       if (value)
6185 +               ltq_setbits(gpio_out, data);
6186 +       else
6187 +               ltq_clrbits(gpio_out, data);
6188 +
6189 +       return 0;
6190 +}
6191 +
6192 +int gpio_set_altfunc(unsigned gpio, int altsel0, int altsel1, int dir)
6193 +{
6194 +       unsigned port = gpio_to_port(gpio);
6195 +       const void *gpio_od = &ltq_gpio_regs->ports[port].od;
6196 +       const void *gpio_altsel0 = &ltq_gpio_regs->ports[port].altsel0;
6197 +       const void *gpio_altsel1 = &ltq_gpio_regs->ports[port].altsel1;
6198 +       const void *gpio_dir = &ltq_gpio_regs->ports[port].dir;
6199 +
6200 +       if (is_gpio_ssio(gpio))
6201 +               return 0;
6202 +
6203 +       if (is_gpio_bank3(port)) {
6204 +               gpio_od = &ltq_gpio3_regs->od;
6205 +               gpio_altsel0 = &ltq_gpio3_regs->altsel0;
6206 +               gpio_altsel1 = &ltq_gpio3_regs->altsel1;
6207 +               gpio_dir = &ltq_gpio3_regs->dir;
6208 +       }
6209 +
6210 +       if (altsel0)
6211 +               ltq_setbits(gpio_altsel0, gpio_to_bit(gpio));
6212 +       else
6213 +               ltq_clrbits(gpio_altsel0, gpio_to_bit(gpio));
6214 +
6215 +       if (altsel1)
6216 +               ltq_setbits(gpio_altsel1, gpio_to_bit(gpio));
6217 +       else
6218 +               ltq_clrbits(gpio_altsel1, gpio_to_bit(gpio));
6219 +
6220 +       if (dir) {
6221 +               ltq_setbits(gpio_od, gpio_to_bit(gpio));
6222 +               ltq_setbits(gpio_dir, gpio_to_bit(gpio));
6223 +       } else {
6224 +               ltq_clrbits(gpio_od, gpio_to_bit(gpio));
6225 +               ltq_clrbits(gpio_dir, gpio_to_bit(gpio));
6226 +       }
6227 +
6228 +       return 0;
6229 +}
6230 +
6231 +int gpio_set_opendrain(unsigned gpio, int od)
6232 +{
6233 +       unsigned port = gpio_to_port(gpio);
6234 +       const void *gpio_od = &ltq_gpio_regs->ports[port].od;
6235 +
6236 +       if (is_gpio_ssio(gpio))
6237 +               return 0;
6238 +
6239 +       if (is_gpio_bank3(port))
6240 +               gpio_od = &ltq_gpio3_regs->od;
6241 +
6242 +       if (od)
6243 +               ltq_setbits(gpio_od, gpio_to_bit(gpio));
6244 +       else
6245 +               ltq_clrbits(gpio_od, gpio_to_bit(gpio));
6246 +
6247 +       return 0;
6248 +}
6249 --- a/drivers/mtd/cfi_flash.c
6250 +++ b/drivers/mtd/cfi_flash.c
6251 @@ -161,6 +161,18 @@ u64 flash_read64(void *addr)__attribute_
6252  #define flash_read64   __flash_read64
6253  #endif
6254  
6255 +static inline void *__flash_swap_addr(unsigned long addr)
6256 +{
6257 +       return (void *) addr;
6258 +}
6259 +
6260 +#ifdef CONFIG_CFI_FLASH_USE_WEAK_ADDR_SWAP
6261 +void *flash_swap_addr(unsigned long addr)
6262 +               __attribute__((weak, alias("__flash_swap_addr")));
6263 +#else
6264 +#define flash_swap_addr        __flash_swap_addr
6265 +#endif
6266 +
6267  /*-----------------------------------------------------------------------
6268   */
6269  #if defined(CONFIG_ENV_IS_IN_FLASH) || defined(CONFIG_ENV_ADDR_REDUND) || (CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE)
6270 @@ -196,7 +208,7 @@ flash_map (flash_info_t * info, flash_se
6271  {
6272         unsigned int byte_offset = offset * info->portwidth;
6273  
6274 -       return (void *)(info->start[sect] + byte_offset);
6275 +       return flash_swap_addr(info->start[sect] + byte_offset);
6276  }
6277  
6278  static inline void flash_unmap(flash_info_t *info, flash_sect_t sect,
6279 --- a/drivers/mtd/nand/Makefile
6280 +++ b/drivers/mtd/nand/Makefile
6281 @@ -53,6 +53,7 @@ COBJS-$(CONFIG_NAND_JZ4740) += jz4740_na
6282  COBJS-$(CONFIG_NAND_KB9202) += kb9202_nand.o
6283  COBJS-$(CONFIG_NAND_KIRKWOOD) += kirkwood_nand.o
6284  COBJS-$(CONFIG_NAND_KMETER1) += kmeter1_nand.o
6285 +COBJS-$(CONFIG_NAND_LANTIQ) += lantiq_nand.o
6286  COBJS-$(CONFIG_NAND_MPC5121_NFC) += mpc5121_nfc.o
6287  COBJS-$(CONFIG_NAND_MXC) += mxc_nand.o
6288  COBJS-$(CONFIG_NAND_MXS) += mxs_nand.o
6289 --- /dev/null
6290 +++ b/drivers/mtd/nand/lantiq_nand.c
6291 @@ -0,0 +1,126 @@
6292 +/*
6293 + * Copyright (C) 2012-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
6294 + *
6295 + * SPDX-License-Identifier:    GPL-2.0+
6296 + */
6297 +
6298 +#include <common.h>
6299 +#include <linux/mtd/nand.h>
6300 +#include <linux/compiler.h>
6301 +#include <asm/arch/soc.h>
6302 +#include <asm/arch/nand.h>
6303 +#include <asm/lantiq/io.h>
6304 +
6305 +#define NAND_CON_ECC_ON                (1 << 31)
6306 +#define NAND_CON_LATCH_PRE     (1 << 23)
6307 +#define NAND_CON_LATCH_WP      (1 << 22)
6308 +#define NAND_CON_LATCH_SE      (1 << 21)
6309 +#define NAND_CON_LATCH_CS      (1 << 20)
6310 +#define NAND_CON_LATCH_CLE     (1 << 19)
6311 +#define NAND_CON_LATCH_ALE     (1 << 18)
6312 +#define NAND_CON_OUT_CS1       (1 << 10)
6313 +#define NAND_CON_IN_CS1                (1 << 8)
6314 +#define NAND_CON_PRE_P         (1 << 7)
6315 +#define NAND_CON_WP_P          (1 << 6)
6316 +#define NAND_CON_SE_P          (1 << 5)
6317 +#define NAND_CON_CS_P          (1 << 4)
6318 +#define NAND_CON_CLE_P         (1 << 3)
6319 +#define NAND_CON_ALE_P         (1 << 2)
6320 +#define NAND_CON_CSMUX         (1 << 1)
6321 +#define NAND_CON_NANDM         (1 << 0)
6322 +
6323 +#define NAND_WAIT_WR_C         (1 << 3)
6324 +#define NAND_WAIT_RDBY         (1 << 0)
6325 +
6326 +#define NAND_CMD_ALE           (1 << 2)
6327 +#define NAND_CMD_CLE           (1 << 3)
6328 +#define NAND_CMD_CS            (1 << 4)
6329 +#define NAND_CMD_SE            (1 << 5)
6330 +#define NAND_CMD_WP            (1 << 6)
6331 +#define NAND_CMD_PRE           (1 << 7)
6332 +
6333 +struct ltq_nand_regs {
6334 +       __be32  con;            /* NAND controller control */
6335 +       __be32  wait;           /* NAND Flash Device RD/BY State */
6336 +       __be32  ecc0;           /* NAND Flash ECC Register 0 */
6337 +       __be32  ecc_ac;         /* NAND Flash ECC Register address counter */
6338 +       __be32  ecc_cr;         /* NAND Flash ECC Comparison */
6339 +};
6340 +
6341 +static struct ltq_nand_regs *ltq_nand_regs =
6342 +       (struct ltq_nand_regs *) CKSEG1ADDR(LTQ_EBU_NAND_BASE);
6343 +
6344 +static void ltq_nand_wait_ready(void)
6345 +{
6346 +       while ((ltq_readl(&ltq_nand_regs->wait) & NAND_WAIT_WR_C) == 0)
6347 +               ;
6348 +}
6349 +
6350 +static int ltq_nand_dev_ready(struct mtd_info *mtd)
6351 +{
6352 +       u32 data = ltq_readl(&ltq_nand_regs->wait);
6353 +       return data & NAND_WAIT_RDBY;
6354 +}
6355 +
6356 +static void ltq_nand_select_chip(struct mtd_info *mtd, int chip)
6357 +{
6358 +       if (chip == 0) {
6359 +               ltq_setbits(&ltq_nand_regs->con, NAND_CON_NANDM);
6360 +               ltq_setbits(&ltq_nand_regs->con, NAND_CON_LATCH_CS);
6361 +       } else {
6362 +               ltq_clrbits(&ltq_nand_regs->con, NAND_CON_LATCH_CS);
6363 +               ltq_clrbits(&ltq_nand_regs->con, NAND_CON_NANDM);
6364 +       }
6365 +}
6366 +
6367 +static void ltq_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
6368 +{
6369 +       struct nand_chip *chip = mtd->priv;
6370 +       unsigned long addr = (unsigned long) chip->IO_ADDR_W;
6371 +
6372 +       if (ctrl & NAND_CTRL_CHANGE) {
6373 +               if (ctrl & NAND_ALE)
6374 +                       addr |= NAND_CMD_ALE;
6375 +               else
6376 +                       addr &= ~NAND_CMD_ALE;
6377 +
6378 +               if (ctrl & NAND_CLE)
6379 +                       addr |= NAND_CMD_CLE;
6380 +               else
6381 +                       addr &= ~NAND_CMD_CLE;
6382 +
6383 +               chip->IO_ADDR_W = (void __iomem *) addr;
6384 +       }
6385 +
6386 +       if (cmd != NAND_CMD_NONE) {
6387 +               writeb(cmd, chip->IO_ADDR_W);
6388 +               ltq_nand_wait_ready();
6389 +       }
6390 +}
6391 +
6392 +int ltq_nand_init(struct nand_chip *nand)
6393 +{
6394 +       /* Enable NAND, set NAND CS to EBU CS1, enable EBU CS mux */
6395 +       ltq_writel(&ltq_nand_regs->con, NAND_CON_OUT_CS1 | NAND_CON_IN_CS1 |
6396 +               NAND_CON_PRE_P | NAND_CON_WP_P | NAND_CON_SE_P |
6397 +               NAND_CON_CS_P | NAND_CON_CSMUX);
6398 +
6399 +       nand->dev_ready = ltq_nand_dev_ready;
6400 +       nand->select_chip = ltq_nand_select_chip;
6401 +       nand->cmd_ctrl = ltq_nand_cmd_ctrl;
6402 +
6403 +       nand->chip_delay = 30;
6404 +       nand->options = 0;
6405 +       nand->ecc.mode = NAND_ECC_SOFT;
6406 +
6407 +       /* Enable CS bit in address offset */
6408 +       nand->IO_ADDR_R = nand->IO_ADDR_R + NAND_CMD_CS;
6409 +       nand->IO_ADDR_W = nand->IO_ADDR_W + NAND_CMD_CS;
6410 +
6411 +       return 0;
6412 +}
6413 +
6414 +__weak int board_nand_init(struct nand_chip *chip)
6415 +{
6416 +       return ltq_nand_init(chip);
6417 +}
6418 --- a/drivers/net/Makefile
6419 +++ b/drivers/net/Makefile
6420 @@ -37,6 +37,8 @@ COBJS-$(CONFIG_INCA_IP_SWITCH) += inca-i
6421  COBJS-$(CONFIG_DRIVER_KS8695ETH) += ks8695eth.o
6422  COBJS-$(CONFIG_KS8851_MLL) += ks8851_mll.o
6423  COBJS-$(CONFIG_LAN91C96) += lan91c96.o
6424 +COBJS-$(CONFIG_LANTIQ_DANUBE_ETOP) += lantiq_danube_etop.o
6425 +COBJS-$(CONFIG_LANTIQ_VRX200_SWITCH) += lantiq_vrx200_switch.o
6426  COBJS-$(CONFIG_MACB) += macb.o
6427  COBJS-$(CONFIG_MCFFEC) += mcffec.o mcfmii.o
6428  COBJS-$(CONFIG_MPC5xxx_FEC) += mpc5xxx_fec.o
6429 --- /dev/null
6430 +++ b/drivers/net/lantiq_danube_etop.c
6431 @@ -0,0 +1,410 @@
6432 +/*
6433 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
6434 + *
6435 + * SPDX-License-Identifier:    GPL-2.0+
6436 + */
6437 +
6438 +#include <common.h>
6439 +#include <malloc.h>
6440 +#include <netdev.h>
6441 +#include <miiphy.h>
6442 +#include <switch.h>
6443 +#include <asm/lantiq/io.h>
6444 +#include <asm/lantiq/eth.h>
6445 +#include <asm/lantiq/pm.h>
6446 +#include <asm/lantiq/reset.h>
6447 +#include <asm/lantiq/dma.h>
6448 +#include <asm/arch/soc.h>
6449 +
6450 +#define LTQ_PPE_ETOP_MDIO_ACC_RA       (1 << 31)
6451 +#define LTQ_PPE_ETOP_MDIO_CFG_UMM1     (1 << 2)
6452 +#define LTQ_PPE_ETOP_MDIO_CFG_UMM0     (1 << 1)
6453 +
6454 +#define LTQ_PPE_ETOP_CFG_TCKINV1       (1 << 11)
6455 +#define LTQ_PPE_ETOP_CFG_TCKINV0       (1 << 10)
6456 +#define LTQ_PPE_ETOP_CFG_FEN1          (1 << 9)
6457 +#define LTQ_PPE_ETOP_CFG_FEN0          (1 << 8)
6458 +#define LTQ_PPE_ETOP_CFG_SEN1          (1 << 7)
6459 +#define LTQ_PPE_ETOP_CFG_SEN0          (1 << 6)
6460 +#define LTQ_PPE_ETOP_CFG_TURBO1                (1 << 5)
6461 +#define LTQ_PPE_ETOP_CFG_REMII1                (1 << 4)
6462 +#define LTQ_PPE_ETOP_CFG_OFF1          (1 << 3)
6463 +#define LTQ_PPE_ETOP_CFG_TURBO0                (1 << 2)
6464 +#define LTQ_PPE_ETOP_CFG_REMII0                (1 << 1)
6465 +#define LTQ_PPE_ETOP_CFG_OFF0          (1 << 0)
6466 +
6467 +#define LTQ_PPE_ENET0_MAC_CFG_CGEN     (1 << 11)
6468 +#define LTQ_PPE_ENET0_MAC_CFG_DUPLEX   (1 << 2)
6469 +#define LTQ_PPE_ENET0_MAC_CFG_SPEED    (1 << 1)
6470 +#define LTQ_PPE_ENET0_MAC_CFG_LINK     (1 << 0)
6471 +
6472 +#define LTQ_PPE_ENETS0_CFG_FTUC                (1 << 28)
6473 +
6474 +#define LTQ_ETH_RX_BUFFER_CNT          PKTBUFSRX
6475 +#define LTQ_ETH_TX_BUFFER_CNT          8
6476 +#define LTQ_ETH_RX_DATA_SIZE           PKTSIZE_ALIGN
6477 +#define LTQ_ETH_IP_ALIGN               2
6478 +
6479 +#define LTQ_MDIO_DRV_NAME              "ltq-mdio"
6480 +#define LTQ_ETH_DRV_NAME               "ltq-eth"
6481 +
6482 +struct ltq_ppe_etop_regs {
6483 +       u32     mdio_cfg;               /* MDIO configuration */
6484 +       u32     mdio_acc;               /* MDIO access */
6485 +       u32     cfg;                    /* ETOP configuration */
6486 +       u32     ig_vlan_cos;            /* IG VLAN priority CoS mapping */
6487 +       u32     ig_dscp_cos3;           /* IG DSCP CoS mapping 3 */
6488 +       u32     ig_dscp_cos2;           /* IG DSCP CoS mapping 2 */
6489 +       u32     ig_dscp_cos1;           /* IG DSCP CoS mapping 1 */
6490 +       u32     ig_dscp_cos0;           /* IG DSCP CoS mapping 0 */
6491 +       u32     ig_plen_ctrl;           /* IG frame length control */
6492 +       u32     rsvd0[3];
6493 +       u32     vpid;                   /* VLAN protocol ID */
6494 +};
6495 +
6496 +struct ltq_ppe_enet_regs {
6497 +       u32     mac_cfg;                /* MAC configuration */
6498 +       u32     rsvd0[3];
6499 +       u32     ig_cfg;                 /* Ingress configuration */
6500 +       u32     ig_pgcnt;               /* Ingress buffer used page count */
6501 +       u32     rsvd1;
6502 +       u32     ig_buf_ctrl;            /* Ingress buffer backpressure ctrl */
6503 +       u32     cos_cfg;                /* Classification configuration */
6504 +       u32     ig_drop;                /* Total ingress drop frames */
6505 +       u32     ig_err;                 /* Total ingress error frames */
6506 +       u32     mac_da0;                /* Ingress MAC address 0 */
6507 +       u32     mac_da1;                /* Ingress MAC address 1 */
6508 +       u32     rsvd2[22];
6509 +       u32     pgcnt;                  /* Page counter */
6510 +       u32     rsvd3;
6511 +       u32     hf_ctrl;                /* Half duplex control */
6512 +       u32     tx_ctrl;                /* Transmit control */
6513 +       u32     rsvd4;
6514 +       u32     vlcos0;                 /* VLAN insertion config CoS 0 */
6515 +       u32     vlcos1;                 /* VLAN insertion config CoS 1 */
6516 +       u32     vlcos2;                 /* VLAN insertion config CoS 2 */
6517 +       u32     vlcos3;                 /* VLAN insertion config CoS 3 */
6518 +       u32     eg_col;                 /* Total egress collision frames */
6519 +       u32     eg_drop;                /* Total egress drop frames */
6520 +};
6521 +
6522 +struct ltq_eth_priv {
6523 +       struct ltq_dma_device dma_dev;
6524 +       struct mii_dev *bus;
6525 +       struct eth_device *dev;
6526 +       int rx_num;
6527 +       int tx_num;
6528 +};
6529 +
6530 +struct ltq_mdio_access {
6531 +       union {
6532 +               struct {
6533 +                       unsigned ra:1;
6534 +                       unsigned rw:1;
6535 +                       unsigned rsvd:4;
6536 +                       unsigned phya:5;
6537 +                       unsigned rega:5;
6538 +                       unsigned phyd:16;
6539 +               } reg;
6540 +               u32 val;
6541 +       };
6542 +};
6543 +
6544 +static struct ltq_ppe_etop_regs *ltq_ppe_etop_regs =
6545 +       (struct ltq_ppe_etop_regs *) CKSEG1ADDR(LTQ_PPE_ETOP_BASE);
6546 +
6547 +static struct ltq_ppe_enet_regs *ltq_ppe_enet0_regs =
6548 +       (struct ltq_ppe_enet_regs *) CKSEG1ADDR(LTQ_PPE_ENET0_BASE);
6549 +
6550 +static inline int ltq_mdio_poll(void)
6551 +{
6552 +       struct ltq_mdio_access acc;
6553 +       unsigned cnt = 10000;
6554 +
6555 +       while (likely(cnt--)) {
6556 +               acc.val = ltq_readl(&ltq_ppe_etop_regs->mdio_acc);
6557 +               if (!acc.reg.ra)
6558 +                       return 0;
6559 +       }
6560 +
6561 +       return 1;
6562 +}
6563 +
6564 +static int ltq_mdio_read(struct mii_dev *bus, int addr, int dev_addr,
6565 +                               int regnum)
6566 +{
6567 +       struct ltq_mdio_access acc;
6568 +       int ret;
6569 +
6570 +       acc.val = 0;
6571 +       acc.reg.ra = 1;
6572 +       acc.reg.rw = 1;
6573 +       acc.reg.phya = addr;
6574 +       acc.reg.rega = regnum;
6575 +
6576 +       ret = ltq_mdio_poll();
6577 +       if (ret)
6578 +               return ret;
6579 +
6580 +       ltq_writel(&ltq_ppe_etop_regs->mdio_acc, acc.val);
6581 +
6582 +       ret = ltq_mdio_poll();
6583 +       if (ret)
6584 +               return ret;
6585 +
6586 +       acc.val = ltq_readl(&ltq_ppe_etop_regs->mdio_acc);
6587 +
6588 +       return acc.reg.phyd;
6589 +}
6590 +
6591 +static int ltq_mdio_write(struct mii_dev *bus, int addr, int dev_addr,
6592 +                               int regnum, u16 val)
6593 +{
6594 +       struct ltq_mdio_access acc;
6595 +       int ret;
6596 +
6597 +       acc.val = 0;
6598 +       acc.reg.ra = 1;
6599 +       acc.reg.rw = 0;
6600 +       acc.reg.phya = addr;
6601 +       acc.reg.rega = regnum;
6602 +       acc.reg.phyd = val;
6603 +
6604 +       ret = ltq_mdio_poll();
6605 +       if (ret)
6606 +               return ret;
6607 +
6608 +       ltq_writel(&ltq_ppe_etop_regs->mdio_acc, acc.val);
6609 +
6610 +       return 0;
6611 +}
6612 +
6613 +static inline void ltq_eth_write_hwaddr(const struct eth_device *dev)
6614 +{
6615 +       u32 da0, da1;
6616 +
6617 +       da0 = (dev->enetaddr[0] << 24) + (dev->enetaddr[1] << 16) +
6618 +               (dev->enetaddr[2] << 8) + dev->enetaddr[3];
6619 +       da1 = (dev->enetaddr[4] << 24) + (dev->enetaddr[5] << 16);
6620 +
6621 +       ltq_writel(&ltq_ppe_enet0_regs->mac_da0, da0);
6622 +       ltq_writel(&ltq_ppe_enet0_regs->mac_da1, da1);
6623 +}
6624 +
6625 +static inline u8 *ltq_eth_rx_packet_align(int rx_num)
6626 +{
6627 +       u8 *packet = (u8 *) NetRxPackets[rx_num];
6628 +
6629 +       /*
6630 +        * IP header needs
6631 +        */
6632 +       return packet + LTQ_ETH_IP_ALIGN;
6633 +}
6634 +
6635 +static int ltq_eth_init(struct eth_device *dev, bd_t *bis)
6636 +{
6637 +       struct ltq_eth_priv *priv = dev->priv;
6638 +       struct ltq_dma_device *dma_dev = &priv->dma_dev;
6639 +       int i;
6640 +
6641 +       ltq_eth_write_hwaddr(dev);
6642 +
6643 +       for (i = 0; i < LTQ_ETH_RX_BUFFER_CNT; i++)
6644 +               ltq_dma_rx_map(dma_dev, i, ltq_eth_rx_packet_align(i),
6645 +                       LTQ_ETH_RX_DATA_SIZE);
6646 +
6647 +       ltq_dma_enable(dma_dev);
6648 +
6649 +       priv->rx_num = 0;
6650 +       priv->tx_num = 0;
6651 +
6652 +       return 0;
6653 +}
6654 +
6655 +static void ltq_eth_halt(struct eth_device *dev)
6656 +{
6657 +       struct ltq_eth_priv *priv = dev->priv;
6658 +       struct ltq_dma_device *dma_dev = &priv->dma_dev;
6659 +
6660 +       ltq_dma_reset(dma_dev);
6661 +}
6662 +
6663 +static int ltq_eth_send(struct eth_device *dev, void *packet, int length)
6664 +{
6665 +       struct ltq_eth_priv *priv = dev->priv;
6666 +       struct ltq_dma_device *dma_dev = &priv->dma_dev;
6667 +       int err;
6668 +
6669 +       /* Minimum payload length w/ CRC is 60 bytes */
6670 +       if (length < 60)
6671 +               length = 60;
6672 +
6673 +       err = ltq_dma_tx_map(dma_dev, priv->tx_num, packet, length, 10);
6674 +       if (err) {
6675 +               puts("NET: timeout on waiting for TX descriptor\n");
6676 +               return -1;
6677 +       }
6678 +
6679 +       priv->tx_num = (priv->tx_num + 1) % LTQ_ETH_TX_BUFFER_CNT;
6680 +
6681 +       return err;
6682 +}
6683 +
6684 +static int ltq_eth_recv(struct eth_device *dev)
6685 +{
6686 +       struct ltq_eth_priv *priv = dev->priv;
6687 +       struct ltq_dma_device *dma_dev = &priv->dma_dev;
6688 +       u8 *packet;
6689 +       int len;
6690 +
6691 +       if (!ltq_dma_rx_poll(dma_dev, priv->rx_num))
6692 +               return 0;
6693 +
6694 +#if 0
6695 +       printf("%s: rx_num %d\n", __func__, priv->rx_num);
6696 +#endif
6697 +
6698 +       len = ltq_dma_rx_length(dma_dev, priv->rx_num);
6699 +       packet = ltq_eth_rx_packet_align(priv->rx_num);
6700 +
6701 +#if 0
6702 +       printf("%s: received: packet %p, len %u, rx_num %d\n",
6703 +               __func__, packet, len, priv->rx_num);
6704 +#endif
6705 +
6706 +       if (len)
6707 +               NetReceive(packet, len);
6708 +
6709 +       ltq_dma_rx_map(dma_dev, priv->rx_num, packet,
6710 +               LTQ_ETH_RX_DATA_SIZE);
6711 +
6712 +       priv->rx_num = (priv->rx_num + 1) % LTQ_ETH_RX_BUFFER_CNT;
6713 +
6714 +       return 0;
6715 +}
6716 +
6717 +static void ltq_eth_hw_init(const struct ltq_eth_port_config *port)
6718 +{
6719 +       u32 data;
6720 +
6721 +       /* Power up ethernet subsystems */
6722 +       ltq_pm_enable(LTQ_PM_ETH);
6723 +
6724 +       /* Reset ethernet subsystems */
6725 +       ltq_reset_once(LTQ_RESET_ETH, 1);
6726 +
6727 +       /* Disable MDIO auto-detection */
6728 +       ltq_clrbits(&ltq_ppe_etop_regs->mdio_cfg, LTQ_PPE_ETOP_MDIO_CFG_UMM1 |
6729 +                       LTQ_PPE_ETOP_MDIO_CFG_UMM0);
6730 +
6731 +       /* Enable CRC generation, Full Duplex, 100Mbps, Link up */
6732 +       ltq_writel(&ltq_ppe_enet0_regs->mac_cfg, LTQ_PPE_ENET0_MAC_CFG_CGEN |
6733 +                       LTQ_PPE_ENET0_MAC_CFG_DUPLEX |
6734 +                       LTQ_PPE_ENET0_MAC_CFG_SPEED |
6735 +                       LTQ_PPE_ENET0_MAC_CFG_LINK);
6736 +
6737 +       /* Reset ETOP cfg and disable all */
6738 +       data = LTQ_PPE_ETOP_CFG_OFF0 | LTQ_PPE_ETOP_CFG_OFF1;
6739 +
6740 +       /* Enable ENET0, enable store and fetch */
6741 +       data &= ~LTQ_PPE_ETOP_CFG_OFF0;
6742 +       data |= LTQ_PPE_ETOP_CFG_SEN0 | LTQ_PPE_ETOP_CFG_FEN0;
6743 +
6744 +       if (port->phy_if == PHY_INTERFACE_MODE_RMII)
6745 +               data |= LTQ_PPE_ETOP_CFG_REMII0;
6746 +       else
6747 +               data &= ~LTQ_PPE_ETOP_CFG_REMII0;
6748 +
6749 +       ltq_writel(&ltq_ppe_etop_regs->cfg, data);
6750 +
6751 +       /* Set allowed packet length from 64 bytes to 1518 bytes */
6752 +       ltq_writel(&ltq_ppe_etop_regs->ig_plen_ctrl, (64 << 16) | 1518);
6753 +
6754 +       /* Enable filter for unicast packets */
6755 +       ltq_setbits(&ltq_ppe_enet0_regs->ig_cfg, LTQ_PPE_ENETS0_CFG_FTUC);
6756 +}
6757 +
6758 +int ltq_eth_initialize(const struct ltq_eth_board_config *board_config)
6759 +{
6760 +       struct eth_device *dev;
6761 +       struct mii_dev *bus;
6762 +       struct ltq_eth_priv *priv;
6763 +       struct ltq_dma_device *dma_dev;
6764 +       const struct ltq_eth_port_config *port = &board_config->ports[0];
6765 +       struct phy_device *phy;
6766 +       struct switch_device *sw;
6767 +       int ret;
6768 +
6769 +       ltq_dma_init();
6770 +       ltq_eth_hw_init(port);
6771 +
6772 +       dev = calloc(1, sizeof(*dev));
6773 +       if (!dev)
6774 +               return -1;
6775 +
6776 +       priv = calloc(1, sizeof(*priv));
6777 +       if (!priv)
6778 +               return -1;
6779 +
6780 +       bus = mdio_alloc();
6781 +       if (!bus)
6782 +               return -1;
6783 +
6784 +       sprintf(dev->name, LTQ_ETH_DRV_NAME);
6785 +       dev->priv = priv;
6786 +       dev->init = ltq_eth_init;
6787 +       dev->halt = ltq_eth_halt;
6788 +       dev->recv = ltq_eth_recv;
6789 +       dev->send = ltq_eth_send;
6790 +
6791 +       sprintf(bus->name, LTQ_MDIO_DRV_NAME);
6792 +       bus->read = ltq_mdio_read;
6793 +       bus->write = ltq_mdio_write;
6794 +       bus->priv = priv;
6795 +
6796 +       dma_dev = &priv->dma_dev;
6797 +       dma_dev->port = 0;
6798 +       dma_dev->rx_chan.chan_no = 6;
6799 +       dma_dev->rx_chan.class = 3;
6800 +       dma_dev->rx_chan.num_desc = LTQ_ETH_RX_BUFFER_CNT;
6801 +       dma_dev->rx_endian_swap = LTQ_DMA_ENDIANESS_B3_B2_B1_B0;
6802 +       dma_dev->rx_burst_len = LTQ_DMA_BURST_2WORDS;
6803 +       dma_dev->tx_chan.chan_no = 7;
6804 +       dma_dev->tx_chan.class = 3;
6805 +       dma_dev->tx_chan.num_desc = LTQ_ETH_TX_BUFFER_CNT;
6806 +       dma_dev->tx_endian_swap = LTQ_DMA_ENDIANESS_B3_B2_B1_B0;
6807 +       dma_dev->tx_burst_len = LTQ_DMA_BURST_2WORDS;
6808 +
6809 +       priv->bus = bus;
6810 +       priv->dev = dev;
6811 +
6812 +       ret = ltq_dma_register(dma_dev);
6813 +       if (ret)
6814 +               return ret;
6815 +
6816 +       ret = mdio_register(bus);
6817 +       if (ret)
6818 +               return ret;
6819 +
6820 +       ret = eth_register(dev);
6821 +       if (ret)
6822 +               return ret;
6823 +
6824 +       if (port->flags & LTQ_ETH_PORT_SWITCH) {
6825 +               sw = switch_connect(bus);
6826 +               if (!sw)
6827 +                       return -1;
6828 +
6829 +               switch_setup(sw);
6830 +       }
6831 +
6832 +       if (port->flags & LTQ_ETH_PORT_PHY) {
6833 +               phy = phy_connect(bus, port->phy_addr, dev, port->phy_if);
6834 +               if (!phy)
6835 +                       return -1;
6836 +
6837 +               phy_config(phy);
6838 +       }
6839 +
6840 +       return 0;
6841 +}
6842 --- /dev/null
6843 +++ b/drivers/net/lantiq_vrx200_switch.c
6844 @@ -0,0 +1,675 @@
6845 +/*
6846 + * Copyright (C) 2010-2011 Lantiq Deutschland GmbH
6847 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
6848 + *
6849 + * SPDX-License-Identifier:    GPL-2.0+
6850 + */
6851 +
6852 +#define DEBUG
6853 +
6854 +#include <common.h>
6855 +#include <malloc.h>
6856 +#include <netdev.h>
6857 +#include <miiphy.h>
6858 +#include <linux/compiler.h>
6859 +#include <asm/gpio.h>
6860 +#include <asm/processor.h>
6861 +#include <asm/lantiq/io.h>
6862 +#include <asm/lantiq/eth.h>
6863 +#include <asm/lantiq/pm.h>
6864 +#include <asm/lantiq/reset.h>
6865 +#include <asm/lantiq/dma.h>
6866 +#include <asm/arch/soc.h>
6867 +#include <asm/arch/switch.h>
6868 +
6869 +#define LTQ_ETH_RX_BUFFER_CNT          PKTBUFSRX
6870 +#define LTQ_ETH_TX_BUFFER_CNT          8
6871 +#define LTQ_ETH_RX_DATA_SIZE           PKTSIZE_ALIGN
6872 +#define LTQ_ETH_IP_ALIGN               2
6873 +
6874 +#define LTQ_MDIO_DRV_NAME              "ltq-mdio"
6875 +#define LTQ_ETH_DRV_NAME               "ltq-eth"
6876 +
6877 +#define LTQ_ETHSW_MAX_GMAC             6
6878 +#define LTQ_ETHSW_PMAC                 6
6879 +
6880 +struct ltq_mdio_phy_addr_reg {
6881 +       union {
6882 +               struct {
6883 +                       unsigned rsvd:1;
6884 +                       unsigned lnkst:2;       /* Link status control */
6885 +                       unsigned speed:2;       /* Speed control */
6886 +                       unsigned fdup:2;        /* Full duplex control */
6887 +                       unsigned fcontx:2;      /* Flow control mode TX */
6888 +                       unsigned fconrx:2;      /* Flow control mode RX */
6889 +                       unsigned addr:5;        /* PHY address */
6890 +               } bits;
6891 +               u16 val;
6892 +       };
6893 +};
6894 +
6895 +enum ltq_mdio_phy_addr_lnkst {
6896 +       LTQ_MDIO_PHY_ADDR_LNKST_AUTO = 0,
6897 +       LTQ_MDIO_PHY_ADDR_LNKST_UP = 1,
6898 +       LTQ_MDIO_PHY_ADDR_LNKST_DOWN = 2,
6899 +};
6900 +
6901 +enum ltq_mdio_phy_addr_speed {
6902 +       LTQ_MDIO_PHY_ADDR_SPEED_M10 = 0,
6903 +       LTQ_MDIO_PHY_ADDR_SPEED_M100 = 1,
6904 +       LTQ_MDIO_PHY_ADDR_SPEED_G1 = 2,
6905 +       LTQ_MDIO_PHY_ADDR_SPEED_AUTO = 3,
6906 +};
6907 +
6908 +enum ltq_mdio_phy_addr_fdup {
6909 +       LTQ_MDIO_PHY_ADDR_FDUP_AUTO = 0,
6910 +       LTQ_MDIO_PHY_ADDR_FDUP_ENABLE = 1,
6911 +       LTQ_MDIO_PHY_ADDR_FDUP_DISABLE = 3,
6912 +};
6913 +
6914 +enum ltq_mdio_phy_addr_fcon {
6915 +       LTQ_MDIO_PHY_ADDR_FCON_AUTO = 0,
6916 +       LTQ_MDIO_PHY_ADDR_FCON_ENABLE = 1,
6917 +       LTQ_MDIO_PHY_ADDR_FCON_DISABLE = 3,
6918 +};
6919 +
6920 +struct ltq_mii_mii_cfg_reg {
6921 +       union {
6922 +               struct {
6923 +                       unsigned res:1;         /* Hardware reset */
6924 +                       unsigned en:1;          /* xMII interface enable */
6925 +                       unsigned isol:1;        /* xMII interface isolate */
6926 +                       unsigned ldclkdis:1;    /* Link down clock disable */
6927 +                       unsigned rsvd:1;
6928 +                       unsigned crs:2;         /* CRS sensitivity config */
6929 +                       unsigned rgmii_ibs:1;   /* RGMII In Band status */
6930 +                       unsigned rmii:1;        /* RMII ref clock direction */
6931 +                       unsigned miirate:3;     /* xMII interface clock rate */
6932 +                       unsigned miimode:4;     /* xMII interface mode */
6933 +               } bits;
6934 +               u16 val;
6935 +       };
6936 +};
6937 +
6938 +enum ltq_mii_mii_cfg_miirate {
6939 +       LTQ_MII_MII_CFG_MIIRATE_M2P5 = 0,
6940 +       LTQ_MII_MII_CFG_MIIRATE_M25 = 1,
6941 +       LTQ_MII_MII_CFG_MIIRATE_M125 = 2,
6942 +       LTQ_MII_MII_CFG_MIIRATE_M50 = 3,
6943 +       LTQ_MII_MII_CFG_MIIRATE_AUTO = 4,
6944 +};
6945 +
6946 +enum ltq_mii_mii_cfg_miimode {
6947 +       LTQ_MII_MII_CFG_MIIMODE_MIIP = 0,
6948 +       LTQ_MII_MII_CFG_MIIMODE_MIIM = 1,
6949 +       LTQ_MII_MII_CFG_MIIMODE_RMIIP = 2,
6950 +       LTQ_MII_MII_CFG_MIIMODE_RMIIM = 3,
6951 +       LTQ_MII_MII_CFG_MIIMODE_RGMII = 4,
6952 +};
6953 +
6954 +struct ltq_eth_priv {
6955 +       struct ltq_dma_device dma_dev;
6956 +       struct mii_dev *bus;
6957 +       struct eth_device *dev;
6958 +       struct phy_device *phymap[LTQ_ETHSW_MAX_GMAC];
6959 +       int rx_num;
6960 +       int tx_num;
6961 +};
6962 +
6963 +static struct vr9_switch_regs *switch_regs =
6964 +       (struct vr9_switch_regs *) CKSEG1ADDR(LTQ_SWITCH_BASE);
6965 +
6966 +static inline void vr9_switch_sync(void)
6967 +{
6968 +       __asm__("sync");
6969 +}
6970 +
6971 +static inline int vr9_switch_mdio_is_busy(void)
6972 +{
6973 +       u32 mdio_ctrl = ltq_readl(&switch_regs->mdio.mdio_ctrl);
6974 +
6975 +       return mdio_ctrl & MDIO_CTRL_MBUSY;
6976 +}
6977 +
6978 +static inline void vr9_switch_mdio_poll(void)
6979 +{
6980 +       while (vr9_switch_mdio_is_busy())
6981 +               cpu_relax();
6982 +}
6983 +
6984 +static int vr9_switch_mdio_read(struct mii_dev *bus, int phyad, int devad,
6985 +                                       int regad)
6986 +{
6987 +       u32 mdio_ctrl;
6988 +       int retval;
6989 +
6990 +       mdio_ctrl = MDIO_CTRL_OP_READ |
6991 +               ((phyad << MDIO_CTRL_PHYAD_SHIFT) & MDIO_CTRL_PHYAD_MASK) |
6992 +               (regad & MDIO_CTRL_REGAD_MASK);
6993 +
6994 +       vr9_switch_mdio_poll();
6995 +       ltq_writel(&switch_regs->mdio.mdio_ctrl, mdio_ctrl);
6996 +       vr9_switch_mdio_poll();
6997 +       retval = ltq_readl(&switch_regs->mdio.mdio_read);
6998 +
6999 +       return retval;
7000 +}
7001 +
7002 +static int vr9_switch_mdio_write(struct mii_dev *bus, int phyad, int devad,
7003 +                                       int regad, u16 val)
7004 +{
7005 +       u32 mdio_ctrl;
7006 +
7007 +       mdio_ctrl = MDIO_CTRL_OP_WRITE |
7008 +               ((phyad << MDIO_CTRL_PHYAD_SHIFT) & MDIO_CTRL_PHYAD_MASK) |
7009 +               (regad & MDIO_CTRL_REGAD_MASK);
7010 +
7011 +       vr9_switch_mdio_poll();
7012 +       ltq_writel(&switch_regs->mdio.mdio_write, val);
7013 +       ltq_writel(&switch_regs->mdio.mdio_ctrl, mdio_ctrl);
7014 +
7015 +       return 0;
7016 +}
7017 +
7018 +static void ltq_eth_gmac_update(struct phy_device *phydev, int num)
7019 +{
7020 +       struct ltq_mdio_phy_addr_reg phy_addr_reg;
7021 +       struct ltq_mii_mii_cfg_reg mii_cfg_reg;
7022 +
7023 +       phy_addr_reg.val = ltq_readl(to_mdio_phyaddr(switch_regs, num));
7024 +
7025 +       switch (num) {
7026 +       case 0:
7027 +       case 1:
7028 +       case 5:
7029 +               mii_cfg_reg.val = ltq_readl(to_mii_miicfg(switch_regs, num));
7030 +               break;
7031 +       default:
7032 +               mii_cfg_reg.val = 0;
7033 +               break;
7034 +       }
7035 +
7036 +       phy_addr_reg.bits.addr = phydev->addr;
7037 +
7038 +       if (phydev->link)
7039 +               phy_addr_reg.bits.lnkst = LTQ_MDIO_PHY_ADDR_LNKST_UP;
7040 +       else
7041 +               phy_addr_reg.bits.lnkst = LTQ_MDIO_PHY_ADDR_LNKST_DOWN;
7042 +
7043 +       switch (phydev->speed) {
7044 +       case SPEED_1000:
7045 +               phy_addr_reg.bits.speed = LTQ_MDIO_PHY_ADDR_SPEED_G1;
7046 +               mii_cfg_reg.bits.miirate = LTQ_MII_MII_CFG_MIIRATE_M125;
7047 +               break;
7048 +       case SPEED_100:
7049 +               phy_addr_reg.bits.speed = LTQ_MDIO_PHY_ADDR_SPEED_M100;
7050 +               switch (mii_cfg_reg.bits.miimode) {
7051 +               case LTQ_MII_MII_CFG_MIIMODE_RMIIM:
7052 +               case LTQ_MII_MII_CFG_MIIMODE_RMIIP:
7053 +                       mii_cfg_reg.bits.miirate = LTQ_MII_MII_CFG_MIIRATE_M50;
7054 +                       break;
7055 +               default:
7056 +                       mii_cfg_reg.bits.miirate = LTQ_MII_MII_CFG_MIIRATE_M25;
7057 +                       break;
7058 +               }
7059 +               break;
7060 +       default:
7061 +               phy_addr_reg.bits.speed = LTQ_MDIO_PHY_ADDR_SPEED_M10;
7062 +               mii_cfg_reg.bits.miirate = LTQ_MII_MII_CFG_MIIRATE_M2P5;
7063 +               break;
7064 +       }
7065 +
7066 +       if (phydev->duplex == DUPLEX_FULL)
7067 +               phy_addr_reg.bits.fdup = LTQ_MDIO_PHY_ADDR_FDUP_ENABLE;
7068 +       else
7069 +               phy_addr_reg.bits.fdup = LTQ_MDIO_PHY_ADDR_FDUP_DISABLE;
7070 +
7071 +       ltq_writel(to_mdio_phyaddr(switch_regs, num), phy_addr_reg.val);
7072 +
7073 +       switch (num) {
7074 +       case 0:
7075 +       case 1:
7076 +       case 5:
7077 +               ltq_writel(to_mii_miicfg(switch_regs, num), mii_cfg_reg.val);
7078 +               break;
7079 +       default:
7080 +               break;
7081 +       }
7082 +}
7083 +
7084 +static inline u8 *ltq_eth_rx_packet_align(int rx_num)
7085 +{
7086 +       u8 *packet = (u8 *) NetRxPackets[rx_num];
7087 +
7088 +       /*
7089 +        * IP header needs
7090 +        */
7091 +       return packet + LTQ_ETH_IP_ALIGN;
7092 +}
7093 +
7094 +static int ltq_eth_init(struct eth_device *dev, bd_t *bis)
7095 +{
7096 +       struct ltq_eth_priv *priv = dev->priv;
7097 +       struct ltq_dma_device *dma_dev = &priv->dma_dev;
7098 +       struct phy_device *phydev;
7099 +       int i;
7100 +
7101 +       for (i = 0; i < LTQ_ETHSW_MAX_GMAC; i++) {
7102 +               phydev = priv->phymap[i];
7103 +               if (!phydev)
7104 +                       continue;
7105 +
7106 +               phy_startup(phydev);
7107 +               ltq_eth_gmac_update(phydev, i);
7108 +       }
7109 +
7110 +       for (i = 0; i < LTQ_ETH_RX_BUFFER_CNT; i++)
7111 +               ltq_dma_rx_map(dma_dev, i, ltq_eth_rx_packet_align(i),
7112 +                       LTQ_ETH_RX_DATA_SIZE);
7113 +
7114 +       ltq_dma_enable(dma_dev);
7115 +
7116 +       priv->rx_num = 0;
7117 +       priv->tx_num = 0;
7118 +
7119 +       return 0;
7120 +}
7121 +
7122 +static void ltq_eth_halt(struct eth_device *dev)
7123 +{
7124 +       struct ltq_eth_priv *priv = dev->priv;
7125 +       struct ltq_dma_device *dma_dev = &priv->dma_dev;
7126 +       struct phy_device *phydev;
7127 +       int i;
7128 +
7129 +       ltq_dma_reset(dma_dev);
7130 +
7131 +       for (i = 0; i < LTQ_ETHSW_MAX_GMAC; i++) {
7132 +               phydev = priv->phymap[i];
7133 +               if (!phydev)
7134 +                       continue;
7135 +
7136 +               phy_shutdown(phydev);
7137 +               phydev->link = 0;
7138 +               ltq_eth_gmac_update(phydev, i);
7139 +       }
7140 +}
7141 +
7142 +static int ltq_eth_send(struct eth_device *dev, void *packet, int length)
7143 +{
7144 +       struct ltq_eth_priv *priv = dev->priv;
7145 +       struct ltq_dma_device *dma_dev = &priv->dma_dev;
7146 +
7147 +#if 0
7148 +       printf("%s: packet %p, len %d\n", __func__, packet, length);
7149 +#endif
7150 +
7151 +       ltq_dma_tx_map(dma_dev, priv->tx_num, packet, length, 10);
7152 +       priv->tx_num = (priv->tx_num + 1) % LTQ_ETH_TX_BUFFER_CNT;
7153 +
7154 +       return 0;
7155 +}
7156 +
7157 +static int ltq_eth_recv(struct eth_device *dev)
7158 +{
7159 +       struct ltq_eth_priv *priv = dev->priv;
7160 +       struct ltq_dma_device *dma_dev = &priv->dma_dev;
7161 +       u8 *packet;
7162 +       int len;
7163 +
7164 +       if (!ltq_dma_rx_poll(dma_dev, priv->rx_num))
7165 +               return 0;
7166 +
7167 +#if 0
7168 +       printf("%s: rx_num %d\n", __func__, priv->rx_num);
7169 +#endif
7170 +
7171 +       len = ltq_dma_rx_length(dma_dev, priv->rx_num);
7172 +       packet = ltq_eth_rx_packet_align(priv->rx_num);
7173 +
7174 +#if 0
7175 +       printf("%s: received: packet %p, len %u, rx_num %d\n",
7176 +               __func__, packet, len, priv->rx_num);
7177 +#endif
7178 +
7179 +       if (len)
7180 +               NetReceive(packet, len);
7181 +
7182 +       ltq_dma_rx_map(dma_dev, priv->rx_num, packet,
7183 +               LTQ_ETH_RX_DATA_SIZE);
7184 +
7185 +       priv->rx_num = (priv->rx_num + 1) % LTQ_ETH_RX_BUFFER_CNT;
7186 +
7187 +       return 0;
7188 +}
7189 +
7190 +static void ltq_eth_gmac_init(int num)
7191 +{
7192 +       struct ltq_mdio_phy_addr_reg phy_addr_reg;
7193 +       struct ltq_mii_mii_cfg_reg mii_cfg_reg;
7194 +
7195 +       /* Reset PHY status to link down */
7196 +       phy_addr_reg.val = ltq_readl(to_mdio_phyaddr(switch_regs, num));
7197 +       phy_addr_reg.bits.addr = num;
7198 +       phy_addr_reg.bits.lnkst = LTQ_MDIO_PHY_ADDR_LNKST_DOWN;
7199 +       phy_addr_reg.bits.speed = LTQ_MDIO_PHY_ADDR_SPEED_M10;
7200 +       phy_addr_reg.bits.fdup = LTQ_MDIO_PHY_ADDR_FDUP_DISABLE;
7201 +       ltq_writel(to_mdio_phyaddr(switch_regs, num), phy_addr_reg.val);
7202 +
7203 +       /* Reset and disable MII interface */
7204 +       switch (num) {
7205 +       case 0:
7206 +       case 1:
7207 +       case 5:
7208 +               mii_cfg_reg.val = ltq_readl(to_mii_miicfg(switch_regs, num));
7209 +               mii_cfg_reg.bits.en = 0;
7210 +               mii_cfg_reg.bits.res = 1;
7211 +               mii_cfg_reg.bits.miirate = LTQ_MII_MII_CFG_MIIRATE_M2P5;
7212 +               ltq_writel(to_mii_miicfg(switch_regs, num), mii_cfg_reg.val);
7213 +               break;
7214 +       default:
7215 +               break;
7216 +       }
7217 +
7218 +       /*
7219 +        * - enable frame checksum generation
7220 +        * - enable padding of short frames
7221 +        * - disable flow control
7222 +        */
7223 +       ltq_writel(to_mac_ctrl(switch_regs, num, 0),
7224 +               MAC_CTRL0_PADEN | MAC_CTRL0_FCS | MAC_CTRL0_FCON_NONE);
7225 +
7226 +       vr9_switch_sync();
7227 +}
7228 +
7229 +static void ltq_eth_pmac_init(void)
7230 +{
7231 +       /*
7232 +        * WAR: buffer congestion:
7233 +        * - shorten preambel to 1 byte
7234 +        * - set TX IPG to 7 bytes
7235 +        */
7236 +#if 1
7237 +       ltq_writel(to_mac_ctrl(switch_regs, LTQ_ETHSW_PMAC, 1),
7238 +               MAC_CTRL1_SHORTPRE | 7);
7239 +#endif
7240 +
7241 +       /*
7242 +        * WAR: systematical concept weakness ACM bug
7243 +        * - set maximum number of used buffer segments to 254
7244 +        * - soft-reset BM FSQM
7245 +        */
7246 +#if 1
7247 +       ltq_writel(&switch_regs->bm.core.fsqm_gctrl, 253);
7248 +       ltq_setbits(&switch_regs->bm.core.gctrl, BM_GCTRL_F_SRES);
7249 +       ltq_clrbits(&switch_regs->bm.core.gctrl, BM_GCTRL_F_SRES);
7250 +#endif
7251 +
7252 +       /*
7253 +        * WAR: switch MAC drop bug
7254 +        */
7255 +#if 1
7256 +       ltq_writel(to_pce_tbl_key(switch_regs, 0), 0xf);
7257 +       ltq_writel(to_pce_tbl_value(switch_regs, 0), 0x40);
7258 +       ltq_writel(&switch_regs->pce.core.tbl_addr, 0x3);
7259 +       ltq_writel(&switch_regs->pce.core.tbl_ctrl, 0x902f);
7260 +#endif
7261 +
7262 +       /*
7263 +        * Configure frame header control:
7264 +        * - enable flow control
7265 +        * - enable CRC check for packets from DMA to PMAC
7266 +        * - remove special tag from packets from PMAC to DMA
7267 +        * - add CRC for packets from DMA to PMAC
7268 +        */
7269 +       ltq_writel(&switch_regs->pmac.hd_ctl, /*PMAC_HD_CTL_FC |*/
7270 +               PMAC_HD_CTL_CCRC | PMAC_HD_CTL_RST | PMAC_HD_CTL_AC |
7271 +               PMAC_HD_CTL_RC);
7272 +
7273 +#if 1
7274 +       ltq_writel(&switch_regs->pmac.rx_ipg, 0x8b);
7275 +#endif
7276 +
7277 +       /*
7278 +        * - enable frame checksum generation
7279 +        * - enable padding of short frames
7280 +        * - disable flow control
7281 +        */
7282 +       ltq_writel(to_mac_ctrl(switch_regs, LTQ_ETHSW_PMAC, 0),
7283 +               MAC_CTRL0_PADEN | MAC_CTRL0_FCS | MAC_CTRL0_FCON_NONE);
7284 +
7285 +       vr9_switch_sync();
7286 +}
7287 +
7288 +static void ltq_eth_hw_init(void)
7289 +{
7290 +       int i;
7291 +
7292 +       /* Power up ethernet and switch subsystems */
7293 +       ltq_pm_enable(LTQ_PM_ETH);
7294 +
7295 +       /* Reset ethernet and switch subsystems */
7296 +#if 0
7297 +       ltq_reset_once(LTQ_RESET_ETH, 10);
7298 +#endif
7299 +
7300 +       /* Enable switch macro */
7301 +       ltq_setbits(&switch_regs->mdio.glob_ctrl, MDIO_GLOB_CTRL_SE);
7302 +
7303 +       /* Disable MDIO auto-polling for all ports */
7304 +       ltq_writel(&switch_regs->mdio.mdc_cfg_0, 0);
7305 +
7306 +       /*
7307 +        * Enable and set MDIO management clock to 2.5 MHz. This is the
7308 +        * maximum clock for FE PHYs.
7309 +        * Formula for clock is:
7310 +        *
7311 +        *      50 MHz
7312 +        * x = ----------- - 1
7313 +        *      2 * f_MDC
7314 +        */
7315 +       ltq_writel(&switch_regs->mdio.mdc_cfg_1, MDIO_MDC_CFG1_RES |
7316 +               MDIO_MDC_CFG1_MCEN | 5);
7317 +
7318 +       vr9_switch_sync();
7319 +
7320 +       /* Init MAC connected to CPU  */
7321 +       ltq_eth_pmac_init();
7322 +
7323 +       /* Init MACs connected to external MII interfaces */
7324 +       for (i = 0; i < LTQ_ETHSW_MAX_GMAC; i++)
7325 +               ltq_eth_gmac_init(i);
7326 +}
7327 +
7328 +static void ltq_eth_port_config(struct ltq_eth_priv *priv,
7329 +                                       const struct ltq_eth_port_config *port)
7330 +{
7331 +       struct ltq_mii_mii_cfg_reg mii_cfg_reg;
7332 +       struct phy_device *phydev;
7333 +       int setup_gpio = 0;
7334 +
7335 +       switch (port->num) {
7336 +       case 0: /* xMII0 */
7337 +       case 1: /* xMII1 */
7338 +               mii_cfg_reg.val = ltq_readl(to_mii_miicfg(switch_regs,
7339 +                                       port->num));
7340 +               mii_cfg_reg.bits.en = port->flags ? 1 : 0;
7341 +
7342 +               switch (port->phy_if) {
7343 +               case PHY_INTERFACE_MODE_MII:
7344 +                       if (port->flags & LTQ_ETH_PORT_PHY)
7345 +                               /* MII MAC mode, connected to external PHY */
7346 +                               mii_cfg_reg.bits.miimode =
7347 +                                       LTQ_MII_MII_CFG_MIIMODE_MIIM;
7348 +                       else
7349 +                               /* MII PHY mode, connected to external MAC */
7350 +                               mii_cfg_reg.bits.miimode =
7351 +                                       LTQ_MII_MII_CFG_MIIMODE_MIIP;
7352 +                       setup_gpio = 1;
7353 +                       break;
7354 +               case PHY_INTERFACE_MODE_RMII:
7355 +                       if (port->flags & LTQ_ETH_PORT_PHY)
7356 +                               /* RMII MAC mode, connected to external PHY */
7357 +                               mii_cfg_reg.bits.miimode =
7358 +                                       LTQ_MII_MII_CFG_MIIMODE_RMIIM;
7359 +                       else
7360 +                               /* RMII PHY mode, connected to external MAC */
7361 +                               mii_cfg_reg.bits.miimode =
7362 +                                       LTQ_MII_MII_CFG_MIIMODE_RMIIP;
7363 +                       setup_gpio = 1;
7364 +                       break;
7365 +               case PHY_INTERFACE_MODE_RGMII:
7366 +                       /* RGMII MAC mode, connected to external PHY */
7367 +                       mii_cfg_reg.bits.miimode =
7368 +                               LTQ_MII_MII_CFG_MIIMODE_RGMII;
7369 +                       setup_gpio = 1;
7370 +
7371 +                       /* RGMII clock delays */
7372 +                       ltq_writel(to_mii_pcdu(switch_regs, port->num),
7373 +                               port->rgmii_rx_delay << PCDU_RXDLY_SHIFT |
7374 +                               port->rgmii_tx_delay);
7375 +                       break;
7376 +               default:
7377 +                       break;
7378 +               }
7379 +
7380 +               ltq_writel(to_mii_miicfg(switch_regs, port->num),
7381 +                       mii_cfg_reg.val);
7382 +               break;
7383 +       case 2: /* internal GPHY0 */
7384 +       case 3: /* internal GPHY0 */
7385 +       case 4: /* internal GPHY1 */
7386 +               switch (port->phy_if) {
7387 +               case PHY_INTERFACE_MODE_MII:
7388 +               case PHY_INTERFACE_MODE_GMII:
7389 +                       setup_gpio = 1;
7390 +                       break;
7391 +               default:
7392 +                       break;
7393 +               }
7394 +               break;
7395 +       case 5: /* internal GPHY1 or xMII2 */
7396 +               mii_cfg_reg.val = ltq_readl(to_mii_miicfg(switch_regs,
7397 +                                       port->num));
7398 +               mii_cfg_reg.bits.en = port->flags ? 1 : 0;
7399 +
7400 +               switch (port->phy_if) {
7401 +               case PHY_INTERFACE_MODE_MII:
7402 +                       /* MII MAC mode, connected to internal GPHY */
7403 +                       mii_cfg_reg.bits.miimode =
7404 +                               LTQ_MII_MII_CFG_MIIMODE_MIIM;
7405 +                       setup_gpio = 1;
7406 +                       break;
7407 +               case PHY_INTERFACE_MODE_RGMII:
7408 +                       /* RGMII MAC mode, connected to external PHY */
7409 +                       mii_cfg_reg.bits.miimode =
7410 +                               LTQ_MII_MII_CFG_MIIMODE_RGMII;
7411 +                       setup_gpio = 1;
7412 +
7413 +                       /* RGMII clock delays */
7414 +                       ltq_writel(to_mii_pcdu(switch_regs, port->num),
7415 +                               port->rgmii_rx_delay << PCDU_RXDLY_SHIFT |
7416 +                               port->rgmii_tx_delay);
7417 +                       break;
7418 +               default:
7419 +                       break;
7420 +               }
7421 +
7422 +               ltq_writel(to_mii_miicfg(switch_regs, port->num),
7423 +                       mii_cfg_reg.val);
7424 +               break;
7425 +       default:
7426 +               break;
7427 +       }
7428 +
7429 +       /* Setup GPIOs for MII with external PHYs/MACs */
7430 +       if (setup_gpio) {
7431 +               /* MII/MDIO */
7432 +               gpio_set_altfunc(42, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR,
7433 +                                       GPIO_DIR_OUT);
7434 +               /* MII/MDC */
7435 +               gpio_set_altfunc(43, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR,
7436 +                                       GPIO_DIR_OUT);
7437 +       }
7438 +
7439 +       /* Connect to internal/external PHYs */
7440 +       if (port->flags & LTQ_ETH_PORT_PHY) {
7441 +               phydev = phy_connect(priv->bus, port->phy_addr, priv->dev,
7442 +                                       port->phy_if);
7443 +               if (phydev)
7444 +                       phy_config(phydev);
7445 +
7446 +               priv->phymap[port->num] = phydev;
7447 +       }
7448 +}
7449 +
7450 +int ltq_eth_initialize(const struct ltq_eth_board_config *board_config)
7451 +{
7452 +       struct eth_device *dev;
7453 +       struct mii_dev *bus;
7454 +       struct ltq_eth_priv *priv;
7455 +       struct ltq_dma_device *dma_dev;
7456 +       int i, ret;
7457 +
7458 +       build_check_vr9_registers();
7459 +
7460 +       ltq_dma_init();
7461 +       ltq_eth_hw_init();
7462 +
7463 +       dev = calloc(1, sizeof(struct eth_device));
7464 +       if (!dev)
7465 +               return -1;
7466 +
7467 +       priv = calloc(1, sizeof(struct ltq_eth_priv));
7468 +       if (!priv)
7469 +               return -1;
7470 +
7471 +       bus = mdio_alloc();
7472 +       if (!bus)
7473 +               return -1;
7474 +
7475 +       sprintf(dev->name, LTQ_ETH_DRV_NAME);
7476 +       dev->priv = priv;
7477 +       dev->init = ltq_eth_init;
7478 +       dev->halt = ltq_eth_halt;
7479 +       dev->recv = ltq_eth_recv;
7480 +       dev->send = ltq_eth_send;
7481 +
7482 +       sprintf(bus->name, LTQ_MDIO_DRV_NAME);
7483 +       bus->read = vr9_switch_mdio_read;
7484 +       bus->write = vr9_switch_mdio_write;
7485 +       bus->priv = priv;
7486 +
7487 +       dma_dev = &priv->dma_dev;
7488 +       dma_dev->port = 0;
7489 +       dma_dev->rx_chan.chan_no = 0;
7490 +       dma_dev->rx_chan.class = 0;
7491 +       dma_dev->rx_chan.num_desc = LTQ_ETH_RX_BUFFER_CNT;
7492 +       dma_dev->rx_endian_swap = LTQ_DMA_ENDIANESS_B3_B2_B1_B0;
7493 +       dma_dev->rx_burst_len = LTQ_DMA_BURST_2WORDS;
7494 +       dma_dev->tx_chan.chan_no = 1;
7495 +       dma_dev->tx_chan.class = 0;
7496 +       dma_dev->tx_chan.num_desc = LTQ_ETH_TX_BUFFER_CNT;
7497 +       dma_dev->tx_endian_swap = LTQ_DMA_ENDIANESS_B3_B2_B1_B0;
7498 +       dma_dev->tx_burst_len = LTQ_DMA_BURST_2WORDS;
7499 +
7500 +       priv->bus = bus;
7501 +       priv->dev = dev;
7502 +
7503 +       ret = ltq_dma_register(dma_dev);
7504 +       if (ret)
7505 +               return -1;
7506 +
7507 +       ret = mdio_register(bus);
7508 +       if (ret)
7509 +               return -1;
7510 +
7511 +       ret = eth_register(dev);
7512 +       if (ret)
7513 +               return -1;
7514 +
7515 +       for (i = 0; i < board_config->num_ports; i++)
7516 +               ltq_eth_port_config(priv, &board_config->ports[i]);
7517 +
7518 +       return 0;
7519 +}
7520 --- a/drivers/net/phy/Makefile
7521 +++ b/drivers/net/phy/Makefile
7522 @@ -20,6 +20,7 @@ COBJS-$(CONFIG_PHY_BROADCOM) += broadcom
7523  COBJS-$(CONFIG_PHY_DAVICOM) += davicom.o
7524  COBJS-$(CONFIG_PHY_ET1011C) += et1011c.o
7525  COBJS-$(CONFIG_PHY_ICPLUS) += icplus.o
7526 +COBJS-$(CONFIG_PHY_LANTIQ) += lantiq.o
7527  COBJS-$(CONFIG_PHY_LXT) += lxt.o
7528  COBJS-$(CONFIG_PHY_MARVELL) += marvell.o
7529  COBJS-$(CONFIG_PHY_MICREL) += micrel.o
7530 --- /dev/null
7531 +++ b/drivers/net/phy/lantiq.c
7532 @@ -0,0 +1,238 @@
7533 +/*
7534 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
7535 + *
7536 + * SPDX-License-Identifier:    GPL-2.0+
7537 + */
7538 +
7539 +#define DEBUG
7540 +
7541 +#include <common.h>
7542 +#include <miiphy.h>
7543 +
7544 +#define ADVERTIZE_MPD          (1 << 10)
7545 +
7546 +DECLARE_GLOBAL_DATA_PTR;
7547 +
7548 +/*
7549 + * Update link status.
7550 + *
7551 + * Based on genphy_update_link in phylib.c
7552 + */
7553 +static int ltq_phy_update_link(struct phy_device *phydev)
7554 +{
7555 +       unsigned int mii_reg;
7556 +
7557 +       mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
7558 +
7559 +       /*
7560 +        * If we already saw the link up, and it hasn't gone down, then
7561 +        * we don't need to wait for autoneg again
7562 +        */
7563 +       if (phydev->link && mii_reg & BMSR_LSTATUS)
7564 +               return 0;
7565 +
7566 +       if ((mii_reg & BMSR_ANEGCAPABLE) && !(mii_reg & BMSR_ANEGCOMPLETE)) {
7567 +               phydev->link = 0;
7568 +               return 0;
7569 +       } else {
7570 +               /* Read the link a second time to clear the latched state */
7571 +               mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
7572 +
7573 +               if (mii_reg & BMSR_LSTATUS)
7574 +                       phydev->link = 1;
7575 +               else
7576 +                       phydev->link = 0;
7577 +       }
7578 +
7579 +       return 0;
7580 +}
7581 +
7582 +/*
7583 + * Update speed and duplex.
7584 + *
7585 + * Based on genphy_parse_link in phylib.c
7586 + */
7587 +static int ltq_phy_parse_link(struct phy_device *phydev)
7588 +{
7589 +       unsigned int mii_reg;
7590 +
7591 +       mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
7592 +
7593 +       /* We're using autonegotiation */
7594 +       if (mii_reg & BMSR_ANEGCAPABLE) {
7595 +               u32 lpa = 0;
7596 +               u32 gblpa = 0;
7597 +
7598 +               /* Check for gigabit capability */
7599 +               if (mii_reg & BMSR_ERCAP) {
7600 +                       /* We want a list of states supported by
7601 +                        * both PHYs in the link
7602 +                        */
7603 +                       gblpa = phy_read(phydev, MDIO_DEVAD_NONE, MII_STAT1000);
7604 +                       gblpa &= phy_read(phydev,
7605 +                                       MDIO_DEVAD_NONE, MII_CTRL1000) << 2;
7606 +               }
7607 +
7608 +               /* Set the baseline so we only have to set them
7609 +                * if they're different
7610 +                */
7611 +               phydev->speed = SPEED_10;
7612 +               phydev->duplex = DUPLEX_HALF;
7613 +
7614 +               /* Check the gigabit fields */
7615 +               if (gblpa & (PHY_1000BTSR_1000FD | PHY_1000BTSR_1000HD)) {
7616 +                       phydev->speed = SPEED_1000;
7617 +
7618 +                       if (gblpa & PHY_1000BTSR_1000FD)
7619 +                               phydev->duplex = DUPLEX_FULL;
7620 +
7621 +                       /* We're done! */
7622 +                       return 0;
7623 +               }
7624 +
7625 +               lpa = phy_read(phydev, MDIO_DEVAD_NONE, MII_ADVERTISE);
7626 +               lpa &= phy_read(phydev, MDIO_DEVAD_NONE, MII_LPA);
7627 +
7628 +               if (lpa & (LPA_100FULL | LPA_100HALF)) {
7629 +                       phydev->speed = SPEED_100;
7630 +
7631 +                       if (lpa & LPA_100FULL)
7632 +                               phydev->duplex = DUPLEX_FULL;
7633 +
7634 +               } else if (lpa & LPA_10FULL)
7635 +                       phydev->duplex = DUPLEX_FULL;
7636 +       } else {
7637 +               u32 bmcr = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);
7638 +
7639 +               phydev->speed = SPEED_10;
7640 +               phydev->duplex = DUPLEX_HALF;
7641 +
7642 +               if (bmcr & BMCR_FULLDPLX)
7643 +                       phydev->duplex = DUPLEX_FULL;
7644 +
7645 +               if (bmcr & BMCR_SPEED1000)
7646 +                       phydev->speed = SPEED_1000;
7647 +               else if (bmcr & BMCR_SPEED100)
7648 +                       phydev->speed = SPEED_100;
7649 +       }
7650 +
7651 +       return 0;
7652 +}
7653 +
7654 +static int ltq_phy_config(struct phy_device *phydev)
7655 +{
7656 +       u16 val;
7657 +
7658 +       /* Advertise as Multi-port device */
7659 +       val = phy_read(phydev, MDIO_DEVAD_NONE, MII_CTRL1000);
7660 +       val |= ADVERTIZE_MPD;
7661 +       phy_write(phydev, MDIO_DEVAD_NONE, MII_CTRL1000, val);
7662 +
7663 +       genphy_config_aneg(phydev);
7664 +
7665 +       return 0;
7666 +}
7667 +
7668 +static int ltq_phy_startup(struct phy_device *phydev)
7669 +{
7670 +       /*
7671 +        * Update PHY status immediately without any delays as genphy_startup
7672 +        * does because VRX200 switch needs to be configured dependent
7673 +        * on this information.
7674 +        */
7675 +       ltq_phy_update_link(phydev);
7676 +       ltq_phy_parse_link(phydev);
7677 +
7678 +       debug("ltq_phy: addr %d, link %d, speed %d, duplex %d\n",
7679 +               phydev->addr, phydev->link, phydev->speed, phydev->duplex);
7680 +
7681 +       return 0;
7682 +}
7683 +
7684 +static struct phy_driver xrx_11g_13_driver = {
7685 +       .name = "Lantiq XWAY XRX PHY11G v1.3 and earlier",
7686 +       .uid = 0x030260D0,
7687 +       .mask = 0xFFFFFFF0,
7688 +       .features = PHY_GBIT_FEATURES,
7689 +       .config = ltq_phy_config,
7690 +       .startup = ltq_phy_startup,
7691 +       .shutdown = genphy_shutdown,
7692 +};
7693 +
7694 +static struct phy_driver xrx_11g_14_driver = {
7695 +       .name = "Lantiq XWAY XRX PHY11G v1.4 and later",
7696 +       .uid = 0xd565a408,
7697 +       .mask = 0xFFFFFFF8,
7698 +       .features = PHY_GBIT_FEATURES,
7699 +       .config = ltq_phy_config,
7700 +       .startup = ltq_phy_startup,
7701 +       .shutdown = genphy_shutdown,
7702 +};
7703 +
7704 +static struct phy_driver xrx_22f_14_driver = {
7705 +       .name = "Lantiq XWAY XRX PHY22F v1.4 and later",
7706 +       .uid = 0xd565a418,
7707 +       .mask = 0xFFFFFFF8,
7708 +       .features = PHY_BASIC_FEATURES,
7709 +       .config = ltq_phy_config,
7710 +       .startup = ltq_phy_startup,
7711 +       .shutdown = genphy_shutdown,
7712 +};
7713 +
7714 +static struct phy_driver pef7071_driver = {
7715 +       .name = "Lantiq XWAY PEF7071",
7716 +       .uid = 0xd565a400,
7717 +       .mask = 0xFFFFFFFF,
7718 +       .features = PHY_GBIT_FEATURES,
7719 +       .config = ltq_phy_config,
7720 +       .startup = ltq_phy_startup,
7721 +       .shutdown = genphy_shutdown,
7722 +};
7723 +
7724 +static struct phy_driver xrx_genphy_driver = {
7725 +       .name = "Generic PHY at Lantiq XWAY XRX switch",
7726 +       .uid = 0,
7727 +       .mask = 0,
7728 +       .features = 0,
7729 +       .config = genphy_config,
7730 +       .startup = ltq_phy_startup,
7731 +       .shutdown = genphy_shutdown,
7732 +};
7733 +
7734 +int phy_lantiq_init(void)
7735 +{
7736 +#ifdef CONFIG_NEEDS_MANUAL_RELOC
7737 +       xrx_11g_13_driver.config = ltq_phy_config;
7738 +       xrx_11g_13_driver.startup = ltq_phy_startup;
7739 +       xrx_11g_13_driver.shutdown = genphy_shutdown;
7740 +       xrx_11g_13_driver.name += gd->reloc_off;
7741 +
7742 +       xrx_11g_14_driver.config = ltq_phy_config;
7743 +       xrx_11g_14_driver.startup = ltq_phy_startup;
7744 +       xrx_11g_14_driver.shutdown = genphy_shutdown;
7745 +       xrx_11g_14_driver.name += gd->reloc_off;
7746 +
7747 +       xrx_22f_14_driver.config = ltq_phy_config;
7748 +       xrx_22f_14_driver.startup = ltq_phy_startup;
7749 +       xrx_22f_14_driver.shutdown = genphy_shutdown;
7750 +       xrx_22f_14_driver.name += gd->reloc_off;
7751 +
7752 +       pef7071_driver.config = ltq_phy_config;
7753 +       pef7071_driver.startup = ltq_phy_startup;
7754 +       pef7071_driver.shutdown = genphy_shutdown;
7755 +       pef7071_driver.name += gd->reloc_off;
7756 +
7757 +       xrx_genphy_driver.config = genphy_config;
7758 +       xrx_genphy_driver.startup = ltq_phy_startup;
7759 +       xrx_genphy_driver.shutdown = genphy_shutdown;
7760 +       xrx_genphy_driver.name += gd->reloc_off;
7761 +#endif
7762 +
7763 +       phy_register(&xrx_11g_13_driver);
7764 +       phy_register(&xrx_11g_14_driver);
7765 +       phy_register(&xrx_22f_14_driver);
7766 +       phy_register(&pef7071_driver);
7767 +       phy_register(&xrx_genphy_driver);
7768 +
7769 +       return 0;
7770 +}
7771 --- a/drivers/net/phy/phy.c
7772 +++ b/drivers/net/phy/phy.c
7773 @@ -16,9 +16,10 @@
7774  #include <command.h>
7775  #include <miiphy.h>
7776  #include <phy.h>
7777 -#include <errno.h>
7778  #include <linux/err.h>
7779  
7780 +DECLARE_GLOBAL_DATA_PTR;
7781 +
7782  /* Generic PHY support and helper functions */
7783  
7784  /**
7785 @@ -440,6 +441,16 @@ static LIST_HEAD(phy_drivers);
7786  
7787  int phy_init(void)
7788  {
7789 +#ifdef CONFIG_NEEDS_MANUAL_RELOC
7790 +       INIT_LIST_HEAD(&phy_drivers);
7791 +
7792 +       genphy_driver.config = genphy_config;
7793 +       genphy_driver.startup = genphy_startup;
7794 +       genphy_driver.shutdown = genphy_shutdown;
7795 +
7796 +       genphy_driver.name += gd->reloc_off;
7797 +#endif
7798 +
7799  #ifdef CONFIG_PHY_ATHEROS
7800         phy_atheros_init();
7801  #endif
7802 @@ -455,6 +466,9 @@ int phy_init(void)
7803  #ifdef CONFIG_PHY_ICPLUS
7804         phy_icplus_init();
7805  #endif
7806 +#ifdef CONFIG_PHY_LANTIQ
7807 +       phy_lantiq_init();
7808 +#endif
7809  #ifdef CONFIG_PHY_LXT
7810         phy_lxt_init();
7811  #endif
7812 --- a/drivers/serial/Makefile
7813 +++ b/drivers/serial/Makefile
7814 @@ -24,6 +24,7 @@ COBJS-$(CONFIG_SYS_NS16550_SERIAL) += se
7815  COBJS-$(CONFIG_IMX_SERIAL) += serial_imx.o
7816  COBJS-$(CONFIG_IXP_SERIAL) += serial_ixp.o
7817  COBJS-$(CONFIG_KS8695_SERIAL) += serial_ks8695.o
7818 +COBJS-$(CONFIG_LANTIQ_SERIAL) += serial_lantiq.o
7819  COBJS-$(CONFIG_MAX3100_SERIAL) += serial_max3100.o
7820  COBJS-$(CONFIG_MXC_UART) += serial_mxc.o
7821  COBJS-$(CONFIG_PL010_SERIAL) += serial_pl01x.o
7822 --- a/drivers/serial/serial.c
7823 +++ b/drivers/serial/serial.c
7824 @@ -160,6 +160,7 @@ serial_initfunc(sa1100_serial_initialize
7825  serial_initfunc(sh_serial_initialize);
7826  serial_initfunc(arm_dcc_initialize);
7827  serial_initfunc(mxs_auart_initialize);
7828 +serial_initfunc(ltq_serial_initialize);
7829  
7830  /**
7831   * serial_register() - Register serial driver with serial driver core
7832 @@ -253,6 +254,7 @@ void serial_initialize(void)
7833         sh_serial_initialize();
7834         arm_dcc_initialize();
7835         mxs_auart_initialize();
7836 +       ltq_serial_initialize();
7837  
7838         serial_assign(default_serial_console()->name);
7839  }
7840 --- /dev/null
7841 +++ b/drivers/serial/serial_lantiq.c
7842 @@ -0,0 +1,263 @@
7843 +/*
7844 + * Copyright (C) 2010 Thomas Langer <thomas.langer@lantiq.com>
7845 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
7846 + *
7847 + * SPDX-License-Identifier:    GPL-2.0+
7848 + */
7849 +
7850 +#include <common.h>
7851 +#include <serial.h>
7852 +#include <asm/errno.h>
7853 +#include <asm/arch/soc.h>
7854 +#include <asm/lantiq/clk.h>
7855 +#include <asm/lantiq/io.h>
7856 +
7857 +#if CONFIG_CONSOLE_ASC == 0
7858 +#define LTQ_ASC_BASE                   LTQ_ASC0_BASE
7859 +#else
7860 +#define LTQ_ASC_BASE                   LTQ_ASC1_BASE
7861 +#endif
7862 +
7863 +#define LTQ_ASC_ID_TXFS_SHIFT          24
7864 +#define LTQ_ASC_ID_TXFS_MASK           (0x3F << LTQ_ASC_ID_TXFS_SHIFT)
7865 +#define LTQ_ASC_ID_RXFS_SHIFT          16
7866 +#define LTQ_ASC_ID_RXFS_MASK           (0x3F << LTQ_ASC_ID_RXFS_SHIFT)
7867 +
7868 +#define LTQ_ASC_MCON_R                 (1 << 15)
7869 +#define LTQ_ASC_MCON_FDE               (1 << 9)
7870 +
7871 +#define LTQ_ASC_WHBSTATE_SETREN                (1 << 1)
7872 +#define LTQ_ASC_WHBSTATE_CLRREN                (1 << 0)
7873 +
7874 +#define LTQ_ASC_RXFCON_RXFITL_SHIFT    8
7875 +#define LTQ_ASC_RXFCON_RXFITL_MASK     (0x3F << LTQ_ASC_RXFCON_RXFITL_SHIFT)
7876 +#define LTQ_ASC_RXFCON_RXFITL_RXFFLU   (1 << 1)
7877 +#define LTQ_ASC_RXFCON_RXFITL_RXFEN    (1 << 0)
7878 +
7879 +#define LTQ_ASC_TXFCON_TXFITL_SHIFT    8
7880 +#define LTQ_ASC_TXFCON_TXFITL_MASK     (0x3F << LTQ_ASC_TXFCON_TXFITL_SHIFT)
7881 +#define LTQ_ASC_TXFCON_TXFITL_TXFFLU   (1 << 1)
7882 +#define LTQ_ASC_TXFCON_TXFITL_TXFEN    (1 << 0)
7883 +
7884 +#define LTQ_ASC_FSTAT_TXFREE_SHIFT     24
7885 +#define LTQ_ASC_FSTAT_TXFREE_MASK      (0x3F << LTQ_ASC_FSTAT_TXFREE_SHIFT)
7886 +#define LTQ_ASC_FSTAT_RXFREE_SHIFT     16
7887 +#define LTQ_ASC_FSTAT_RXFREE_MASK      (0x3F << LTQ_ASC_FSTAT_RXFREE_SHIFT)
7888 +#define LTQ_ASC_FSTAT_TXFFL_SHIFT      8
7889 +#define LTQ_ASC_FSTAT_TXFFL_MASK       (0x3F << LTQ_ASC_FSTAT_TXFFL_SHIFT)
7890 +#define LTQ_ASC_FSTAT_RXFFL_MASK       0x3F
7891 +
7892 +#ifdef __BIG_ENDIAN
7893 +#define LTQ_ASC_RBUF_OFFSET            3
7894 +#define LTQ_ASC_TBUF_OFFSET            3
7895 +#else
7896 +#define LTQ_ASC_RBUF_OFFSET            0
7897 +#define LTQ_ASC_TBUF_OFFSET            0
7898 +#endif
7899 +
7900 +struct ltq_asc_regs {
7901 +       u32     clc;
7902 +       u32     pisel;
7903 +       u32     id;
7904 +       u32     rsvd0;
7905 +       u32     mcon;
7906 +       u32     state;
7907 +       u32     whbstate;
7908 +       u32     rsvd1;
7909 +       u8      tbuf[4];
7910 +       u8      rbuf[4];
7911 +       u32     rsvd2[2];
7912 +       u32     abcon;
7913 +       u32     abstat;
7914 +       u32     whbabcon;
7915 +       u32     whbabstat;
7916 +       u32     rxfcon;
7917 +       u32     txfcon;
7918 +       u32     fstat;
7919 +       u32     rsvd3;
7920 +       u32     bg;
7921 +       u32     bg_timer;
7922 +       u32     fdv;
7923 +       u32     pmw;
7924 +       u32     modcon;
7925 +       u32     modstat;
7926 +};
7927 +
7928 +DECLARE_GLOBAL_DATA_PTR;
7929 +
7930 +static struct ltq_asc_regs *ltq_asc_regs =
7931 +       (struct ltq_asc_regs *) CKSEG1ADDR(LTQ_ASC_BASE);
7932 +
7933 +static int ltq_serial_init(void)
7934 +{
7935 +       /* Set clock divider for normal run mode to 1 and enable module */
7936 +       ltq_writel(&ltq_asc_regs->clc, 0x100);
7937 +
7938 +       /* Reset MCON register */
7939 +       ltq_writel(&ltq_asc_regs->mcon, 0);
7940 +
7941 +       /* Use Port A as receiver input */
7942 +       ltq_writel(&ltq_asc_regs->pisel, 0);
7943 +
7944 +       /* Enable and flush RX/TX FIFOs */
7945 +       ltq_setbits(&ltq_asc_regs->rxfcon,
7946 +               LTQ_ASC_RXFCON_RXFITL_RXFFLU | LTQ_ASC_RXFCON_RXFITL_RXFEN);
7947 +       ltq_setbits(&ltq_asc_regs->txfcon,
7948 +               LTQ_ASC_TXFCON_TXFITL_TXFFLU | LTQ_ASC_TXFCON_TXFITL_TXFEN);
7949 +
7950 +       serial_setbrg();
7951 +
7952 +       /* Disable error flags, enable receiver */
7953 +       ltq_writel(&ltq_asc_regs->whbstate, LTQ_ASC_WHBSTATE_SETREN);
7954 +
7955 +       return 0;
7956 +}
7957 +
7958 +/*
7959 + *             fdv       asc_clk
7960 + * Baudrate = ----- * -------------
7961 + *             512    16 * (bg + 1)
7962 + */
7963 +static void ltq_serial_calc_br_fdv(unsigned long asc_clk,
7964 +                                       unsigned long baudrate, u16 *fdv,
7965 +                                       u16 *bg)
7966 +{
7967 +       const u32 c = asc_clk / (16 * 512);
7968 +       u32 diff1, diff2;
7969 +       u32 bg_calc, br_calc, i;
7970 +
7971 +       diff1 = baudrate;
7972 +       for (i = 512; i > 0; i--) {
7973 +               /* Calc bg for current fdv value */
7974 +               bg_calc = i * c / baudrate;
7975 +
7976 +               /* Impossible baudrate */
7977 +               if (!bg_calc)
7978 +                       return;
7979 +
7980 +               /*
7981 +                * Calc diff to target baudrate dependent on current
7982 +                * bg and fdv values
7983 +                */
7984 +               br_calc = i * c / bg_calc;
7985 +               if (br_calc > baudrate)
7986 +                       diff2 = br_calc - baudrate;
7987 +               else
7988 +                       diff2 = baudrate - br_calc;
7989 +
7990 +               /* Perfect values found */
7991 +               if (diff2 == 0) {
7992 +                       *fdv = i;
7993 +                       *bg = bg_calc - 1;
7994 +                       return;
7995 +               }
7996 +
7997 +               if (diff2 < diff1) {
7998 +                       *fdv = i;
7999 +                       *bg = bg_calc - 1;
8000 +                       diff1 = diff2;
8001 +               }
8002 +       }
8003 +}
8004 +
8005 +static void ltq_serial_setbrg(void)
8006 +{
8007 +       unsigned long asc_clk, baudrate;
8008 +       u16 bg = 0;
8009 +       u16 fdv = 511;
8010 +
8011 +       /* ASC clock is same as FPI clock with CLC.RMS = 1 */
8012 +       asc_clk = ltq_get_bus_clock();
8013 +       baudrate = gd->baudrate;
8014 +
8015 +       /* Calculate FDV and BG values */
8016 +       ltq_serial_calc_br_fdv(asc_clk, baudrate, &fdv, &bg);
8017 +
8018 +       /* Disable baudrate generator */
8019 +       ltq_clrbits(&ltq_asc_regs->mcon, LTQ_ASC_MCON_R);
8020 +
8021 +       /* Enable fractional divider */
8022 +       ltq_setbits(&ltq_asc_regs->mcon, LTQ_ASC_MCON_FDE);
8023 +
8024 +       /* Set fdv and bg values */
8025 +       ltq_writel(&ltq_asc_regs->fdv, fdv);
8026 +       ltq_writel(&ltq_asc_regs->bg, bg);
8027 +
8028 +       /* Enable baudrate generator */
8029 +       ltq_setbits(&ltq_asc_regs->mcon, LTQ_ASC_MCON_R);
8030 +}
8031 +
8032 +static unsigned int ltq_serial_tx_free(void)
8033 +{
8034 +       unsigned int txfree;
8035 +
8036 +       txfree = (ltq_readl(&ltq_asc_regs->fstat) &
8037 +                       LTQ_ASC_FSTAT_TXFREE_MASK) >>
8038 +                       LTQ_ASC_FSTAT_TXFREE_SHIFT;
8039 +
8040 +       return txfree;
8041 +}
8042 +
8043 +static unsigned int ltq_serial_rx_fill(void)
8044 +{
8045 +       unsigned int rxffl;
8046 +
8047 +       rxffl = ltq_readl(&ltq_asc_regs->fstat) & LTQ_ASC_FSTAT_RXFFL_MASK;
8048 +
8049 +       return rxffl;
8050 +}
8051 +
8052 +static void ltq_serial_tx(const char c)
8053 +{
8054 +       ltq_writeb(&ltq_asc_regs->tbuf[LTQ_ASC_TBUF_OFFSET], c);
8055 +}
8056 +
8057 +static u8 ltq_serial_rx(void)
8058 +{
8059 +       return ltq_readb(&ltq_asc_regs->rbuf[LTQ_ASC_RBUF_OFFSET]);
8060 +}
8061 +
8062 +static void ltq_serial_putc(const char c)
8063 +{
8064 +       if (c == '\n')
8065 +               ltq_serial_putc('\r');
8066 +
8067 +       while (!ltq_serial_tx_free())
8068 +               ;
8069 +
8070 +       ltq_serial_tx(c);
8071 +}
8072 +
8073 +static int ltq_serial_getc(void)
8074 +{
8075 +       while (!ltq_serial_rx_fill())
8076 +               ;
8077 +
8078 +       return ltq_serial_rx();
8079 +}
8080 +
8081 +static int ltq_serial_tstc(void)
8082 +{
8083 +       return (0 != ltq_serial_rx_fill());
8084 +}
8085 +
8086 +static struct serial_device ltq_serial_drv = {
8087 +       .name   = "ltq_serial",
8088 +       .start  = ltq_serial_init,
8089 +       .stop   = NULL,
8090 +       .setbrg = ltq_serial_setbrg,
8091 +       .putc   = ltq_serial_putc,
8092 +       .puts   = default_serial_puts,
8093 +       .getc   = ltq_serial_getc,
8094 +       .tstc   = ltq_serial_tstc,
8095 +};
8096 +
8097 +void ltq_serial_initialize(void)
8098 +{
8099 +       serial_register(&ltq_serial_drv);
8100 +}
8101 +
8102 +__weak struct serial_device *default_serial_console(void)
8103 +{
8104 +       return &ltq_serial_drv;
8105 +}
8106 --- a/drivers/spi/Makefile
8107 +++ b/drivers/spi/Makefile
8108 @@ -25,6 +25,7 @@ COBJS-$(CONFIG_DAVINCI_SPI) += davinci_s
8109  COBJS-$(CONFIG_EXYNOS_SPI) += exynos_spi.o
8110  COBJS-$(CONFIG_ICH_SPI) +=  ich.o
8111  COBJS-$(CONFIG_KIRKWOOD_SPI) += kirkwood_spi.o
8112 +COBJS-$(CONFIG_LANTIQ_SPI) += lantiq_spi.o
8113  COBJS-$(CONFIG_MPC52XX_SPI) += mpc52xx_spi.o
8114  COBJS-$(CONFIG_MPC8XXX_SPI) += mpc8xxx_spi.o
8115  COBJS-$(CONFIG_MXC_SPI) += mxc_spi.o
8116 --- /dev/null
8117 +++ b/drivers/spi/lantiq_spi.c
8118 @@ -0,0 +1,666 @@
8119 +/*
8120 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
8121 + *
8122 + * SPDX-License-Identifier:    GPL-2.0+
8123 + */
8124 +
8125 +#include <common.h>
8126 +#include <spi.h>
8127 +#include <malloc.h>
8128 +#include <watchdog.h>
8129 +#include <asm/gpio.h>
8130 +#include <asm/lantiq/io.h>
8131 +#include <asm/lantiq/clk.h>
8132 +#include <asm/lantiq/pm.h>
8133 +#include <asm/arch/soc.h>
8134 +
8135 +#define LTQ_SPI_CLC_RMC_SHIFT          8
8136 +#define LTQ_SPI_CLC_RMC_MASK           (0xFF << LTQ_SPI_CLC_RMC_SHIFT)
8137 +#define LTQ_SPI_CLC_DISS               (1 << 1)
8138 +#define LTQ_SPI_CLC_DISR               1
8139 +
8140 +#define LTQ_SPI_ID_TXFS_SHIFT          24
8141 +#define LTQ_SPI_ID_TXFS_MASK           (0x3F << LTQ_SPI_ID_TXFS_SHIFT)
8142 +#define LTQ_SPI_ID_RXFS_SHIFT          16
8143 +#define LTQ_SPI_ID_RXFS_MASK           (0x3F << LTQ_SPI_ID_RXFS_SHIFT)
8144 +
8145 +#define LTQ_SPI_CON_ENBV               (1 << 22)
8146 +#define LTQ_SPI_CON_BM_SHIFT           16
8147 +#define LTQ_SPI_CON_BM_MASK            (0x1F << LTQ_SPI_CON_BM_SHIFT)
8148 +#define LTQ_SPI_CON_IDLE               (1 << 23)
8149 +#define LTQ_SPI_CON_RUEN               (1 << 12)
8150 +#define LTQ_SPI_CON_AEN                        (1 << 10)
8151 +#define LTQ_SPI_CON_REN                        (1 << 9)
8152 +#define LTQ_SPI_CON_TEN                        (1 << 8)
8153 +#define LTQ_SPI_CON_LB                 (1 << 7)
8154 +#define LTQ_SPI_CON_PO                 (1 << 6)
8155 +#define LTQ_SPI_CON_PH                 (1 << 5)
8156 +#define LTQ_SPI_CON_HB                 (1 << 4)
8157 +#define LTQ_SPI_CON_RXOFF              (1 << 1)
8158 +#define LTQ_SPI_CON_TXOFF              1
8159 +
8160 +#define LTQ_SPI_STAT_RXBV_SHIFT                28
8161 +#define LTQ_SPI_STAT_RXBV_MASK         (0x7 << LTQ_SPI_STAT_RXBV_SHIFT)
8162 +#define LTQ_SPI_STAT_BSY               (1 << 13)
8163 +
8164 +#define LTQ_SPI_WHBSTATE_SETMS         (1 << 3)
8165 +#define LTQ_SPI_WHBSTATE_CLRMS         (1 << 2)
8166 +#define LTQ_SPI_WHBSTATE_SETEN         (1 << 1)
8167 +#define LTQ_SPI_WHBSTATE_CLREN         1
8168 +#define LTQ_SPI_WHBSTATE_CLR_ERRORS    0x0F50
8169 +
8170 +#define LTQ_SPI_TXFCON_TXFLU           (1 << 1)
8171 +#define LTQ_SPI_TXFCON_TXFEN           1
8172 +
8173 +#define LTQ_SPI_RXFCON_RXFLU           (1 << 1)
8174 +#define LTQ_SPI_RXFCON_RXFEN           1
8175 +
8176 +#define LTQ_SPI_FSTAT_RXFFL_MASK       0x3f
8177 +#define LTQ_SPI_FSTAT_TXFFL_SHIFT      8
8178 +#define LTQ_SPI_FSTAT_TXFFL_MASK       (0x3f << LTQ_SPI_FSTAT_TXFFL_SHIFT)
8179 +
8180 +#define LTQ_SPI_RXREQ_RXCNT_MASK       0xFFFF
8181 +#define LTQ_SPI_RXCNT_TODO_MASK                0xFFFF
8182 +
8183 +#define LTQ_SPI_GPIO_DIN               16
8184 +#define LTQ_SPI_GPIO_DOUT              17
8185 +#define LTQ_SPI_GPIO_CLK               18
8186 +
8187 +struct ltq_spi_regs {
8188 +       __be32  clc;            /* Clock control */
8189 +       __be32  pisel;          /* Port input select */
8190 +       __be32  id;             /* Identification */
8191 +       __be32  rsvd0;
8192 +       __be32  con;            /* Control */
8193 +       __be32  stat;           /* Status */
8194 +       __be32  whbstate;       /* Write HW modified state */
8195 +       __be32  rsvd1;
8196 +       __be32  tb;             /* Transmit buffer */
8197 +       __be32  rb;             /* Receive buffer */
8198 +       __be32  rsvd2[2];
8199 +       __be32  rxfcon;         /* Recevie FIFO control */
8200 +       __be32  txfcon;         /* Transmit FIFO control */
8201 +       __be32  fstat;          /* FIFO status */
8202 +       __be32  rsvd3;
8203 +       __be32  brt;            /* Baudrate timer */
8204 +       __be32  brstat;         /* Baudrate timer status */
8205 +       __be32  rsvd4[6];
8206 +       __be32  sfcon;          /* Serial frame control */
8207 +       __be32  sfstat;         /* Serial frame status */
8208 +       __be32  rsvd5[2];
8209 +       __be32  gpocon;         /* General purpose output control */
8210 +       __be32  gpostat;        /* General purpose output status */
8211 +       __be32  fgpo;           /* Force general purpose output */
8212 +       __be32  rsvd6;
8213 +       __be32  rxreq;          /* Receive request */
8214 +       __be32  rxcnt;          /* Receive count */
8215 +       __be32  rsvd7[25];
8216 +       __be32  dmacon;         /* DMA control */
8217 +       __be32  rsvd8;
8218 +       __be32  irnen;          /* Interrupt node enable */
8219 +       __be32  irnicr;         /* Interrupt node interrupt capture */
8220 +       __be32  irncr;          /* Interrupt node control */
8221 +};
8222 +
8223 +struct ltq_spi_drv_data {
8224 +       struct ltq_spi_regs __iomem *regs;
8225 +
8226 +       struct spi_slave slave;
8227 +       unsigned int max_hz;
8228 +       unsigned int mode;
8229 +       unsigned int tx_todo;
8230 +       unsigned int rx_todo;
8231 +       unsigned int rx_req;
8232 +       unsigned int bits_per_word;
8233 +       unsigned int speed_hz;
8234 +       const u8 *tx;
8235 +       u8 *rx;
8236 +       int status;
8237 +};
8238 +
8239 +static struct ltq_spi_drv_data *to_ltq_spi_slave(struct spi_slave *slave)
8240 +{
8241 +       return container_of(slave, struct ltq_spi_drv_data, slave);
8242 +}
8243 +
8244 +#ifdef CONFIG_SPL_BUILD
8245 +/*
8246 + * We do not have or want malloc in a SPI flash SPL.
8247 + * Neither we have to support multiple SPI slaves. Thus we put the
8248 + * SPI slave context in BSS for SPL builds.
8249 + */
8250 +static struct ltq_spi_drv_data ltq_spi_slave;
8251 +
8252 +static struct ltq_spi_drv_data *ltq_spi_slave_alloc(unsigned int bus,
8253 +                                                       unsigned int cs)
8254 +{
8255 +       ltq_spi_slave.slave.bus = bus;
8256 +       ltq_spi_slave.slave.cs = cs;
8257 +
8258 +       return &ltq_spi_slave;
8259 +}
8260 +
8261 +static void ltq_spi_slave_free(struct spi_slave *slave)
8262 +{
8263 +}
8264 +#else
8265 +static struct ltq_spi_drv_data *ltq_spi_slave_alloc(unsigned int bus,
8266 +                                                       unsigned int cs)
8267 +{
8268 +       return spi_alloc_slave(struct ltq_spi_drv_data, bus, cs);
8269 +}
8270 +
8271 +static void ltq_spi_slave_free(struct spi_slave *slave)
8272 +{
8273 +       struct ltq_spi_drv_data *drv;
8274 +
8275 +       if (slave) {
8276 +               drv = to_ltq_spi_slave(slave);
8277 +               free(drv);
8278 +       }
8279 +}
8280 +#endif
8281 +
8282 +static unsigned int tx_fifo_size(struct ltq_spi_drv_data *drv)
8283 +{
8284 +       u32 id = ltq_readl(&drv->regs->id);
8285 +
8286 +       return (id & LTQ_SPI_ID_TXFS_MASK) >> LTQ_SPI_ID_TXFS_SHIFT;
8287 +}
8288 +
8289 +static unsigned int rx_fifo_size(struct ltq_spi_drv_data *drv)
8290 +{
8291 +       u32 id = ltq_readl(&drv->regs->id);
8292 +
8293 +       return (id & LTQ_SPI_ID_RXFS_MASK) >> LTQ_SPI_ID_RXFS_SHIFT;
8294 +}
8295 +
8296 +static unsigned int tx_fifo_level(struct ltq_spi_drv_data *drv)
8297 +{
8298 +       u32 fstat = ltq_readl(&drv->regs->fstat);
8299 +
8300 +       return (fstat & LTQ_SPI_FSTAT_TXFFL_MASK) >> LTQ_SPI_FSTAT_TXFFL_SHIFT;
8301 +}
8302 +
8303 +static unsigned int rx_fifo_level(struct ltq_spi_drv_data *drv)
8304 +{
8305 +       u32 fstat = ltq_readl(&drv->regs->fstat);
8306 +
8307 +       return fstat & LTQ_SPI_FSTAT_RXFFL_MASK;
8308 +}
8309 +
8310 +static unsigned int tx_fifo_free(struct ltq_spi_drv_data *drv)
8311 +{
8312 +       return tx_fifo_size(drv) - tx_fifo_level(drv);
8313 +}
8314 +
8315 +static void hw_power_on(struct ltq_spi_drv_data *drv)
8316 +{
8317 +       u32 clc;
8318 +
8319 +       /* Power-up mdule */
8320 +       ltq_pm_enable(LTQ_PM_SPI);
8321 +
8322 +       /*
8323 +        * Set clock divider for run mode to 1 to
8324 +        * run at same frequency as FPI bus
8325 +        */
8326 +       clc = (1 << LTQ_SPI_CLC_RMC_SHIFT);
8327 +       ltq_writel(&drv->regs->clc, clc);
8328 +}
8329 +
8330 +static void hw_reset_fifos(struct ltq_spi_drv_data *drv)
8331 +{
8332 +       u32 val;
8333 +
8334 +       val = LTQ_SPI_TXFCON_TXFEN | LTQ_SPI_TXFCON_TXFLU;
8335 +       ltq_writel(&drv->regs->txfcon, val);
8336 +
8337 +       val = LTQ_SPI_RXFCON_RXFEN | LTQ_SPI_RXFCON_RXFLU;
8338 +       ltq_writel(&drv->regs->rxfcon, val);
8339 +}
8340 +
8341 +static int hw_is_busy(struct ltq_spi_drv_data *drv)
8342 +{
8343 +       u32 stat = ltq_readl(&drv->regs->stat);
8344 +
8345 +       return stat & LTQ_SPI_STAT_BSY;
8346 +}
8347 +
8348 +static void hw_enter_config_mode(struct ltq_spi_drv_data *drv)
8349 +{
8350 +       ltq_writel(&drv->regs->whbstate, LTQ_SPI_WHBSTATE_CLREN);
8351 +}
8352 +
8353 +static void hw_enter_active_mode(struct ltq_spi_drv_data *drv)
8354 +{
8355 +       ltq_writel(&drv->regs->whbstate, LTQ_SPI_WHBSTATE_SETEN);
8356 +}
8357 +
8358 +static void hw_setup_speed_hz(struct ltq_spi_drv_data *drv,
8359 +                               unsigned int max_speed_hz)
8360 +{
8361 +       unsigned int spi_hz, speed_hz, brt;
8362 +
8363 +       /*
8364 +        * SPI module clock is derived from FPI bus clock dependent on
8365 +        * divider value in CLC.RMS which is always set to 1.
8366 +        *
8367 +        *                 f_SPI
8368 +        * baudrate = --------------
8369 +        *             2 * (BR + 1)
8370 +        */
8371 +       spi_hz = ltq_get_bus_clock() / 2;
8372 +
8373 +       /* TODO: optimize baudrate calculation */
8374 +       for (brt = 0; brt < 0xFFFF; brt++) {
8375 +               speed_hz = spi_hz / (brt + 1);
8376 +               if (speed_hz <= max_speed_hz)
8377 +                       break;
8378 +       }
8379 +
8380 +       ltq_writel(&drv->regs->brt, brt);
8381 +}
8382 +
8383 +static void hw_setup_bits_per_word(struct ltq_spi_drv_data *drv,
8384 +                                       unsigned int bits_per_word)
8385 +{
8386 +       u32 bm;
8387 +
8388 +       /* CON.BM value = bits_per_word - 1 */
8389 +       bm = (bits_per_word - 1) << LTQ_SPI_CON_BM_SHIFT;
8390 +
8391 +       ltq_clrsetbits(&drv->regs->con, LTQ_SPI_CON_BM_MASK, bm);
8392 +}
8393 +
8394 +static void hw_setup_clock_mode(struct ltq_spi_drv_data *drv, unsigned int mode)
8395 +{
8396 +       u32 con_set = 0, con_clr = 0;
8397 +
8398 +       /*
8399 +        * SPI mode mapping in CON register:
8400 +        * Mode CPOL CPHA CON.PO CON.PH
8401 +        *  0    0    0      0      1
8402 +        *  1    0    1      0      0
8403 +        *  2    1    0      1      1
8404 +        *  3    1    1      1      0
8405 +        */
8406 +       if (mode & SPI_CPHA)
8407 +               con_clr |= LTQ_SPI_CON_PH;
8408 +       else
8409 +               con_set |= LTQ_SPI_CON_PH;
8410 +
8411 +       if (mode & SPI_CPOL)
8412 +               con_set |= LTQ_SPI_CON_PO | LTQ_SPI_CON_IDLE;
8413 +       else
8414 +               con_clr |= LTQ_SPI_CON_PO | LTQ_SPI_CON_IDLE;
8415 +
8416 +       /* Set heading control */
8417 +       if (mode & SPI_LSB_FIRST)
8418 +               con_clr |= LTQ_SPI_CON_HB;
8419 +       else
8420 +               con_set |= LTQ_SPI_CON_HB;
8421 +
8422 +       /* Set loopback mode */
8423 +       if (mode & SPI_LOOP)
8424 +               con_set |= LTQ_SPI_CON_LB;
8425 +       else
8426 +               con_clr |= LTQ_SPI_CON_LB;
8427 +
8428 +       ltq_clrsetbits(&drv->regs->con, con_clr, con_set);
8429 +}
8430 +
8431 +static void hw_set_rxtx(struct ltq_spi_drv_data *drv)
8432 +{
8433 +       u32 con;
8434 +
8435 +       /* Configure transmitter and receiver */
8436 +       con = ltq_readl(&drv->regs->con);
8437 +       if (drv->tx)
8438 +               con &= ~LTQ_SPI_CON_TXOFF;
8439 +       else
8440 +               con |= LTQ_SPI_CON_TXOFF;
8441 +
8442 +       if (drv->rx)
8443 +               con &= ~LTQ_SPI_CON_RXOFF;
8444 +       else
8445 +               con |= LTQ_SPI_CON_RXOFF;
8446 +
8447 +       ltq_writel(&drv->regs->con, con);
8448 +}
8449 +
8450 +static void hw_init(struct ltq_spi_drv_data *drv)
8451 +{
8452 +       hw_power_on(drv);
8453 +
8454 +       /* Put controller into config mode */
8455 +       hw_enter_config_mode(drv);
8456 +
8457 +       /* Disable all interrupts */
8458 +       ltq_writel(&drv->regs->irnen, 0);
8459 +
8460 +       /* Clear error flags */
8461 +       ltq_clrsetbits(&drv->regs->whbstate, 0, LTQ_SPI_WHBSTATE_CLR_ERRORS);
8462 +
8463 +       /* Enable error checking, disable TX/RX */
8464 +       ltq_writel(&drv->regs->con, LTQ_SPI_CON_RUEN | LTQ_SPI_CON_AEN |
8465 +                       LTQ_SPI_CON_TEN | LTQ_SPI_CON_REN | LTQ_SPI_CON_TXOFF |
8466 +                       LTQ_SPI_CON_RXOFF);
8467 +
8468 +       /* Setup default SPI mode */
8469 +       drv->bits_per_word = 8;
8470 +       drv->speed_hz = 0;
8471 +       hw_setup_bits_per_word(drv, drv->bits_per_word);
8472 +       hw_setup_clock_mode(drv, SPI_MODE_0);
8473 +
8474 +       /* Enable master mode and clear error flags */
8475 +       ltq_writel(&drv->regs->whbstate, LTQ_SPI_WHBSTATE_SETMS |
8476 +                       LTQ_SPI_WHBSTATE_CLR_ERRORS);
8477 +
8478 +       /* Reset GPIO/CS registers */
8479 +       ltq_writel(&drv->regs->gpocon, 0);
8480 +       ltq_writel(&drv->regs->fgpo, 0xFF00);
8481 +
8482 +       /* Enable and flush FIFOs */
8483 +       hw_reset_fifos(drv);
8484 +
8485 +       /* SPI/DIN input */
8486 +       gpio_set_altfunc(16, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_IN);
8487 +       /* SPI/DOUT output */
8488 +       gpio_set_altfunc(17, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT);
8489 +       /* SPI/CLK output */
8490 +       gpio_set_altfunc(18, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT);
8491 +}
8492 +
8493 +static void tx_fifo_write(struct ltq_spi_drv_data *drv)
8494 +{
8495 +       const u8 *tx8;
8496 +       const u16 *tx16;
8497 +       const u32 *tx32;
8498 +       u32 data;
8499 +       unsigned int tx_free = tx_fifo_free(drv);
8500 +
8501 +       while (drv->tx_todo && tx_free) {
8502 +               switch (drv->bits_per_word) {
8503 +               case 8:
8504 +                       tx8 = drv->tx;
8505 +                       data = *tx8;
8506 +                       drv->tx_todo--;
8507 +                       drv->tx++;
8508 +                       break;
8509 +               case 16:
8510 +                       tx16 = (u16 *) drv->tx;
8511 +                       data = *tx16;
8512 +                       drv->tx_todo -= 2;
8513 +                       drv->tx += 2;
8514 +                       break;
8515 +               case 32:
8516 +                       tx32 = (u32 *) drv->tx;
8517 +                       data = *tx32;
8518 +                       drv->tx_todo -= 4;
8519 +                       drv->tx += 4;
8520 +                       break;
8521 +               default:
8522 +                       return;
8523 +               }
8524 +
8525 +               ltq_writel(&drv->regs->tb, data);
8526 +               tx_free--;
8527 +       }
8528 +}
8529 +
8530 +static void rx_fifo_read_full_duplex(struct ltq_spi_drv_data *drv)
8531 +{
8532 +       u8 *rx8;
8533 +       u16 *rx16;
8534 +       u32 *rx32;
8535 +       u32 data;
8536 +       unsigned int rx_fill = rx_fifo_level(drv);
8537 +
8538 +       while (rx_fill) {
8539 +               data = ltq_readl(&drv->regs->rb);
8540 +
8541 +               switch (drv->bits_per_word) {
8542 +               case 8:
8543 +                       rx8 = drv->rx;
8544 +                       *rx8 = data;
8545 +                       drv->rx_todo--;
8546 +                       drv->rx++;
8547 +                       break;
8548 +               case 16:
8549 +                       rx16 = (u16 *) drv->rx;
8550 +                       *rx16 = data;
8551 +                       drv->rx_todo -= 2;
8552 +                       drv->rx += 2;
8553 +                       break;
8554 +               case 32:
8555 +                       rx32 = (u32 *) drv->rx;
8556 +                       *rx32 = data;
8557 +                       drv->rx_todo -= 4;
8558 +                       drv->rx += 4;
8559 +                       break;
8560 +               default:
8561 +                       return;
8562 +               }
8563 +
8564 +               rx_fill--;
8565 +       }
8566 +}
8567 +
8568 +static void rx_fifo_read_half_duplex(struct ltq_spi_drv_data *drv)
8569 +{
8570 +       u32 data, *rx32;
8571 +       u8 *rx8;
8572 +       unsigned int rxbv, shift;
8573 +       unsigned int rx_fill = rx_fifo_level(drv);
8574 +
8575 +       /*
8576 +        * In RX-only mode the bits per word value is ignored by HW. A value
8577 +        * of 32 is used instead. Thus all 4 bytes per FIFO must be read.
8578 +        * If remaining RX bytes are less than 4, the FIFO must be read
8579 +        * differently. The amount of received and valid bytes is indicated
8580 +        * by STAT.RXBV register value.
8581 +        */
8582 +       while (rx_fill) {
8583 +               if (drv->rx_todo < 4) {
8584 +                       rxbv = (ltq_readl(&drv->regs->stat) &
8585 +                               LTQ_SPI_STAT_RXBV_MASK) >>
8586 +                               LTQ_SPI_STAT_RXBV_SHIFT;
8587 +                       data = ltq_readl(&drv->regs->rb);
8588 +
8589 +                       shift = (rxbv - 1) * 8;
8590 +                       rx8 = drv->rx;
8591 +
8592 +                       while (rxbv) {
8593 +                               *rx8++ = (data >> shift) & 0xFF;
8594 +                               rxbv--;
8595 +                               shift -= 8;
8596 +                               drv->rx_todo--;
8597 +                               drv->rx++;
8598 +
8599 +                               if (drv->rx_req)
8600 +                                       drv->rx_req --;
8601 +                       }
8602 +               } else {
8603 +                       data = ltq_readl(&drv->regs->rb);
8604 +                       rx32 = (u32 *) drv->rx;
8605 +
8606 +                       *rx32++ = data;
8607 +                       drv->rx_todo -= 4;
8608 +                       drv->rx += 4;
8609 +
8610 +                       if (drv->rx_req >= 4)
8611 +                               drv->rx_req -= 4;
8612 +               }
8613 +               rx_fill--;
8614 +       }
8615 +}
8616 +
8617 +static void rx_request(struct ltq_spi_drv_data *drv)
8618 +{
8619 +       unsigned int rxreq, rxreq_max;
8620 +
8621 +       if (drv->rx_req)
8622 +               return;
8623 +
8624 +       /*
8625 +        * To avoid receive overflows at high clocks it is better to request
8626 +        * only the amount of bytes that fits into all FIFOs. This value
8627 +        * depends on the FIFO size implemented in hardware.
8628 +        */
8629 +       rxreq = drv->rx_todo;
8630 +       rxreq_max = rx_fifo_size(drv) * 4;
8631 +       if (rxreq > rxreq_max)
8632 +               rxreq = rxreq_max;
8633 +
8634 +       drv->rx_req = rxreq;
8635 +       ltq_writel(&drv->regs->rxreq, rxreq);
8636 +}
8637 +
8638 +void spi_init(void)
8639 +{
8640 +}
8641 +
8642 +struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
8643 +                                 unsigned int max_hz, unsigned int mode)
8644 +{
8645 +       struct ltq_spi_drv_data *drv;
8646 +
8647 +       if (!spi_cs_is_valid(bus, cs))
8648 +               return NULL;
8649 +
8650 +       drv = ltq_spi_slave_alloc(bus, cs);
8651 +       if (!drv)
8652 +               return NULL;
8653 +
8654 +       drv->regs = (struct ltq_spi_regs *) CKSEG1ADDR(LTQ_SPI_BASE);
8655 +
8656 +       hw_init(drv);
8657 +
8658 +       drv->max_hz = max_hz;
8659 +       drv->mode = mode;
8660 +
8661 +       return &drv->slave;
8662 +}
8663 +
8664 +void spi_free_slave(struct spi_slave *slave)
8665 +{
8666 +       ltq_spi_slave_free(slave);
8667 +}
8668 +
8669 +static int ltq_spi_wait_ready(struct ltq_spi_drv_data *drv)
8670 +{
8671 +       const unsigned long timeout = 20000;
8672 +       unsigned long timebase;
8673 +
8674 +       timebase = get_timer(0);
8675 +
8676 +       do {
8677 +               WATCHDOG_RESET();
8678 +
8679 +               if (!hw_is_busy(drv))
8680 +                       return 0;
8681 +       } while (get_timer(timebase) < timeout);
8682 +
8683 +       return 1;
8684 +}
8685 +
8686 +int spi_claim_bus(struct spi_slave *slave)
8687 +{
8688 +       struct ltq_spi_drv_data *drv = to_ltq_spi_slave(slave);
8689 +       int ret;
8690 +
8691 +       ret = ltq_spi_wait_ready(drv);
8692 +       if (ret) {
8693 +               debug("cannot claim bus\n");
8694 +               return ret;
8695 +       }
8696 +
8697 +       hw_enter_config_mode(drv);
8698 +       hw_setup_clock_mode(drv, drv->mode);
8699 +       hw_setup_speed_hz(drv, drv->max_hz);
8700 +       hw_setup_bits_per_word(drv, drv->bits_per_word);
8701 +       hw_enter_active_mode(drv);
8702 +
8703 +       return 0;
8704 +}
8705 +
8706 +void spi_release_bus(struct spi_slave *slave)
8707 +{
8708 +       struct ltq_spi_drv_data *drv = to_ltq_spi_slave(slave);
8709 +
8710 +       hw_enter_config_mode(drv);
8711 +}
8712 +
8713 +int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
8714 +               const void *dout, void *din, unsigned long flags)
8715 +{
8716 +
8717 +       struct ltq_spi_drv_data *drv = to_ltq_spi_slave(slave);
8718 +       int ret = 0;
8719 +
8720 +       if (bitlen % 8)
8721 +               return 1;
8722 +
8723 +       if (!bitlen) {
8724 +               ret = 0;
8725 +               goto done;
8726 +       }
8727 +
8728 +       if (flags & SPI_XFER_BEGIN)
8729 +               spi_cs_activate(slave);
8730 +
8731 +       drv->tx = dout;
8732 +       drv->tx_todo = 0;
8733 +       drv->rx = din;
8734 +       drv->rx_todo = 0;
8735 +       hw_set_rxtx(drv);
8736 +
8737 +       if (drv->tx) {
8738 +               drv->tx_todo = bitlen / 8;
8739 +
8740 +               tx_fifo_write(drv);
8741 +       }
8742 +
8743 +       if (drv->rx) {
8744 +               drv->rx_todo = bitlen / 8;
8745 +
8746 +               if (!drv->tx)
8747 +                       rx_request(drv);
8748 +       }
8749 +
8750 +       for (;;) {
8751 +               if (drv->tx) {
8752 +                       if (drv->rx && drv->rx_todo)
8753 +                               rx_fifo_read_full_duplex(drv);
8754 +
8755 +                       if (drv->tx_todo)
8756 +                               tx_fifo_write(drv);
8757 +                       else
8758 +                               goto done;
8759 +               } else if (drv->rx) {
8760 +                       if (drv->rx_todo) {
8761 +                               rx_fifo_read_half_duplex(drv);
8762 +
8763 +                               if (drv->rx_todo)
8764 +                                       rx_request(drv);
8765 +                               else
8766 +                                       goto done;
8767 +                       } else {
8768 +                               goto done;
8769 +                       }
8770 +               }
8771 +       }
8772 +
8773 +done:
8774 +       ret = ltq_spi_wait_ready(drv);
8775 +
8776 +       drv->rx = NULL;
8777 +       drv->tx = NULL;
8778 +       hw_set_rxtx(drv);
8779 +
8780 +       if (flags & SPI_XFER_END)
8781 +               spi_cs_deactivate(slave);
8782 +
8783 +       return ret;
8784 +}
8785 --- /dev/null
8786 +++ b/include/configs/easy50712.h
8787 @@ -0,0 +1,79 @@
8788 +/*
8789 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
8790 + *
8791 + * SPDX-License-Identifier:    GPL-2.0+
8792 + */
8793 +
8794 +#ifndef __CONFIG_H
8795 +#define __CONFIG_H
8796 +
8797 +#define CONFIG_MACH_TYPE       "EASY50712"
8798 +#define CONFIG_IDENT_STRING    " "CONFIG_MACH_TYPE
8799 +#define CONFIG_BOARD_NAME      "Lantiq EASY50712 Danube Reference Board"
8800 +
8801 +/* Configure SoC */
8802 +#define CONFIG_LTQ_SUPPORT_UART                /* Enable ASC and UART */
8803 +
8804 +#define CONFIG_LTQ_SUPPORT_ETHERNET    /* Enable ethernet */
8805 +
8806 +#define CONFIG_LTQ_SUPPORT_NOR_FLASH   /* Have a parallel NOR flash */
8807 +
8808 +#define CONFIG_LTQ_SUPPORT_SPI_FLASH
8809 +#define CONFIG_SPI_FLASH_ATMEL         /* Have an AT45DB321D serial flash */
8810 +
8811 +#define CONFIG_LTQ_SUPPORT_NAND_FLASH
8812 +
8813 +#define CONFIG_LTQ_SUPPORT_SPL_NOR_FLASH       /* Build NOR flash SPL */
8814 +
8815 +#define CONFIG_LTQ_SPL_COMP_LZO
8816 +#define CONFIG_LTQ_SPL_CONSOLE
8817 +
8818 +/* Switch devices */
8819 +#define CONFIG_SWITCH_MULTI
8820 +#define CONFIG_SWITCH_ADM6996I
8821 +
8822 +/* Environment */
8823 +#define CONFIG_ENV_SPI_BUS             0
8824 +#define CONFIG_ENV_SPI_CS              2
8825 +#define CONFIG_ENV_SPI_MAX_HZ          20000000
8826 +#define CONFIG_ENV_SPI_MODE            0
8827 +
8828 +#if defined(CONFIG_SYS_BOOT_NOR)
8829 +#define CONFIG_ENV_IS_IN_FLASH
8830 +#define CONFIG_ENV_OVERWRITE
8831 +#define CONFIG_ENV_OFFSET              (256 * 1024)
8832 +#define CONFIG_ENV_SECT_SIZE           (64 * 1024)
8833 +#elif defined(CONFIG_SYS_BOOT_NORSPL)
8834 +#define CONFIG_ENV_IS_IN_FLASH
8835 +#define CONFIG_ENV_OVERWRITE
8836 +#define CONFIG_ENV_OFFSET              (128 * 1024)
8837 +#define CONFIG_ENV_SECT_SIZE           (64 * 1024)
8838 +#else
8839 +#define CONFIG_ENV_IS_NOWHERE
8840 +#endif
8841 +
8842 +#define CONFIG_ENV_SIZE                        (8 * 1024)
8843 +
8844 +#define CONFIG_LOADADDR                        CONFIG_SYS_LOAD_ADDR
8845 +
8846 +/* Console */
8847 +#define CONFIG_LTQ_ADVANCED_CONSOLE
8848 +#define CONFIG_BAUDRATE                        115200
8849 +#define CONFIG_CONSOLE_ASC             1
8850 +#define CONFIG_CONSOLE_DEV             "ttyLTQ1"
8851 +
8852 +/* Commands */
8853 +#define CONFIG_CMD_PING
8854 +
8855 +/* Pull in default board configs for Lantiq XWAY Danube */
8856 +#include <asm/lantiq/config.h>
8857 +#include <asm/arch/config.h>
8858 +
8859 +#define CONFIG_ENV_UPDATE_UBOOT_NOR                                    \
8860 +       "update-uboot-nor=run load-uboot-norspl-lzo write-uboot-nor\0"
8861 +
8862 +#define CONFIG_EXTRA_ENV_SETTINGS      \
8863 +       CONFIG_ENV_LANTIQ_DEFAULTS      \
8864 +       CONFIG_ENV_UPDATE_UBOOT_NOR
8865 +
8866 +#endif /* __CONFIG_H */
8867 --- /dev/null
8868 +++ b/include/configs/easy80920.h
8869 @@ -0,0 +1,92 @@
8870 +/*
8871 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
8872 + *
8873 + * SPDX-License-Identifier:    GPL-2.0+
8874 + */
8875 +
8876 +#ifndef __CONFIG_H
8877 +#define __CONFIG_H
8878 +
8879 +#define CONFIG_MACH_TYPE       "EASY80920"
8880 +#define CONFIG_IDENT_STRING    " "CONFIG_MACH_TYPE
8881 +#define CONFIG_BOARD_NAME      "Lantiq EASY80920 VRX200 Family Board"
8882 +
8883 +/* Configure SoC */
8884 +#define CONFIG_LTQ_SUPPORT_UART                /* Enable ASC and UART */
8885 +
8886 +#define CONFIG_LTQ_SUPPORT_ETHERNET    /* Enable ethernet */
8887 +
8888 +#define CONFIG_LTQ_SUPPORT_NOR_FLASH   /* Have a parallel NOR flash */
8889 +
8890 +#define CONFIG_LTQ_SUPPORT_SPI_FLASH
8891 +#define CONFIG_SPI_FLASH_MACRONIX      /* Have a MX29LV620 serial flash */
8892 +
8893 +#define CONFIG_LTQ_SUPPORT_NAND_FLASH
8894 +
8895 +#define CONFIG_LTQ_SUPPORT_SPL_SPI_FLASH       /* Build SPI flash SPL */
8896 +#define CONFIG_SPL_SPI_BUS             0
8897 +#define CONFIG_SPL_SPI_CS              4
8898 +#define CONFIG_SPL_SPI_MAX_HZ          25000000
8899 +#define CONFIG_SPL_SPI_MODE            0
8900 +
8901 +#define CONFIG_LTQ_SUPPORT_SPL_NOR_FLASH       /* Build NOR flash SPL */
8902 +
8903 +#define CONFIG_LTQ_SPL_COMP_LZO
8904 +#define CONFIG_LTQ_SPL_CONSOLE
8905 +
8906 +#define CONFIG_SYS_DRAM_PROBE
8907 +
8908 +/* Environment */
8909 +#define CONFIG_ENV_SPI_BUS             CONFIG_SPL_SPI_BUS
8910 +#define CONFIG_ENV_SPI_CS              CONFIG_SPL_SPI_CS
8911 +#define CONFIG_ENV_SPI_MAX_HZ          CONFIG_SPL_SPI_MAX_HZ
8912 +#define CONFIG_ENV_SPI_MODE            CONFIG_SPL_SPI_MODE
8913 +
8914 +#if defined(CONFIG_SYS_BOOT_NOR)
8915 +#define CONFIG_ENV_IS_IN_FLASH
8916 +#define CONFIG_ENV_OVERWRITE
8917 +#define CONFIG_ENV_OFFSET              (384 * 1024)
8918 +#define CONFIG_ENV_SECT_SIZE           (64 * 1024)
8919 +#elif defined(CONFIG_SYS_BOOT_NORSPL)
8920 +#define CONFIG_ENV_IS_IN_FLASH
8921 +#define CONFIG_ENV_OVERWRITE
8922 +#define CONFIG_ENV_OFFSET              (192 * 1024)
8923 +#define CONFIG_ENV_SECT_SIZE           (64 * 1024)
8924 +#elif defined(CONFIG_SYS_BOOT_SFSPL)
8925 +#define CONFIG_ENV_IS_IN_SPI_FLASH
8926 +#define CONFIG_ENV_OVERWRITE
8927 +#define CONFIG_ENV_OFFSET              (192 * 1024)
8928 +#define CONFIG_ENV_SECT_SIZE           (64 * 1024)
8929 +#else
8930 +#define CONFIG_ENV_IS_NOWHERE
8931 +#endif
8932 +
8933 +#define CONFIG_ENV_SIZE                        (8 * 1024)
8934 +
8935 +#define CONFIG_LOADADDR                        CONFIG_SYS_LOAD_ADDR
8936 +
8937 +/* Console */
8938 +#define CONFIG_LTQ_ADVANCED_CONSOLE
8939 +#define CONFIG_BAUDRATE                        115200
8940 +#define CONFIG_CONSOLE_ASC             1
8941 +#define CONFIG_CONSOLE_DEV             "ttyLTQ1"
8942 +
8943 +/* Commands */
8944 +#define CONFIG_CMD_PING
8945 +
8946 +/* Pull in default board configs for Lantiq XWAY VRX200 */
8947 +#include <asm/lantiq/config.h>
8948 +#include <asm/arch/config.h>
8949 +
8950 +#define CONFIG_ENV_UPDATE_UBOOT_NOR                                    \
8951 +       "update-uboot-nor=run load-uboot-norspl-lzo write-uboot-nor\0"
8952 +
8953 +#define CONFIG_ENV_UPDATE_UBOOT_SF                                     \
8954 +       "update-uboot-sf=run load-uboot-sfspl-lzo write-uboot-sf\0"
8955 +
8956 +#define CONFIG_EXTRA_ENV_SETTINGS      \
8957 +       CONFIG_ENV_LANTIQ_DEFAULTS      \
8958 +       CONFIG_ENV_UPDATE_UBOOT_NOR     \
8959 +       CONFIG_ENV_UPDATE_UBOOT_SF
8960 +
8961 +#endif /* __CONFIG_H */
8962 --- a/include/phy.h
8963 +++ b/include/phy.h
8964 @@ -214,6 +214,7 @@ int phy_atheros_init(void);
8965  int phy_broadcom_init(void);
8966  int phy_davicom_init(void);
8967  int phy_et1011c_init(void);
8968 +int phy_lantiq_init(void);
8969  int phy_lxt_init(void);
8970  int phy_marvell_init(void);
8971  int phy_micrel_init(void);
8972 --- a/spl/Makefile
8973 +++ b/spl/Makefile
8974 @@ -100,6 +100,8 @@ LIBS-$(CONFIG_SPL_USBETH_SUPPORT) += dri
8975  LIBS-$(CONFIG_SPL_MUSB_NEW_SUPPORT) += drivers/usb/musb-new/libusb_musb-new.o
8976  LIBS-$(CONFIG_SPL_USBETH_SUPPORT) += drivers/usb/gadget/libusb_gadget.o
8977  LIBS-$(CONFIG_SPL_WATCHDOG_SUPPORT) += drivers/watchdog/libwatchdog.o
8978 +LIBS-$(CONFIG_SPL_LZMA_SUPPORT) += lib/lzma/liblzma.o
8979 +LIBS-$(CONFIG_SPL_LZO_SUPPORT) += lib/lzo/liblzo.o
8980  
8981  ifneq ($(CONFIG_OMAP_COMMON),)
8982  LIBS-y += $(CPUDIR)/omap-common/libomap-common.o
8983 --- a/tools/.gitignore
8984 +++ b/tools/.gitignore
8985 @@ -2,6 +2,7 @@
8986  /envcrc
8987  /gen_eth_addr
8988  /img2srec
8989 +/ltq-boot-image
8990  /kwboot
8991  /mkenvimage
8992  /mkimage
8993 --- a/tools/Makefile
8994 +++ b/tools/Makefile
8995 @@ -49,6 +49,7 @@ BIN_FILES-$(CONFIG_VIDEO_LOGO) += bmp_lo
8996  BIN_FILES-$(CONFIG_BUILD_ENVCRC) += envcrc$(SFX)
8997  BIN_FILES-$(CONFIG_CMD_NET) += gen_eth_addr$(SFX)
8998  BIN_FILES-$(CONFIG_CMD_LOADS) += img2srec$(SFX)
8999 +BIN_FILES-$(CONFIG_SOC_LANTIQ) += ltq-boot-image$(SFX)
9000  BIN_FILES-$(CONFIG_XWAY_SWAP_BYTES) += xway-swap-bytes$(SFX)
9001  BIN_FILES-y += mkenvimage$(SFX)
9002  BIN_FILES-y += mkimage$(SFX)
9003 @@ -95,6 +96,7 @@ OBJ_FILES-$(CONFIG_MX28) += mxsboot.o
9004  OBJ_FILES-$(CONFIG_NETCONSOLE) += ncb.o
9005  OBJ_FILES-$(CONFIG_SHA1_CHECK_UB_IMG) += ubsha1.o
9006  OBJ_FILES-$(CONFIG_SMDK5250) += mkexynosspl.o
9007 +OBJ_FILES-$(CONFIG_SOC_LANTIQ) += ltq-boot-image.o
9008  OBJ_FILES-$(CONFIG_VIDEO_LOGO) += bmp_logo.o
9009  OBJ_FILES-$(CONFIG_XWAY_SWAP_BYTES) += xway-swap-bytes.o
9010  
9011 @@ -195,6 +197,10 @@ $(obj)img2srec$(SFX):      $(obj)img2srec.o
9012         $(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^
9013         $(HOSTSTRIP) $@
9014  
9015 +$(obj)ltq-boot-image$(SFX):    $(obj)ltq-boot-image.o
9016 +       $(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^
9017 +       $(HOSTSTRIP) $@
9018 +
9019  $(obj)xway-swap-bytes$(SFX):   $(obj)xway-swap-bytes.o
9020         $(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^
9021         $(HOSTSTRIP) $@
9022 --- /dev/null
9023 +++ b/tools/ltq-boot-image.c
9024 @@ -0,0 +1,315 @@
9025 +/*
9026 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
9027 + *
9028 + * SPDX-License-Identifier:    GPL-2.0+
9029 + */
9030 +
9031 +#include <stdio.h>
9032 +#include <stdlib.h>
9033 +#include <string.h>
9034 +#include <unistd.h>
9035 +#include <getopt.h>
9036 +#include <compiler.h>
9037 +#include <sys/stat.h>
9038 +
9039 +enum image_types {
9040 +       IMAGE_NONE,
9041 +       IMAGE_SFSPL
9042 +};
9043 +
9044 +/* Lantiq non-volatile bootstrap command IDs */
9045 +enum nvb_cmd_ids {
9046 +       NVB_CMD_DEBUG   = 0x11,
9047 +       NVB_CMD_REGCFG  = 0x22,
9048 +       NVB_CMD_IDWNLD  = 0x33,
9049 +       NVB_CMD_CDWNLD  = 0x44,
9050 +       NVB_CMD_DWNLD   = 0x55,
9051 +       NVB_CMD_IFCFG   = 0x66,
9052 +       NVB_CMD_START   = 0x77
9053 +};
9054 +
9055 +/* Lantiq non-volatile bootstrap command flags */
9056 +enum nvb_cmd_flags {
9057 +       NVB_FLAG_START  = 1,
9058 +       NVB_FLAG_DEC    = (1 << 1),
9059 +       NVB_FLAG_DBG    = (1 << 2),
9060 +       NVB_FLAG_SDBG   = (1 << 3),
9061 +       NVB_FLAG_CFG0   = (1 << 4),
9062 +       NVB_FLAG_CFG1   = (1 << 5),
9063 +       NVB_FLAG_CFG2   = (1 << 6),
9064 +       NVB_FLAG_RST    = (1 << 7)
9065 +};
9066 +
9067 +struct args {
9068 +       enum image_types type;
9069 +       __u32           entry_addr;
9070 +       const char      *uboot_bin;
9071 +       const char      *spl_bin;
9072 +       const char      *out_bin;
9073 +};
9074 +
9075 +static void usage_msg(const char *name)
9076 +{
9077 +       fprintf(stderr, "%s: [-h] -t type -e entry-addr -u uboot-bin [-s spl-bin] -o out-bin\n",
9078 +               name);
9079 +       fprintf(stderr, " Image types:\n"
9080 +                       "  sfspl  - SPL + [compressed] U-Boot for SPI flash\n");
9081 +}
9082 +
9083 +static enum image_types parse_image_type(const char *type)
9084 +{
9085 +       if (!type)
9086 +               return IMAGE_NONE;
9087 +
9088 +       if (!strncmp(type, "sfspl", 6))
9089 +               return IMAGE_SFSPL;
9090 +
9091 +       return IMAGE_NONE;
9092 +}
9093 +
9094 +static int parse_args(int argc, char *argv[], struct args *arg)
9095 +{
9096 +       int opt;
9097 +
9098 +       memset(arg, 0, sizeof(*arg));
9099 +
9100 +       while ((opt = getopt(argc, argv, "ht:e:u:s:o:")) != -1) {
9101 +               switch (opt) {
9102 +               case 'h':
9103 +                       usage_msg(argv[0]);
9104 +                       return 1;
9105 +               case 't':
9106 +                       arg->type = parse_image_type(optarg);
9107 +                       break;
9108 +               case 'e':
9109 +                       arg->entry_addr = strtoul(optarg, NULL, 16);
9110 +                       break;
9111 +               case 'u':
9112 +                       arg->uboot_bin = optarg;
9113 +                       break;
9114 +               case 's':
9115 +                       arg->spl_bin = optarg;
9116 +                       break;
9117 +               case 'o':
9118 +                       arg->out_bin = optarg;
9119 +                       break;
9120 +               default:
9121 +                       fprintf(stderr, "Invalid option -%c\n", opt);
9122 +                       goto parse_error;
9123 +               }
9124 +       }
9125 +
9126 +       if (arg->type == IMAGE_NONE) {
9127 +               fprintf(stderr, "Invalid image type\n");
9128 +               goto parse_error;
9129 +       }
9130 +
9131 +       if (!arg->uboot_bin) {
9132 +               fprintf(stderr, "Missing U-Boot binary\n");
9133 +               goto parse_error;
9134 +       }
9135 +
9136 +       if (!arg->out_bin) {
9137 +               fprintf(stderr, "Missing output binary\n");
9138 +               goto parse_error;
9139 +       }
9140 +
9141 +       if (arg->type == IMAGE_SFSPL && !arg->spl_bin) {
9142 +               fprintf(stderr, "Missing SPL binary\n");
9143 +               goto parse_error;
9144 +       }
9145 +
9146 +       return 0;
9147 +
9148 +parse_error:
9149 +       usage_msg(argv[0]);
9150 +       return -1;
9151 +}
9152 +
9153 +static __u32 build_nvb_command(unsigned cmdid, unsigned cmdflags)
9154 +{
9155 +       __u32 cmd;
9156 +       __u16 tag;
9157 +
9158 +       tag = (cmdid << 8) | cmdflags;
9159 +       cmd = (tag << 16) | (0xFFFF - tag);
9160 +
9161 +       return cpu_to_be32(cmd);
9162 +}
9163 +
9164 +static int write_header(int fd, const void *hdr, size_t size)
9165 +{
9166 +       ssize_t n;
9167 +
9168 +       n = write(fd, hdr, size);
9169 +       if (n != size) {
9170 +               fprintf(stderr, "Cannot write header: %s\n",
9171 +                       strerror(errno));
9172 +               return -1;
9173 +       }
9174 +
9175 +       return 0;
9176 +}
9177 +
9178 +static int write_nvb_dwnld_header(int fd, size_t size, __u32 addr)
9179 +{
9180 +       __u32 hdr[3];
9181 +
9182 +       hdr[0] = build_nvb_command(NVB_CMD_DWNLD, NVB_FLAG_START |
9183 +                                       NVB_FLAG_SDBG);
9184 +       hdr[1] = cpu_to_be32(size + 4);
9185 +       hdr[2] = cpu_to_be32(addr);
9186 +
9187 +       return write_header(fd, hdr, sizeof(hdr));
9188 +}
9189 +
9190 +static int write_nvb_start_header(int fd, __u32 addr)
9191 +{
9192 +       __u32 hdr[3];
9193 +
9194 +       hdr[0] = build_nvb_command(NVB_CMD_START, NVB_FLAG_SDBG);
9195 +       hdr[1] = cpu_to_be32(4);
9196 +       hdr[2] = cpu_to_be32(addr);
9197 +
9198 +       return write_header(fd, hdr, sizeof(hdr));
9199 +}
9200 +
9201 +static int open_input_bin(const char *name, void **ptr, size_t *size)
9202 +{
9203 +       struct stat sbuf;
9204 +       int ret, fd;
9205 +
9206 +       fd = open(name, O_RDONLY | O_BINARY);
9207 +       if (0 > fd) {
9208 +               fprintf(stderr, "Cannot open %s: %s\n", name,
9209 +                       strerror(errno));
9210 +               return -1;
9211 +       }
9212 +
9213 +       ret = fstat(fd, &sbuf);
9214 +       if (0 > ret) {
9215 +               fprintf(stderr, "Cannot fstat %s: %s\n", name,
9216 +                       strerror(errno));
9217 +               return -1;
9218 +       }
9219 +
9220 +       *ptr = mmap(0, sbuf.st_size, PROT_READ, MAP_SHARED, fd, 0);
9221 +       if (*ptr == MAP_FAILED) {
9222 +               fprintf(stderr, "Cannot mmap %s: %s\n", name,
9223 +                       strerror(errno));
9224 +               return -1;
9225 +       }
9226 +
9227 +       *size = sbuf.st_size;
9228 +
9229 +       return fd;
9230 +}
9231 +
9232 +static void close_input_bin(int fd, void *ptr, size_t size)
9233 +{
9234 +       munmap(ptr, size);
9235 +       close(fd);
9236 +}
9237 +
9238 +static int copy_bin(int fd, void *ptr, size_t size)
9239 +{
9240 +       ssize_t n;
9241 +
9242 +       n = write(fd, ptr, size);
9243 +       if (n != size) {
9244 +               fprintf(stderr, "Cannot copy binary: %s\n", strerror(errno));
9245 +               return -1;
9246 +       }
9247 +
9248 +       return 0;
9249 +}
9250 +
9251 +static int open_output_bin(const char *name)
9252 +{
9253 +       int fd;
9254 +
9255 +       fd = open(name, O_RDWR | O_CREAT | O_TRUNC | O_BINARY, 0666);
9256 +       if (0 > fd) {
9257 +               fprintf(stderr, "Cannot open %s: %s\n", name,
9258 +                       strerror(errno));
9259 +               return -1;
9260 +       }
9261 +
9262 +       return fd;
9263 +}
9264 +
9265 +static int create_sfspl(const struct args *arg)
9266 +{
9267 +       int out_fd, uboot_fd, spl_fd, ret;
9268 +       void *uboot_ptr, *spl_ptr;
9269 +       size_t uboot_size, spl_size;
9270 +
9271 +       out_fd = open_output_bin(arg->out_bin);
9272 +       if (0 > out_fd)
9273 +               goto err;
9274 +
9275 +       spl_fd = open_input_bin(arg->spl_bin, &spl_ptr, &spl_size);
9276 +       if (0 > spl_fd)
9277 +               goto err_spl;
9278 +
9279 +       uboot_fd = open_input_bin(arg->uboot_bin, &uboot_ptr, &uboot_size);
9280 +       if (0 > uboot_fd)
9281 +               goto err_uboot;
9282 +
9283 +       ret = write_nvb_dwnld_header(out_fd, spl_size, arg->entry_addr);
9284 +       if (ret)
9285 +               goto err_write;
9286 +
9287 +       ret = copy_bin(out_fd, spl_ptr, spl_size);
9288 +       if (ret)
9289 +               goto err_write;
9290 +
9291 +       ret = write_nvb_start_header(out_fd, arg->entry_addr);
9292 +       if (ret)
9293 +               goto err_write;
9294 +
9295 +       ret = copy_bin(out_fd, uboot_ptr, uboot_size);
9296 +       if (ret)
9297 +               goto err_write;
9298 +
9299 +       close_input_bin(uboot_fd, uboot_ptr, uboot_size);
9300 +       close_input_bin(spl_fd, spl_ptr, spl_size);
9301 +       close(out_fd);
9302 +
9303 +       return 0;
9304 +
9305 +err_write:
9306 +       close_input_bin(uboot_fd, uboot_ptr, uboot_size);
9307 +err_uboot:
9308 +       close_input_bin(spl_fd, spl_ptr, spl_size);
9309 +err_spl:
9310 +       close(out_fd);
9311 +err:
9312 +       return -1;
9313 +}
9314 +
9315 +int main(int argc, char *argv[])
9316 +{
9317 +       int ret;
9318 +       struct args arg;
9319 +
9320 +       ret = parse_args(argc, argv, &arg);
9321 +       if (ret)
9322 +               goto done;
9323 +
9324 +       switch (arg.type) {
9325 +       case IMAGE_SFSPL:
9326 +               ret = create_sfspl(&arg);
9327 +               break;
9328 +       default:
9329 +               fprintf(stderr, "Image type not implemented\n");
9330 +               ret = -1;
9331 +               break;
9332 +       }
9333 +
9334 +done:
9335 +       if (ret >= 0)
9336 +               return EXIT_SUCCESS;
9337 +
9338 +       return EXIT_FAILURE;
9339 +}