ar71xx: build firmware image for the WNDR3700 v4 board
[openwrt/svn-archive/archive.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 +}