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