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