uboot-lantiq: update to v2013.10
[openwrt/svn-archive/archive.git] / package / boot / uboot-lantiq / patches / 0014-MIPS-add-support-for-Lantiq-XWAY-SoCs.patch
1 From 11553b0de8992ded6240d034bd49f561d17bea53 Mon Sep 17 00:00:00 2001
2 From: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
3 Date: Thu, 13 Jun 2013 01:18:02 +0200
4 Subject: MIPS: add support for Lantiq XWAY SoCs
5
6 Signed-off-by: Luka Perkov <luka@openwrt.org>
7 Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
8
9 diff --git a/.gitignore b/.gitignore
10 index a39bd54..7abdc37 100644
11 --- a/.gitignore
12 +++ b/.gitignore
13 @@ -49,6 +49,13 @@
14 /u-boot.sb
15 /u-boot.bd
16 /u-boot.geany
17 +/u-boot.bin.lzma
18 +/u-boot.bin.lzo
19 +/u-boot.ltq.lzma.norspl
20 +/u-boot.ltq.lzo.norspl
21 +/u-boot.ltq.norspl
22 +/u-boot.lzma.img
23 +/u-boot.lzo.img
24
25 #
26 # Generated files
27 diff --git a/Makefile b/Makefile
28 index 6ee9a3c..73ec67d 100644
29 --- a/Makefile
30 +++ b/Makefile
31 @@ -435,6 +435,12 @@ $(obj)u-boot.bin: $(obj)u-boot
32 $(OBJCOPY) ${OBJCFLAGS} -O binary $< $@
33 $(BOARD_SIZE_CHECK)
34
35 +$(obj)u-boot.bin.lzma: $(obj)u-boot.bin
36 + cat $< | lzma -9 -f - > $@
37 +
38 +$(obj)u-boot.bin.lzo: $(obj)u-boot.bin
39 + cat $< | lzop -9 -f - > $@
40 +
41 $(obj)u-boot.ldr: $(obj)u-boot
42 $(CREATE_LDR_ENV)
43 $(LDR) -T $(CONFIG_BFIN_CPU) -c $@ $< $(LDR_FLAGS)
44 @@ -454,13 +460,23 @@ ifndef CONFIG_SYS_UBOOT_START
45 CONFIG_SYS_UBOOT_START := 0
46 endif
47
48 -$(obj)u-boot.img: $(obj)u-boot.bin
49 - $(obj)tools/mkimage -A $(ARCH) -T firmware -C none \
50 +define GEN_UBOOT_IMAGE
51 + $(obj)tools/mkimage -A $(ARCH) -T firmware -C $(1) \
52 -O u-boot -a $(CONFIG_SYS_TEXT_BASE) \
53 -e $(CONFIG_SYS_UBOOT_START) \
54 -n $(shell sed -n -e 's/.*U_BOOT_VERSION//p' $(VERSION_FILE) | \
55 sed -e 's/"[ ]*$$/ for $(BOARD) board"/') \
56 -d $< $@
57 +endef
58 +
59 +$(obj)u-boot.img: $(obj)u-boot.bin
60 + $(call GEN_UBOOT_IMAGE,none)
61 +
62 +$(obj)u-boot.lzma.img: $(obj)u-boot.bin.lzma
63 + $(call GEN_UBOOT_IMAGE,lzma)
64 +
65 +$(obj)u-boot.lzo.img: $(obj)u-boot.bin.lzo
66 + $(call GEN_UBOOT_IMAGE,lzo)
67
68 $(obj)u-boot.imx: $(obj)u-boot.bin depend
69 $(MAKE) -C $(SRCTREE)/arch/arm/imx-common $(OBJTREE)/u-boot.imx
70 @@ -571,6 +587,27 @@ $(obj)u-boot-img-spl-at-end.bin: $(obj)spl/u-boot-spl.bin $(obj)u-boot.img
71 conv=notrunc 2>/dev/null
72 cat $(obj)u-boot-pad.img $(obj)spl/u-boot-spl.bin > $@
73
74 +$(obj)u-boot.ltq.sfspl: $(obj)u-boot.img $(obj)spl/u-boot-spl.bin
75 + $(obj)tools/ltq-boot-image -t sfspl -e $(CONFIG_SPL_TEXT_BASE) \
76 + -s $(obj)spl/u-boot-spl.bin -u $< -o $@
77 +
78 +$(obj)u-boot.ltq.lzo.sfspl: $(obj)u-boot.lzo.img $(obj)spl/u-boot-spl.bin
79 + $(obj)tools/ltq-boot-image -t sfspl -e $(CONFIG_SPL_TEXT_BASE) \
80 + -s $(obj)spl/u-boot-spl.bin -u $< -o $@
81 +
82 +$(obj)u-boot.ltq.lzma.sfspl: $(obj)u-boot.lzma.img $(obj)spl/u-boot-spl.bin
83 + $(obj)tools/ltq-boot-image -t sfspl -e $(CONFIG_SPL_TEXT_BASE) \
84 + -s $(obj)spl/u-boot-spl.bin -u $< -o $@
85 +
86 +$(obj)u-boot.ltq.norspl: $(obj)u-boot.img $(obj)spl/u-boot-spl.bin
87 + cat $(obj)spl/u-boot-spl.bin $< > $@
88 +
89 +$(obj)u-boot.ltq.lzo.norspl: $(obj)u-boot.lzo.img $(obj)spl/u-boot-spl.bin
90 + cat $(obj)spl/u-boot-spl.bin $< > $@
91 +
92 +$(obj)u-boot.ltq.lzma.norspl: $(obj)u-boot.lzma.img $(obj)spl/u-boot-spl.bin
93 + cat $(obj)spl/u-boot-spl.bin $< > $@
94 +
95 ifeq ($(CONFIG_SANDBOX),y)
96 GEN_UBOOT = \
97 cd $(LNDIR) && $(CC) $(SYMS) -T $(obj)u-boot.lds \
98 diff --git a/README b/README
99 index 09662a4..1acceff 100644
100 --- a/README
101 +++ b/README
102 @@ -468,6 +468,11 @@ The following options need to be configured:
103 CONF_CM_CACHABLE_CUW
104 CONF_CM_CACHABLE_ACCELERATED
105
106 + CONFIG_SYS_MIPS_CACHE_EXT_INIT
107 +
108 + Enable this to use extended cache initialization for recent
109 + MIPS CPU cores.
110 +
111 CONFIG_SYS_XWAY_EBU_BOOTCFG
112
113 Special option for Lantiq XWAY SoCs for booting from NOR flash.
114 diff --git a/arch/mips/config.mk b/arch/mips/config.mk
115 index c3f81b5..84b6e59 100644
116 --- a/arch/mips/config.mk
117 +++ b/arch/mips/config.mk
118 @@ -45,9 +45,13 @@ PLATFORM_CPPFLAGS += -DCONFIG_MIPS -D__MIPS__
119 # On the other hand, we want PIC in the U-Boot code to relocate it from ROM
120 # to RAM. $28 is always used as gp.
121 #
122 -PLATFORM_CPPFLAGS += -G 0 -mabicalls -fpic $(ENDIANNESS)
123 +PF_ABICALLS ?= -mabicalls
124 +PF_PIC ?= -fpic
125 +PF_PIE ?= -pie
126 +
127 +PLATFORM_CPPFLAGS += -G 0 $(PF_ABICALLS) $(PF_PIC) $(ENDIANNESS)
128 PLATFORM_CPPFLAGS += -msoft-float
129 PLATFORM_LDFLAGS += -G 0 -static -n -nostdlib $(ENDIANNESS)
130 PLATFORM_RELFLAGS += -ffunction-sections -fdata-sections
131 -LDFLAGS_FINAL += --gc-sections -pie
132 +LDFLAGS_FINAL += --gc-sections $(PF_PIE)
133 OBJCFLAGS += --remove-section=.dynsym
134 diff --git a/arch/mips/cpu/mips32/cache.S b/arch/mips/cpu/mips32/cache.S
135 index 12f656c..8620a9d 100644
136 --- a/arch/mips/cpu/mips32/cache.S
137 +++ b/arch/mips/cpu/mips32/cache.S
138 @@ -29,7 +29,11 @@
139 */
140 #define MIPS_MAX_CACHE_SIZE 0x10000
141
142 +#ifdef CONFIG_SYS_MIPS_CACHE_EXT_INIT
143 +#define INDEX_BASE 0x9fc00000
144 +#else
145 #define INDEX_BASE CKSEG0
146 +#endif
147
148 .macro cache_op op addr
149 .set push
150 @@ -65,7 +69,11 @@
151 */
152 LEAF(mips_init_icache)
153 blez a1, 9f
154 +#ifdef CONFIG_SYS_MIPS_CACHE_EXT_INIT
155 + mtc0 zero, CP0_ITAGLO
156 +#else
157 mtc0 zero, CP0_TAGLO
158 +#endif
159 /* clear tag to invalidate */
160 PTR_LI t0, INDEX_BASE
161 PTR_ADDU t1, t0, a1
162 @@ -90,7 +98,11 @@ LEAF(mips_init_icache)
163 */
164 LEAF(mips_init_dcache)
165 blez a1, 9f
166 +#ifdef CONFIG_SYS_MIPS_CACHE_EXT_INIT
167 + mtc0 zero, CP0_DTAGLO
168 +#else
169 mtc0 zero, CP0_TAGLO
170 +#endif
171 /* clear all tags */
172 PTR_LI t0, INDEX_BASE
173 PTR_ADDU t1, t0, a1
174 diff --git a/arch/mips/cpu/mips32/danube/Makefile b/arch/mips/cpu/mips32/danube/Makefile
175 new file mode 100644
176 index 0000000..98f5f73
177 --- /dev/null
178 +++ b/arch/mips/cpu/mips32/danube/Makefile
179 @@ -0,0 +1,31 @@
180 +#
181 +# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de
182 +#
183 +# SPDX-License-Identifier: GPL-2.0+
184 +#
185 +
186 +include $(TOPDIR)/config.mk
187 +
188 +LIB = $(obj)lib$(SOC).o
189 +
190 +COBJS-y += cgu.o chipid.o ebu.o mem.o pmu.o rcu.o
191 +SOBJS-y += cgu_init.o mem_init.o
192 +
193 +COBJS := $(COBJS-y)
194 +SOBJS := $(SOBJS-y)
195 +SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
196 +OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
197 +
198 +all: $(LIB)
199 +
200 +$(LIB): $(obj).depend $(OBJS)
201 + $(call cmd_link_o_target, $(OBJS))
202 +
203 +#########################################################################
204 +
205 +# defines $(obj).depend target
206 +include $(SRCTREE)/rules.mk
207 +
208 +sinclude $(obj).depend
209 +
210 +#########################################################################
211 diff --git a/arch/mips/cpu/mips32/danube/cgu.c b/arch/mips/cpu/mips32/danube/cgu.c
212 new file mode 100644
213 index 0000000..4fd110a
214 --- /dev/null
215 +++ b/arch/mips/cpu/mips32/danube/cgu.c
216 @@ -0,0 +1,117 @@
217 +/*
218 + * Copyright (C) 2007-2010 Lantiq Deutschland GmbH
219 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
220 + *
221 + * SPDX-License-Identifier: GPL-2.0+
222 + */
223 +
224 +#include <common.h>
225 +#include <asm/arch/soc.h>
226 +#include <asm/lantiq/clk.h>
227 +#include <asm/lantiq/io.h>
228 +
229 +#define LTQ_CGU_SYS_DDR_MASK 0x0003
230 +#define LTQ_CGU_SYS_DDR_SHIFT 0
231 +#define LTQ_CGU_SYS_CPU0_MASK 0x000C
232 +#define LTQ_CGU_SYS_CPU0_SHIFT 2
233 +#define LTQ_CGU_SYS_FPI_MASK 0x0040
234 +#define LTQ_CGU_SYS_FPI_SHIFT 6
235 +
236 +struct ltq_cgu_regs {
237 + u32 rsvd0;
238 + u32 pll0_cfg; /* PLL0 config */
239 + u32 pll1_cfg; /* PLL1 config */
240 + u32 pll2_cfg; /* PLL2 config */
241 + u32 sys; /* System clock */
242 + u32 update; /* CGU update control */
243 + u32 if_clk; /* Interface clock */
244 + u32 osc_con; /* Update OSC Control */
245 + u32 smd; /* SDRAM Memory Control */
246 + u32 rsvd1[3];
247 + u32 pcm_cr; /* PCM control */
248 + u32 pci_cr; /* PCI clock control */
249 +};
250 +
251 +static struct ltq_cgu_regs *ltq_cgu_regs =
252 + (struct ltq_cgu_regs *) CKSEG1ADDR(LTQ_CGU_BASE);
253 +
254 +static inline u32 ltq_cgu_sys_readl(u32 mask, u32 shift)
255 +{
256 + return (ltq_readl(&ltq_cgu_regs->sys) & mask) >> shift;
257 +}
258 +
259 +unsigned long ltq_get_io_region_clock(void)
260 +{
261 + u32 ddr_sel;
262 + unsigned long clk;
263 +
264 + ddr_sel = ltq_cgu_sys_readl(LTQ_CGU_SYS_DDR_MASK,
265 + LTQ_CGU_SYS_DDR_SHIFT);
266 +
267 + switch (ddr_sel) {
268 + case 0:
269 + clk = CLOCK_166_MHZ;
270 + break;
271 + case 1:
272 + clk = CLOCK_133_MHZ;
273 + break;
274 + case 2:
275 + clk = CLOCK_111_MHZ;
276 + break;
277 + case 3:
278 + clk = CLOCK_83_MHZ;
279 + break;
280 + default:
281 + clk = 0;
282 + break;
283 + }
284 +
285 + return clk;
286 +}
287 +
288 +unsigned long ltq_get_cpu_clock(void)
289 +{
290 + u32 cpu0_sel;
291 + unsigned long clk;
292 +
293 + cpu0_sel = ltq_cgu_sys_readl(LTQ_CGU_SYS_CPU0_MASK,
294 + LTQ_CGU_SYS_CPU0_SHIFT);
295 +
296 + switch (cpu0_sel) {
297 + /* Same as PLL0 output (333,33 MHz) */
298 + case 0:
299 + clk = CLOCK_333_MHZ;
300 + break;
301 + /* 1/1 fixed ratio to DDR clock */
302 + case 1:
303 + clk = ltq_get_io_region_clock();
304 + break;
305 + /* 1/2 fixed ratio to DDR clock */
306 + case 2:
307 + clk = ltq_get_io_region_clock() << 1;
308 + break;
309 + default:
310 + clk = 0;
311 + break;
312 + }
313 +
314 + return clk;
315 +}
316 +
317 +unsigned long ltq_get_bus_clock(void)
318 +{
319 + u32 fpi_sel;
320 + unsigned long clk;
321 +
322 + fpi_sel = ltq_cgu_sys_readl(LTQ_CGU_SYS_FPI_MASK,
323 + LTQ_CGU_SYS_FPI_SHIFT);
324 +
325 + if (fpi_sel)
326 + /* Half the DDR clock */
327 + clk = ltq_get_io_region_clock() >> 1;
328 + else
329 + /* Same as DDR clock */
330 + clk = ltq_get_io_region_clock();
331 +
332 + return clk;
333 +}
334 diff --git a/arch/mips/cpu/mips32/danube/cgu_init.S b/arch/mips/cpu/mips32/danube/cgu_init.S
335 new file mode 100644
336 index 0000000..e0922f1
337 --- /dev/null
338 +++ b/arch/mips/cpu/mips32/danube/cgu_init.S
339 @@ -0,0 +1,142 @@
340 +/*
341 + * Copyright (C) 2007-2010 Lantiq Deutschland GmbH
342 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
343 + *
344 + * SPDX-License-Identifier: GPL-2.0+
345 + */
346 +
347 +#include <config.h>
348 +#include <asm/asm.h>
349 +#include <asm/regdef.h>
350 +#include <asm/addrspace.h>
351 +#include <asm/arch/soc.h>
352 +
353 +/* RCU module register */
354 +#define LTQ_RCU_RST_REQ 0x0010
355 +#define LTQ_RCU_RST_STAT 0x0014
356 +#define LTQ_RCU_RST_REQ_VALUE 0x40000008
357 +#define LTQ_RCU_RST_STAT_XTAL_F 0x20000
358 +
359 +/* CGU module register */
360 +#define LTQ_CGU_PLL0_CFG 0x0004 /* PLL0 config */
361 +#define LTQ_CGU_PLL1_CFG 0x0008 /* PLL1 config */
362 +#define LTQ_CGU_PLL2_CFG 0x000C /* PLL2 config */
363 +#define LTQ_CGU_SYS 0x0010 /* System clock */
364 +
365 +/* Valid SYS.CPU0/1 values */
366 +#define LTQ_CGU_SYS_CPU0_SHIFT 2
367 +#define LTQ_CGU_SYS_CPU1_SHIFT 4
368 +#define LTQ_CGU_SYS_CPU_PLL0 0x0
369 +#define LTQ_CGU_SYS_CPU_DDR_EQUAL 0x1
370 +#define LTQ_CGU_SYS_CPU_DDR_TWICE 0x2
371 +
372 +/* Valid SYS.DDR values */
373 +#define LTQ_CGU_SYS_DDR_SHIFT 0
374 +#define LTQ_CGU_SYS_DDR_167_MHZ 0x0
375 +#define LTQ_CGU_SYS_DDR_133_MHZ 0x1
376 +#define LTQ_CGU_SYS_DDR_111_MHZ 0x2
377 +#define LTQ_CGU_SYS_DDR_83_MHZ 0x3
378 +
379 +/* Valid SYS.FPI values */
380 +#define LTQ_CGU_SYS_FPI_SHIFT 6
381 +#define LTQ_CGU_SYS_FPI_DDR_EQUAL 0x0
382 +#define LTQ_CGU_SYS_FPI_DDR_HALF 0x1
383 +
384 +/* Valid SYS.PPE values */
385 +#define LTQ_CGU_SYS_PPE_SHIFT 7
386 +#define LTQ_CGU_SYS_PPE_266_MHZ 0x0
387 +#define LTQ_CGU_SYS_PPE_240_MHZ 0x1
388 +#define LTQ_CGU_SYS_PPE_222_MHZ 0x2
389 +#define LTQ_CGU_SYS_PPE_133_MHZ 0x3
390 +
391 +#if (CONFIG_SYS_CLOCK_MODE == LTQ_CLK_CPU_333_DDR_167)
392 +#define LTQ_CGU_SYS_CPU_CONFIG LTQ_CGU_SYS_CPU_DDR_TWICE
393 +#define LTQ_CGU_SYS_DDR_CONFIG LTQ_CGU_SYS_DDR_167_MHZ
394 +#define LTQ_CGU_SYS_FPI_CONFIG LTQ_CGU_SYS_FPI_DDR_HALF
395 +#define LTQ_CGU_SYS_PPE_CONFIG LTQ_CGU_SYS_PPE_266_MHZ
396 +#elif (CONFIG_SYS_CLOCK_MODE == LTQ_CLK_CPU_111_DDR_111)
397 +#define LTQ_CGU_SYS_CPU_CONFIG LTQ_CGU_SYS_CPU_DDR_EQUAL
398 +#define LTQ_CGU_SYS_DDR_CONFIG LTQ_CGU_SYS_DDR_111_MHZ
399 +#define LTQ_CGU_SYS_FPI_CONFIG LTQ_CGU_SYS_FPI_DDR_HALF
400 +#define LTQ_CGU_SYS_PPE_CONFIG LTQ_CGU_SYS_PPE_133_MHZ
401 +#else
402 +#error "Invalid system clock configuration!"
403 +#endif
404 +
405 +/* Build register values */
406 +#define LTQ_CGU_SYS_VALUE ((LTQ_CGU_SYS_PPE_CONFIG << \
407 + LTQ_CGU_SYS_PPE_SHIFT) | \
408 + (LTQ_CGU_SYS_FPI_CONFIG << \
409 + LTQ_CGU_SYS_FPI_SHIFT) | \
410 + (LTQ_CGU_SYS_CPU_CONFIG << \
411 + LTQ_CGU_SYS_CPU1_SHIFT) | \
412 + (LTQ_CGU_SYS_CPU_CONFIG << \
413 + LTQ_CGU_SYS_CPU0_SHIFT) | \
414 + LTQ_CGU_SYS_DDR_CONFIG)
415 +
416 +/* Reset values for PLL registers for usage with 35.328 MHz crystal */
417 +#define PLL0_35MHZ_CONFIG 0x9D861059
418 +#define PLL1_35MHZ_CONFIG 0x1A260CD9
419 +#define PLL2_35MHZ_CONFIG 0x8000f1e5
420 +
421 +/* Reset values for PLL registers for usage with 36 MHz crystal */
422 +#define PLL0_36MHZ_CONFIG 0x1000125D
423 +#define PLL1_36MHZ_CONFIG 0x1B1E0C99
424 +#define PLL2_36MHZ_CONFIG 0x8002f2a1
425 +
426 +LEAF(ltq_cgu_init)
427 + /* Load current CGU register value */
428 + li t0, (LTQ_CGU_BASE | KSEG1)
429 + lw t1, LTQ_CGU_SYS(t0)
430 +
431 + /* Load target CGU register values */
432 + li t3, LTQ_CGU_SYS_VALUE
433 +
434 + /* Only update registers if values differ */
435 + beq t1, t3, finished
436 +
437 + /*
438 + * Check whether the XTAL_F bit in RST_STAT register is set or not.
439 + * This bit is latched in via pin strapping. If bit is set then
440 + * clock source is a 36 MHz crystal. Otherwise a 35.328 MHz crystal.
441 + */
442 + li t1, (LTQ_RCU_BASE | KSEG1)
443 + lw t2, LTQ_RCU_RST_STAT(t1)
444 + and t2, t2, LTQ_RCU_RST_STAT_XTAL_F
445 + beq t2, LTQ_RCU_RST_STAT_XTAL_F, boot_36mhz
446 +
447 +boot_35mhz:
448 + /* Configure PLL for 35.328 MHz */
449 + li t2, PLL0_35MHZ_CONFIG
450 + sw t2, LTQ_CGU_PLL0_CFG(t0)
451 + li t2, PLL1_35MHZ_CONFIG
452 + sw t2, LTQ_CGU_PLL1_CFG(t0)
453 + li t2, PLL2_35MHZ_CONFIG
454 + sw t2, LTQ_CGU_PLL2_CFG(t0)
455 +
456 + b do_reset
457 +
458 +boot_36mhz:
459 + /* Configure PLL for 36 MHz */
460 + li t2, PLL0_36MHZ_CONFIG
461 + sw t2, LTQ_CGU_PLL0_CFG(t0)
462 + li t2, PLL1_36MHZ_CONFIG
463 + sw t2, LTQ_CGU_PLL1_CFG(t0)
464 + li t2, PLL2_36MHZ_CONFIG
465 + sw t2, LTQ_CGU_PLL2_CFG(t0)
466 +
467 +do_reset:
468 + /* Store new clock config */
469 + sw t3, LTQ_CGU_SYS(t0)
470 +
471 + /* Perform software reset to activate new clock config */
472 + li t2, LTQ_RCU_RST_REQ_VALUE
473 + sw t2, LTQ_RCU_RST_REQ(t1)
474 +
475 +wait_reset:
476 + b wait_reset
477 +
478 +finished:
479 + jr ra
480 +
481 + END(ltq_cgu_init)
482 diff --git a/arch/mips/cpu/mips32/danube/chipid.c b/arch/mips/cpu/mips32/danube/chipid.c
483 new file mode 100644
484 index 0000000..02d9554
485 --- /dev/null
486 +++ b/arch/mips/cpu/mips32/danube/chipid.c
487 @@ -0,0 +1,59 @@
488 +/*
489 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
490 + *
491 + * SPDX-License-Identifier: GPL-2.0+
492 + */
493 +
494 +#include <common.h>
495 +#include <asm/lantiq/io.h>
496 +#include <asm/lantiq/chipid.h>
497 +#include <asm/arch/soc.h>
498 +
499 +#define LTQ_CHIPID_VERSION_SHIFT 28
500 +#define LTQ_CHIPID_VERSION_MASK (0xF << LTQ_CHIPID_VERSION_SHIFT)
501 +#define LTQ_CHIPID_PNUM_SHIFT 12
502 +#define LTQ_CHIPID_PNUM_MASK (0xFFFF << LTQ_CHIPID_PNUM_SHIFT)
503 +
504 +struct ltq_chipid_regs {
505 + u32 manid; /* Manufacturer identification */
506 + u32 chipid; /* Chip identification */
507 +};
508 +
509 +static struct ltq_chipid_regs *ltq_chipid_regs =
510 + (struct ltq_chipid_regs *) CKSEG1ADDR(LTQ_CHIPID_BASE);
511 +
512 +unsigned int ltq_chip_version_get(void)
513 +{
514 + u32 chipid;
515 +
516 + chipid = ltq_readl(&ltq_chipid_regs->chipid);
517 +
518 + return (chipid & LTQ_CHIPID_VERSION_MASK) >> LTQ_CHIPID_VERSION_SHIFT;
519 +}
520 +
521 +unsigned int ltq_chip_partnum_get(void)
522 +{
523 + u32 chipid;
524 +
525 + chipid = ltq_readl(&ltq_chipid_regs->chipid);
526 +
527 + return (chipid & LTQ_CHIPID_PNUM_MASK) >> LTQ_CHIPID_PNUM_SHIFT;
528 +}
529 +
530 +const char *ltq_chip_partnum_str(void)
531 +{
532 + enum ltq_chip_partnum partnum = ltq_chip_partnum_get();
533 +
534 + switch (partnum) {
535 + case LTQ_SOC_DANUBE:
536 + return "Danube";
537 + case LTQ_SOC_DANUBE_S:
538 + return "Danube-S";
539 + case LTQ_SOC_TWINPASS:
540 + return "Twinpass";
541 + default:
542 + printf("Unknown partnum: %x\n", partnum);
543 + }
544 +
545 + return "";
546 +}
547 diff --git a/arch/mips/cpu/mips32/danube/config.mk b/arch/mips/cpu/mips32/danube/config.mk
548 new file mode 100644
549 index 0000000..cee376f
550 --- /dev/null
551 +++ b/arch/mips/cpu/mips32/danube/config.mk
552 @@ -0,0 +1,25 @@
553 +#
554 +# Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
555 +#
556 +# SPDX-License-Identifier: GPL-2.0+
557 +#
558 +
559 +PF_CPPFLAGS_DANUBE := $(call cc-option,-mtune=24kec,)
560 +PLATFORM_CPPFLAGS += $(PF_CPPFLAGS_DANUBE)
561 +
562 +ifdef CONFIG_SPL_BUILD
563 +PF_ABICALLS := -mno-abicalls
564 +PF_PIC := -fno-pic
565 +PF_PIE :=
566 +USE_PRIVATE_LIBGCC := yes
567 +endif
568 +
569 +LIBS-y += $(CPUDIR)/lantiq-common/liblantiq-common.o
570 +
571 +ifndef CONFIG_SPL_BUILD
572 +ifdef CONFIG_SYS_BOOT_NORSPL
573 +ALL-y += $(obj)u-boot.ltq.norspl
574 +ALL-$(CONFIG_SPL_LZO_SUPPORT) += $(obj)u-boot.ltq.lzo.norspl
575 +ALL-$(CONFIG_SPL_LZMA_SUPPORT) += $(obj)u-boot.ltq.lzma.norspl
576 +endif
577 +endif
578 diff --git a/arch/mips/cpu/mips32/danube/ebu.c b/arch/mips/cpu/mips32/danube/ebu.c
579 new file mode 100644
580 index 0000000..902f6a7
581 --- /dev/null
582 +++ b/arch/mips/cpu/mips32/danube/ebu.c
583 @@ -0,0 +1,105 @@
584 +/*
585 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
586 + *
587 + * SPDX-License-Identifier: GPL-2.0+
588 + */
589 +
590 +#include <common.h>
591 +#include <asm/arch/soc.h>
592 +#include <asm/lantiq/io.h>
593 +
594 +#define EBU_ADDRSEL_MASK(mask) ((mask & 0xf) << 4)
595 +#define EBU_ADDRSEL_REGEN (1 << 0)
596 +
597 +#define EBU_CON_WRDIS (1 << 31)
598 +#define EBU_CON_AGEN_DEMUX (0x0 << 24)
599 +#define EBU_CON_AGEN_MUX (0x2 << 24)
600 +#define EBU_CON_SETUP (1 << 22)
601 +#define EBU_CON_WAIT_DIS (0x0 << 20)
602 +#define EBU_CON_WAIT_ASYNC (0x1 << 20)
603 +#define EBU_CON_WAIT_SYNC (0x2 << 20)
604 +#define EBU_CON_WINV (1 << 19)
605 +#define EBU_CON_PW_8BIT (0x0 << 16)
606 +#define EBU_CON_PW_16BIT (0x1 << 16)
607 +#define EBU_CON_ALEC(cycles) ((cycles & 0x3) << 14)
608 +#define EBU_CON_BCGEN_CS (0x0 << 12)
609 +#define EBU_CON_BCGEN_INTEL (0x1 << 12)
610 +#define EBU_CON_BCGEN_MOTOROLA (0x2 << 12)
611 +#define EBU_CON_WAITWRC(cycles) ((cycles & 0x7) << 8)
612 +#define EBU_CON_WAITRDC(cycles) ((cycles & 0x3) << 6)
613 +#define EBU_CON_HOLDC(cycles) ((cycles & 0x3) << 4)
614 +#define EBU_CON_RECOVC(cycles) ((cycles & 0x3) << 2)
615 +#define EBU_CON_CMULT_1 0x0
616 +#define EBU_CON_CMULT_4 0x1
617 +#define EBU_CON_CMULT_8 0x2
618 +#define EBU_CON_CMULT_16 0x3
619 +
620 +#if defined(CONFIG_LTQ_SUPPORT_NOR_FLASH)
621 +#define ebu_region0_enable 1
622 +#else
623 +#define ebu_region0_enable 0
624 +#endif
625 +
626 +#if defined(CONFIG_LTQ_SUPPORT_NAND_FLASH)
627 +#define ebu_region1_enable 1
628 +#else
629 +#define ebu_region1_enable 0
630 +#endif
631 +
632 +struct ltq_ebu_regs {
633 + u32 clc;
634 + u32 rsvd0[3];
635 + u32 con;
636 + u32 rsvd1[3];
637 + u32 addr_sel_0;
638 + u32 addr_sel_1;
639 + u32 rsvd2[14];
640 + u32 con_0;
641 + u32 con_1;
642 +};
643 +
644 +static struct ltq_ebu_regs *ltq_ebu_regs =
645 + (struct ltq_ebu_regs *) CKSEG1ADDR(LTQ_EBU_BASE);
646 +
647 +void ltq_ebu_init(void)
648 +{
649 + if (ebu_region0_enable) {
650 + /*
651 + * Map EBU region 0 to range 0x10000000-0x13ffffff and enable
652 + * region control. This supports up to 32 MiB NOR flash in
653 + * bank 0.
654 + */
655 + ltq_writel(&ltq_ebu_regs->addr_sel_0, LTQ_EBU_REGION0_BASE |
656 + EBU_ADDRSEL_MASK(1) | EBU_ADDRSEL_REGEN);
657 +
658 + ltq_writel(&ltq_ebu_regs->con_0, EBU_CON_AGEN_DEMUX |
659 + EBU_CON_WAIT_DIS | EBU_CON_PW_16BIT |
660 + EBU_CON_ALEC(3) | EBU_CON_BCGEN_INTEL |
661 + EBU_CON_WAITWRC(7) | EBU_CON_WAITRDC(3) |
662 + EBU_CON_HOLDC(3) | EBU_CON_RECOVC(3) |
663 + EBU_CON_CMULT_16);
664 + } else
665 + ltq_clrbits(&ltq_ebu_regs->addr_sel_0, EBU_ADDRSEL_REGEN);
666 +
667 + if (ebu_region1_enable) {
668 + /*
669 + * Map EBU region 1 to range 0x14000000-0x13ffffff and enable
670 + * region control. This supports NAND flash in bank 1.
671 + */
672 + ltq_writel(&ltq_ebu_regs->addr_sel_1, LTQ_EBU_REGION1_BASE |
673 + EBU_ADDRSEL_MASK(3) | EBU_ADDRSEL_REGEN);
674 +
675 + ltq_writel(&ltq_ebu_regs->con_1, EBU_CON_AGEN_DEMUX |
676 + EBU_CON_SETUP | EBU_CON_WAIT_DIS | EBU_CON_PW_8BIT |
677 + EBU_CON_ALEC(3) | EBU_CON_BCGEN_INTEL |
678 + EBU_CON_WAITWRC(2) | EBU_CON_WAITRDC(2) |
679 + EBU_CON_HOLDC(1) | EBU_CON_RECOVC(1) |
680 + EBU_CON_CMULT_4);
681 + } else
682 + ltq_clrbits(&ltq_ebu_regs->addr_sel_1, EBU_ADDRSEL_REGEN);
683 +}
684 +
685 +void *flash_swap_addr(unsigned long addr)
686 +{
687 + return (void *)(addr ^ 2);
688 +}
689 diff --git a/arch/mips/cpu/mips32/danube/mem.c b/arch/mips/cpu/mips32/danube/mem.c
690 new file mode 100644
691 index 0000000..be1922c
692 --- /dev/null
693 +++ b/arch/mips/cpu/mips32/danube/mem.c
694 @@ -0,0 +1,30 @@
695 +/*
696 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
697 + *
698 + * SPDX-License-Identifier: GPL-2.0+
699 + */
700 +
701 +#include <common.h>
702 +#include <asm/arch/soc.h>
703 +#include <asm/lantiq/io.h>
704 +
705 +static void *ltq_mc_ddr_base = (void *) CKSEG1ADDR(LTQ_MC_DDR_BASE);
706 +
707 +static inline u32 ltq_mc_dc_read(u32 index)
708 +{
709 + return ltq_readl(ltq_mc_ddr_base + LTQ_MC_DDR_DC_OFFSET(index));
710 +}
711 +
712 +phys_size_t initdram(int board_type)
713 +{
714 + u32 col, row, dc04, dc19, dc20;
715 +
716 + dc04 = ltq_mc_dc_read(4);
717 + dc19 = ltq_mc_dc_read(19);
718 + dc20 = ltq_mc_dc_read(20);
719 +
720 + row = (dc04 & 0xF) - ((dc19 & 0x700) >> 8);
721 + col = ((dc04 & 0xF00) >> 8) - (dc20 & 0x7);
722 +
723 + return (1 << (row + col)) * 4 * 2;
724 +}
725 diff --git a/arch/mips/cpu/mips32/danube/mem_init.S b/arch/mips/cpu/mips32/danube/mem_init.S
726 new file mode 100644
727 index 0000000..47a35e1
728 --- /dev/null
729 +++ b/arch/mips/cpu/mips32/danube/mem_init.S
730 @@ -0,0 +1,114 @@
731 +/*
732 + * Copyright (C) 2007-2010 Lantiq Deutschland GmbH
733 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
734 + *
735 + * SPDX-License-Identifier: GPL-2.0+
736 + */
737 +
738 +#include <config.h>
739 +#include <asm/asm.h>
740 +#include <asm/regdef.h>
741 +#include <asm/addrspace.h>
742 +#include <asm/arch/soc.h>
743 +
744 +/* Must be configured in BOARDDIR */
745 +#include <ddr_settings.h>
746 +
747 +#define LTQ_MC_GEN_ERRCAUSE 0x0010
748 +#define LTQ_MC_GEN_ERRADDR 0x0020
749 +#define LTQ_MC_GEN_CON 0x0060
750 +#define LTQ_MC_GEN_STAT 0x0070
751 +#define LTQ_MC_GEN_CON_SRAM_DDR_ENABLE 0x5
752 +#define LTQ_MC_GEN_STAT_DLCK_PWRON 0xC
753 +
754 +#define LTQ_MC_DDR_DC03_MC_START 0x100
755 +
756 + /* Store given value in MC DDR CCRx register */
757 + .macro dc_sw num, val
758 + li t2, \val
759 + sw t2, LTQ_MC_DDR_DC_OFFSET(\num)(t1)
760 + .endm
761 +
762 +LEAF(ltq_mem_init)
763 + /* Load MC General and MC DDR module base */
764 + li t0, (LTQ_MC_GEN_BASE | KSEG1)
765 + li t1, (LTQ_MC_DDR_BASE | KSEG1)
766 +
767 + /* Clear access error log registers */
768 + sw zero, LTQ_MC_GEN_ERRCAUSE(t0)
769 + sw zero, LTQ_MC_GEN_ERRADDR(t0)
770 +
771 + /* Enable DDR and SRAM module in memory controller */
772 + li t2, LTQ_MC_GEN_CON_SRAM_DDR_ENABLE
773 + sw t2, LTQ_MC_GEN_CON(t0)
774 +
775 + /* Clear start bit of DDR memory controller */
776 + sw zero, LTQ_MC_DDR_DC_OFFSET(3)(t1)
777 +
778 + /* Init memory controller registers with values ddr_settings.h */
779 + dc_sw 0, MC_DC00_VALUE
780 + dc_sw 1, MC_DC01_VALUE
781 + dc_sw 2, MC_DC02_VALUE
782 + dc_sw 4, MC_DC04_VALUE
783 + dc_sw 5, MC_DC05_VALUE
784 + dc_sw 6, MC_DC06_VALUE
785 + dc_sw 7, MC_DC07_VALUE
786 + dc_sw 8, MC_DC08_VALUE
787 + dc_sw 9, MC_DC09_VALUE
788 +
789 + dc_sw 10, MC_DC10_VALUE
790 + dc_sw 11, MC_DC11_VALUE
791 + dc_sw 12, MC_DC12_VALUE
792 + dc_sw 13, MC_DC13_VALUE
793 + dc_sw 14, MC_DC14_VALUE
794 + dc_sw 15, MC_DC15_VALUE
795 + dc_sw 16, MC_DC16_VALUE
796 + dc_sw 17, MC_DC17_VALUE
797 + dc_sw 18, MC_DC18_VALUE
798 + dc_sw 19, MC_DC19_VALUE
799 +
800 + dc_sw 20, MC_DC20_VALUE
801 + dc_sw 21, MC_DC21_VALUE
802 + dc_sw 22, MC_DC22_VALUE
803 + dc_sw 23, MC_DC23_VALUE
804 + dc_sw 24, MC_DC24_VALUE
805 + dc_sw 25, MC_DC25_VALUE
806 + dc_sw 26, MC_DC26_VALUE
807 + dc_sw 27, MC_DC27_VALUE
808 + dc_sw 28, MC_DC28_VALUE
809 + dc_sw 29, MC_DC29_VALUE
810 +
811 + dc_sw 30, MC_DC30_VALUE
812 + dc_sw 31, MC_DC31_VALUE
813 + dc_sw 32, MC_DC32_VALUE
814 + dc_sw 33, MC_DC33_VALUE
815 + dc_sw 34, MC_DC34_VALUE
816 + dc_sw 35, MC_DC35_VALUE
817 + dc_sw 36, MC_DC36_VALUE
818 + dc_sw 37, MC_DC37_VALUE
819 + dc_sw 38, MC_DC38_VALUE
820 + dc_sw 39, MC_DC39_VALUE
821 +
822 + dc_sw 40, MC_DC40_VALUE
823 + dc_sw 41, MC_DC41_VALUE
824 + dc_sw 42, MC_DC42_VALUE
825 + dc_sw 43, MC_DC43_VALUE
826 + dc_sw 44, MC_DC44_VALUE
827 + dc_sw 45, MC_DC45_VALUE
828 + dc_sw 46, MC_DC46_VALUE
829 +
830 + /* Set start bit of DDR memory controller */
831 + li t2, LTQ_MC_DDR_DC03_MC_START
832 + sw t2, LTQ_MC_DDR_DC_OFFSET(3)(t1)
833 +
834 + /* Wait until DLL has locked and core is ready for data transfers */
835 +wait_ready:
836 + lw t2, LTQ_MC_GEN_STAT(t0)
837 + li t3, LTQ_MC_GEN_STAT_DLCK_PWRON
838 + and t2, t3
839 + bne t2, t3, wait_ready
840 +
841 +finished:
842 + jr ra
843 +
844 + END(ltq_mem_init)
845 diff --git a/arch/mips/cpu/mips32/danube/pmu.c b/arch/mips/cpu/mips32/danube/pmu.c
846 new file mode 100644
847 index 0000000..7dd8aea
848 --- /dev/null
849 +++ b/arch/mips/cpu/mips32/danube/pmu.c
850 @@ -0,0 +1,117 @@
851 +/*
852 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
853 + *
854 + * SPDX-License-Identifier: GPL-2.0+
855 + */
856 +
857 +#include <common.h>
858 +#include <asm/lantiq/io.h>
859 +#include <asm/lantiq/pm.h>
860 +#include <asm/arch/soc.h>
861 +
862 +#define LTQ_PMU_PWDCR_RESERVED 0xFD0C001C
863 +
864 +#define LTQ_PMU_PWDCR_TDM (1 << 25)
865 +#define LTQ_PMU_PWDCR_PPE_ENET0 (1 << 23)
866 +#define LTQ_PMU_PWDCR_PPE_ENET1 (1 << 22)
867 +#define LTQ_PMU_PWDCR_PPE_TC (1 << 21)
868 +#define LTQ_PMU_PWDCR_DEU (1 << 20)
869 +#define LTQ_PMU_PWDCR_UART1 (1 << 17)
870 +#define LTQ_PMU_PWDCR_SDIO (1 << 16)
871 +#define LTQ_PMU_PWDCR_AHB (1 << 15)
872 +#define LTQ_PMU_PWDCR_FPI0 (1 << 14)
873 +#define LTQ_PMU_PWDCR_PPE (1 << 13)
874 +#define LTQ_PMU_PWDCR_GPTC (1 << 12)
875 +#define LTQ_PMU_PWDCR_LEDC (1 << 11)
876 +#define LTQ_PMU_PWDCR_EBU (1 << 10)
877 +#define LTQ_PMU_PWDCR_DSL (1 << 9)
878 +#define LTQ_PMU_PWDCR_SPI (1 << 8)
879 +#define LTQ_PMU_PWDCR_UART0 (1 << 7)
880 +#define LTQ_PMU_PWDCR_USB (1 << 6)
881 +#define LTQ_PMU_PWDCR_DMA (1 << 5)
882 +#define LTQ_PMU_PWDCR_FPI1 (1 << 1)
883 +#define LTQ_PMU_PWDCR_USB_PHY (1 << 0)
884 +
885 +struct ltq_pmu_regs {
886 + u32 rsvd0[7];
887 + u32 pwdcr;
888 + u32 sr;
889 + u32 pwdcr1;
890 + u32 sr1;
891 +};
892 +
893 +static struct ltq_pmu_regs *ltq_pmu_regs =
894 + (struct ltq_pmu_regs *) CKSEG1ADDR(LTQ_PMU_BASE);
895 +
896 +u32 ltq_pm_map(enum ltq_pm_modules module)
897 +{
898 + u32 val;
899 +
900 + switch (module) {
901 + case LTQ_PM_CORE:
902 + val = LTQ_PMU_PWDCR_UART1 | LTQ_PMU_PWDCR_FPI0 |
903 + LTQ_PMU_PWDCR_LEDC | LTQ_PMU_PWDCR_EBU;
904 + break;
905 + case LTQ_PM_DMA:
906 + val = LTQ_PMU_PWDCR_DMA;
907 + break;
908 + case LTQ_PM_ETH:
909 + val = LTQ_PMU_PWDCR_PPE_ENET0 | LTQ_PMU_PWDCR_PPE_TC |
910 + LTQ_PMU_PWDCR_PPE;
911 + break;
912 + case LTQ_PM_SPI:
913 + val = LTQ_PMU_PWDCR_SPI;
914 + break;
915 + default:
916 + val = 0;
917 + break;
918 + }
919 +
920 + return val;
921 +}
922 +
923 +int ltq_pm_enable(enum ltq_pm_modules module)
924 +{
925 + const unsigned long timeout = 1000;
926 + unsigned long timebase;
927 + u32 sr, val;
928 +
929 + val = ltq_pm_map(module);
930 + if (unlikely(!val))
931 + return 1;
932 +
933 + ltq_clrbits(&ltq_pmu_regs->pwdcr, val);
934 +
935 + timebase = get_timer(0);
936 +
937 + do {
938 + sr = ltq_readl(&ltq_pmu_regs->sr);
939 + if (~sr & val)
940 + return 0;
941 + } while (get_timer(timebase) < timeout);
942 +
943 + return 1;
944 +}
945 +
946 +int ltq_pm_disable(enum ltq_pm_modules module)
947 +{
948 + u32 val;
949 +
950 + val = ltq_pm_map(module);
951 + if (unlikely(!val))
952 + return 1;
953 +
954 + ltq_setbits(&ltq_pmu_regs->pwdcr, val);
955 +
956 + return 0;
957 +}
958 +
959 +void ltq_pmu_init(void)
960 +{
961 + u32 set, clr;
962 +
963 + clr = ltq_pm_map(LTQ_PM_CORE);
964 + set = ~(LTQ_PMU_PWDCR_RESERVED | clr);
965 +
966 + ltq_clrsetbits(&ltq_pmu_regs->pwdcr, clr, set);
967 +}
968 diff --git a/arch/mips/cpu/mips32/danube/rcu.c b/arch/mips/cpu/mips32/danube/rcu.c
969 new file mode 100644
970 index 0000000..906491a
971 --- /dev/null
972 +++ b/arch/mips/cpu/mips32/danube/rcu.c
973 @@ -0,0 +1,125 @@
974 +/*
975 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
976 + *
977 + * SPDX-License-Identifier: GPL-2.0+
978 + */
979 +
980 +#include <common.h>
981 +#include <asm/lantiq/io.h>
982 +#include <asm/lantiq/reset.h>
983 +#include <asm/lantiq/cpu.h>
984 +#include <asm/arch/soc.h>
985 +
986 +#define LTQ_RCU_RD_SRST (1 << 30) /* Global SW Reset */
987 +#define LTQ_RCU_RD_MC (1 << 14) /* Memory Controller */
988 +#define LTQ_RCU_RD_PCI (1 << 13) /* PCI core */
989 +#define LTQ_RCU_RD_DFE_AFE (1 << 12) /* Voice DFE/AFE */
990 +#define LTQ_RCU_RD_DSL_AFE (1 << 11) /* DSL AFE */
991 +#define LTQ_RCU_RD_SDIO (1 << 10) /* SDIO core */
992 +#define LTQ_RCU_RD_DMA (1 << 9) /* DMA core */
993 +#define LTQ_RCU_RD_PPE (1 << 8) /* PPE core */
994 +#define LTQ_RCU_RD_ARC_DFE (1 << 7) /* ARC/DFE core */
995 +#define LTQ_RCU_RD_AHB (1 << 6) /* AHB bus */
996 +#define LTQ_RCU_RD_ENET_MAC1 (1 << 5) /* Ethernet MAC1 */
997 +#define LTQ_RCU_RD_USB (1 << 4) /* USB and Phy core */
998 +#define LTQ_RCU_RD_CPU1 (1 << 3) /* CPU1 subsystem */
999 +#define LTQ_RCU_RD_FPI (1 << 2) /* FPI bus */
1000 +#define LTQ_RCU_RD_CPU0 (1 << 1) /* CPU0 subsystem */
1001 +#define LTQ_RCU_RD_HRST (1 << 0) /* HW reset via HRST pin */
1002 +
1003 +#define LTQ_RCU_STAT_BOOT_SHIFT 18
1004 +#define LTQ_RCU_STAT_BOOT_MASK (0x7 << LTQ_RCU_STAT_BOOT_SHIFT)
1005 +
1006 +struct ltq_rcu_regs {
1007 + u32 rsvd0[4];
1008 + u32 req; /* Reset request */
1009 + u32 stat; /* Reset status */
1010 + u32 usb_cfg; /* USB configure */
1011 + u32 rsvd1[2];
1012 + u32 pci_rdy; /* PCI boot ready */
1013 +};
1014 +
1015 +static struct ltq_rcu_regs *ltq_rcu_regs =
1016 + (struct ltq_rcu_regs *) CKSEG1ADDR(LTQ_RCU_BASE);
1017 +
1018 +u32 ltq_reset_map(enum ltq_reset_modules module)
1019 +{
1020 + u32 val;
1021 +
1022 + switch (module) {
1023 + case LTQ_RESET_CORE:
1024 + case LTQ_RESET_SOFT:
1025 + val = LTQ_RCU_RD_SRST | LTQ_RCU_RD_CPU1;
1026 + break;
1027 + case LTQ_RESET_DMA:
1028 + val = LTQ_RCU_RD_DMA;
1029 + break;
1030 + case LTQ_RESET_ETH:
1031 + val = LTQ_RCU_RD_PPE;
1032 + break;
1033 + case LTQ_RESET_HARD:
1034 + val = LTQ_RCU_RD_HRST;
1035 + break;
1036 + default:
1037 + val = 0;
1038 + break;
1039 + }
1040 +
1041 + return val;
1042 +}
1043 +
1044 +int ltq_reset_activate(enum ltq_reset_modules module)
1045 +{
1046 + u32 val;
1047 +
1048 + val = ltq_reset_map(module);
1049 + if (unlikely(!val))
1050 + return 1;
1051 +
1052 + ltq_setbits(&ltq_rcu_regs->req, val);
1053 +
1054 + return 0;
1055 +}
1056 +
1057 +int ltq_reset_deactivate(enum ltq_reset_modules module)
1058 +{
1059 + u32 val;
1060 +
1061 + val = ltq_reset_map(module);
1062 + if (unlikely(!val))
1063 + return 1;
1064 +
1065 + ltq_clrbits(&ltq_rcu_regs->req, val);
1066 +
1067 + return 0;
1068 +}
1069 +
1070 +enum ltq_boot_select ltq_boot_select(void)
1071 +{
1072 + u32 stat;
1073 + unsigned int bootstrap;
1074 +
1075 + stat = ltq_readl(&ltq_rcu_regs->stat);
1076 + bootstrap = (stat & LTQ_RCU_STAT_BOOT_MASK) >> LTQ_RCU_STAT_BOOT_SHIFT;
1077 +
1078 + switch (bootstrap) {
1079 + case 0:
1080 + return BOOT_NOR_NO_BOOTROM;
1081 + case 1:
1082 + return BOOT_NOR;
1083 + case 2:
1084 + return BOOT_MII0;
1085 + case 3:
1086 + return BOOT_PCI;
1087 + case 4:
1088 + return BOOT_UART;
1089 + case 5:
1090 + return BOOT_SPI;
1091 + case 6:
1092 + return BOOT_NAND;
1093 + case 7:
1094 + return BOOT_RMII0;
1095 + default:
1096 + return BOOT_UNKNOWN;
1097 + }
1098 +}
1099 diff --git a/arch/mips/cpu/mips32/lantiq-common/Makefile b/arch/mips/cpu/mips32/lantiq-common/Makefile
1100 new file mode 100644
1101 index 0000000..260d67c
1102 --- /dev/null
1103 +++ b/arch/mips/cpu/mips32/lantiq-common/Makefile
1104 @@ -0,0 +1,34 @@
1105 +#
1106 +# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de
1107 +#
1108 +# SPDX-License-Identifier: GPL-2.0+
1109 +#
1110 +
1111 +include $(TOPDIR)/config.mk
1112 +
1113 +LIB = $(obj)liblantiq-common.o
1114 +
1115 +START = start.o
1116 +COBJS-y = cpu.o pmu.o
1117 +COBJS-$(CONFIG_SPL_BUILD) += spl.o
1118 +SOBJS-y = lowlevel_init.o
1119 +
1120 +COBJS := $(COBJS-y)
1121 +SOBJS := $(SOBJS-y)
1122 +SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
1123 +OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
1124 +START := $(addprefix $(obj),$(START))
1125 +
1126 +all: $(LIB)
1127 +
1128 +$(LIB): $(obj).depend $(OBJS)
1129 + $(call cmd_link_o_target, $(OBJS))
1130 +
1131 +#########################################################################
1132 +
1133 +# defines $(obj).depend target
1134 +include $(SRCTREE)/rules.mk
1135 +
1136 +sinclude $(obj).depend
1137 +
1138 +#########################################################################
1139 diff --git a/arch/mips/cpu/mips32/lantiq-common/cpu.c b/arch/mips/cpu/mips32/lantiq-common/cpu.c
1140 new file mode 100644
1141 index 0000000..4a7acdf
1142 --- /dev/null
1143 +++ b/arch/mips/cpu/mips32/lantiq-common/cpu.c
1144 @@ -0,0 +1,59 @@
1145 +/*
1146 + * Copyright (C) 2012-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
1147 + *
1148 + * SPDX-License-Identifier: GPL-2.0+
1149 + */
1150 +
1151 +#include <common.h>
1152 +#include <asm/lantiq/chipid.h>
1153 +#include <asm/lantiq/clk.h>
1154 +#include <asm/lantiq/reset.h>
1155 +#include <asm/lantiq/cpu.h>
1156 +
1157 +static const char ltq_bootsel_strings[][16] = {
1158 + "NOR",
1159 + "NOR w/o BootROM",
1160 + "UART",
1161 + "UART w/o EEPROM",
1162 + "SPI",
1163 + "NAND",
1164 + "PCI",
1165 + "MII0",
1166 + "RMII0",
1167 + "RGMII1",
1168 + "unknown",
1169 +};
1170 +
1171 +const char *ltq_boot_select_str(void)
1172 +{ enum ltq_boot_select bootsel = ltq_boot_select();
1173 +
1174 + if (bootsel > BOOT_UNKNOWN)
1175 + bootsel = BOOT_UNKNOWN;
1176 +
1177 + return ltq_bootsel_strings[bootsel];
1178 +}
1179 +
1180 +void ltq_chip_print_info(void)
1181 +{
1182 + char buf[32];
1183 +
1184 + printf("SoC: Lantiq %s v1.%u\n", ltq_chip_partnum_str(),
1185 + ltq_chip_version_get());
1186 + printf("CPU: %s MHz\n", strmhz(buf, ltq_get_cpu_clock()));
1187 + printf("IO: %s MHz\n", strmhz(buf, ltq_get_io_region_clock()));
1188 + printf("BUS: %s MHz\n", strmhz(buf, ltq_get_bus_clock()));
1189 + printf("BOOT: %s\n", ltq_boot_select_str());
1190 +}
1191 +
1192 +int arch_cpu_init(void)
1193 +{
1194 + ltq_pmu_init();
1195 + ltq_ebu_init();
1196 +
1197 + return 0;
1198 +}
1199 +
1200 +void _machine_restart(void)
1201 +{
1202 + ltq_reset_activate(LTQ_RESET_CORE);
1203 +}
1204 diff --git a/arch/mips/cpu/mips32/lantiq-common/lowlevel_init.S b/arch/mips/cpu/mips32/lantiq-common/lowlevel_init.S
1205 new file mode 100644
1206 index 0000000..ad03b04
1207 --- /dev/null
1208 +++ b/arch/mips/cpu/mips32/lantiq-common/lowlevel_init.S
1209 @@ -0,0 +1,20 @@
1210 +/*
1211 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
1212 + *
1213 + * SPDX-License-Identifier: GPL-2.0+
1214 + */
1215 +
1216 +#include <asm/asm.h>
1217 +#include <asm/regdef.h>
1218 +
1219 +NESTED(lowlevel_init, 0, ra)
1220 + move t8, ra
1221 +
1222 + la t7, ltq_cgu_init
1223 + jalr t7
1224 +
1225 + la t7, ltq_mem_init
1226 + jalr t7
1227 +
1228 + jr t8
1229 + END(lowlevel_init)
1230 diff --git a/arch/mips/cpu/mips32/lantiq-common/pmu.c b/arch/mips/cpu/mips32/lantiq-common/pmu.c
1231 new file mode 100644
1232 index 0000000..8f0dac1
1233 --- /dev/null
1234 +++ b/arch/mips/cpu/mips32/lantiq-common/pmu.c
1235 @@ -0,0 +1,9 @@
1236 +/*
1237 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
1238 + *
1239 + * SPDX-License-Identifier: GPL-2.0+
1240 + */
1241 +
1242 +#include <common.h>
1243 +#include <asm/lantiq/pm.h>
1244 +
1245 diff --git a/arch/mips/cpu/mips32/lantiq-common/spl.c b/arch/mips/cpu/mips32/lantiq-common/spl.c
1246 new file mode 100644
1247 index 0000000..489a82b
1248 --- /dev/null
1249 +++ b/arch/mips/cpu/mips32/lantiq-common/spl.c
1250 @@ -0,0 +1,403 @@
1251 +/*
1252 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
1253 + *
1254 + * SPDX-License-Identifier: GPL-2.0+
1255 + */
1256 +
1257 +#include <common.h>
1258 +#include <image.h>
1259 +#include <version.h>
1260 +#include <spi_flash.h>
1261 +#include <linux/compiler.h>
1262 +#include <lzma/LzmaDec.h>
1263 +#include <linux/lzo.h>
1264 +#include <asm/mipsregs.h>
1265 +
1266 +#if defined(CONFIG_LTQ_SPL_CONSOLE)
1267 +#define spl_has_console 1
1268 +
1269 +#if defined(CONFIG_LTQ_SPL_DEBUG)
1270 +#define spl_has_debug 1
1271 +#else
1272 +#define spl_has_debug 0
1273 +#endif
1274 +
1275 +#else
1276 +#define spl_has_console 0
1277 +#define spl_has_debug 0
1278 +#endif
1279 +
1280 +#define spl_debug(fmt, args...) \
1281 + do { \
1282 + if (spl_has_debug) \
1283 + printf(fmt, ##args); \
1284 + } while (0)
1285 +
1286 +#define spl_puts(msg) \
1287 + do { \
1288 + if (spl_has_console) \
1289 + puts(msg); \
1290 + } while (0)
1291 +
1292 +#if defined(CONFIG_LTQ_SUPPORT_SPL_SPI_FLASH) && defined(CONFIG_SYS_BOOT_SFSPL)
1293 +#define spl_boot_spi_flash 1
1294 +#else
1295 +#define spl_boot_spi_flash 0
1296 +#ifndef CONFIG_SPL_SPI_BUS
1297 +#define CONFIG_SPL_SPI_BUS 0
1298 +#endif
1299 +#ifndef CONFIG_SPL_SPI_CS
1300 +#define CONFIG_SPL_SPI_CS 0
1301 +#endif
1302 +#ifndef CONFIG_SPL_SPI_MAX_HZ
1303 +#define CONFIG_SPL_SPI_MAX_HZ 0
1304 +#endif
1305 +#ifndef CONFIG_SPL_SPI_MODE
1306 +#define CONFIG_SPL_SPI_MODE 0
1307 +#endif
1308 +#endif
1309 +
1310 +#if defined(CONFIG_LTQ_SUPPORT_SPL_NOR_FLASH) && defined(CONFIG_SYS_BOOT_NORSPL)
1311 +#define spl_boot_nor_flash 1
1312 +#else
1313 +#define spl_boot_nor_flash 0
1314 +#endif
1315 +
1316 +#define spl_sync() __asm__ __volatile__("sync");
1317 +
1318 +struct spl_image {
1319 + ulong data_addr;
1320 + ulong entry_addr;
1321 + ulong data_size;
1322 + ulong entry_size;
1323 + ulong data_crc;
1324 + u8 comp;
1325 +};
1326 +
1327 +DECLARE_GLOBAL_DATA_PTR;
1328 +
1329 +/* Emulated malloc area needed for LZMA allocator in BSS */
1330 +static u8 *spl_mem_ptr __maybe_unused;
1331 +static size_t spl_mem_size __maybe_unused;
1332 +
1333 +static int spl_is_comp_lzma(const struct spl_image *spl)
1334 +{
1335 +#if defined(CONFIG_LTQ_SPL_COMP_LZMA)
1336 + return spl->comp == IH_COMP_LZMA;
1337 +#else
1338 + return 0;
1339 +#endif
1340 +}
1341 +
1342 +static int spl_is_comp_lzo(const struct spl_image *spl)
1343 +{
1344 +#if defined(CONFIG_LTQ_SPL_COMP_LZO)
1345 + return spl->comp == IH_COMP_LZO;
1346 +#else
1347 + return 0;
1348 +#endif
1349 +}
1350 +
1351 +static int spl_is_compressed(const struct spl_image *spl)
1352 +{
1353 + if (spl_is_comp_lzma(spl))
1354 + return 1;
1355 +
1356 + if (spl_is_comp_lzo(spl))
1357 + return 1;
1358 +
1359 + return 0;
1360 +}
1361 +
1362 +static void spl_console_init(void)
1363 +{
1364 + if (!spl_has_console)
1365 + return;
1366 +
1367 + gd->flags |= GD_FLG_RELOC;
1368 + gd->baudrate = CONFIG_BAUDRATE;
1369 +
1370 + serial_init();
1371 +
1372 + gd->have_console = 1;
1373 +
1374 + spl_puts("\nU-Boot SPL " PLAIN_VERSION " (" U_BOOT_DATE " - " \
1375 + U_BOOT_TIME ")\n");
1376 +}
1377 +
1378 +static int spl_parse_image(const image_header_t *hdr, struct spl_image *spl)
1379 +{
1380 + spl_puts("SPL: checking U-Boot image\n");
1381 +
1382 + if (!image_check_magic(hdr)) {
1383 + spl_puts("SPL: invalid magic\n");
1384 + return -1;
1385 + }
1386 +
1387 + if (!image_check_hcrc(hdr)) {
1388 + spl_puts("SPL: invalid header CRC\n");
1389 + return -1;
1390 + }
1391 +
1392 + spl->data_addr += image_get_header_size();
1393 + spl->entry_addr = image_get_load(hdr);
1394 + spl->data_size = image_get_data_size(hdr);
1395 + spl->data_crc = image_get_dcrc(hdr);
1396 + spl->comp = image_get_comp(hdr);
1397 +
1398 + spl_debug("SPL: data %08lx, size %lu, entry %08lx, comp %u\n",
1399 + spl->data_addr, spl->data_size, spl->entry_addr, spl->comp);
1400 +
1401 + return 0;
1402 +}
1403 +
1404 +static int spl_check_data(const struct spl_image *spl, ulong loadaddr)
1405 +{
1406 + ulong dcrc = crc32(0, (unsigned char *)loadaddr, spl->data_size);
1407 +
1408 + if (dcrc != spl->data_crc) {
1409 + spl_puts("SPL: invalid data CRC\n");
1410 + return 0;
1411 + }
1412 +
1413 + return 1;
1414 +}
1415 +
1416 +static void *spl_lzma_alloc(void *p, size_t size)
1417 +{
1418 + u8 *ret;
1419 +
1420 + if (size > spl_mem_size)
1421 + return NULL;
1422 +
1423 + ret = spl_mem_ptr;
1424 + spl_mem_ptr += size;
1425 + spl_mem_size -= size;
1426 +
1427 + return ret;
1428 +}
1429 +
1430 +static void spl_lzma_free(void *p, void *addr)
1431 +{
1432 +}
1433 +
1434 +static int spl_copy_image(struct spl_image *spl)
1435 +{
1436 + spl_puts("SPL: copying U-Boot to RAM\n");
1437 +
1438 + memcpy((void *) spl->entry_addr, (const void *) spl->data_addr,
1439 + spl->data_size);
1440 +
1441 + spl->entry_size = spl->data_size;
1442 +
1443 + return 0;
1444 +}
1445 +
1446 +static int spl_uncompress_lzma(struct spl_image *spl, unsigned long loadaddr)
1447 +{
1448 + SRes res;
1449 + const Byte *prop = (const Byte *) loadaddr;
1450 + const Byte *src = (const Byte *) loadaddr + LZMA_PROPS_SIZE +
1451 + sizeof(uint64_t);
1452 + Byte *dest = (Byte *) spl->entry_addr;
1453 + SizeT dest_len = 0xFFFFFFFF;
1454 + SizeT src_len = spl->data_size - LZMA_PROPS_SIZE;
1455 + ELzmaStatus status = 0;
1456 + ISzAlloc alloc;
1457 +
1458 + spl_puts("SPL: decompressing U-Boot with LZMA\n");
1459 +
1460 + alloc.Alloc = spl_lzma_alloc;
1461 + alloc.Free = spl_lzma_free;
1462 + spl_mem_ptr = (u8 *) CONFIG_SPL_MALLOC_BASE;
1463 + spl_mem_size = CONFIG_SPL_MALLOC_MAX_SIZE;
1464 +
1465 + res = LzmaDecode(dest, &dest_len, src, &src_len, prop, LZMA_PROPS_SIZE,
1466 + LZMA_FINISH_ANY, &status, &alloc);
1467 + if (res != SZ_OK)
1468 + return 1;
1469 +
1470 + spl->entry_size = dest_len;
1471 +
1472 + return 0;
1473 +}
1474 +
1475 +static int spl_uncompress_lzo(struct spl_image *spl, unsigned long loadaddr)
1476 +{
1477 + size_t len;
1478 + int ret;
1479 +
1480 + spl_puts("SPL: decompressing U-Boot with LZO\n");
1481 +
1482 + ret = lzop_decompress(
1483 + (const unsigned char*) loadaddr, spl->data_size,
1484 + (unsigned char *) spl->entry_addr, &len);
1485 +
1486 + spl->entry_size = len;
1487 +
1488 + return ret;
1489 +}
1490 +
1491 +static int spl_uncompress(struct spl_image *spl, unsigned long loadaddr)
1492 +{
1493 + int ret;
1494 +
1495 + if (spl_is_comp_lzma(spl))
1496 + ret = spl_uncompress_lzma(spl, loadaddr);
1497 + else if (spl_is_comp_lzo(spl))
1498 + ret = spl_uncompress_lzo(spl, loadaddr);
1499 + else
1500 + ret = 1;
1501 +
1502 + return ret;
1503 +}
1504 +
1505 +static int spl_load_spi_flash(struct spl_image *spl)
1506 +{
1507 + struct spi_flash sf = { 0 };
1508 + image_header_t hdr;
1509 + int ret;
1510 + unsigned long loadaddr;
1511 +
1512 + /*
1513 + * Image format:
1514 + *
1515 + * - 12 byte non-volatile bootstrap header
1516 + * - SPL binary
1517 + * - 12 byte non-volatile bootstrap header
1518 + * - 64 byte U-Boot mkimage header
1519 + * - U-Boot binary
1520 + */
1521 + spl->data_addr = image_copy_end() - CONFIG_SPL_TEXT_BASE + 24;
1522 +
1523 + spl_puts("SPL: probing SPI flash\n");
1524 +
1525 + spi_init();
1526 + ret = spl_spi_flash_probe(&sf);
1527 + if (ret)
1528 + return ret;
1529 +
1530 + spl_debug("SPL: reading image header at offset %lx\n", spl->data_addr);
1531 +
1532 + ret = spi_flash_read(&sf, spl->data_addr, sizeof(hdr), &hdr);
1533 + if (ret)
1534 + return ret;
1535 +
1536 + spl_debug("SPL: checking image header at offset %lx\n", spl->data_addr);
1537 +
1538 + ret = spl_parse_image(&hdr, spl);
1539 + if (ret)
1540 + return ret;
1541 +
1542 + if (spl_is_compressed(spl))
1543 + loadaddr = CONFIG_LOADADDR;
1544 + else
1545 + loadaddr = spl->entry_addr;
1546 +
1547 + spl_puts("SPL: loading U-Boot to RAM\n");
1548 +
1549 + ret = spi_flash_read(&sf, spl->data_addr, spl->data_size,
1550 + (void *) loadaddr);
1551 +
1552 + if (!spl_check_data(spl, loadaddr))
1553 + return -1;
1554 +
1555 + if (spl_is_compressed(spl))
1556 + ret = spl_uncompress(spl, loadaddr);
1557 +
1558 + return ret;
1559 +}
1560 +
1561 +static int spl_load_nor_flash(struct spl_image *spl)
1562 +{
1563 + const image_header_t *hdr;
1564 + int ret;
1565 +
1566 + /*
1567 + * Image format:
1568 + *
1569 + * - SPL binary
1570 + * - 64 byte U-Boot mkimage header
1571 + * - U-Boot binary
1572 + */
1573 + spl->data_addr = image_copy_end();
1574 + hdr = (const image_header_t *) image_copy_end();
1575 +
1576 + spl_debug("SPL: checking image header at address %p\n", hdr);
1577 +
1578 + ret = spl_parse_image(hdr, spl);
1579 + if (ret)
1580 + return ret;
1581 +
1582 + if (spl_is_compressed(spl))
1583 + ret = spl_uncompress(spl, spl->data_addr);
1584 + else
1585 + ret = spl_copy_image(spl);
1586 +
1587 + return ret;
1588 +}
1589 +
1590 +static int spl_load(struct spl_image *spl)
1591 +{
1592 + int ret;
1593 +
1594 + if (spl_boot_spi_flash)
1595 + ret = spl_load_spi_flash(spl);
1596 + else if (spl_boot_nor_flash)
1597 + ret = spl_load_nor_flash(spl);
1598 + else
1599 + ret = 1;
1600 +
1601 + return ret;
1602 +}
1603 +
1604 +void __noreturn spl_lantiq_init(void)
1605 +{
1606 + void (*uboot)(void) __noreturn;
1607 + struct spl_image spl;
1608 + gd_t gd_data;
1609 + int ret;
1610 +
1611 + gd = &gd_data;
1612 + barrier();
1613 + memset((void *)gd, 0, sizeof(gd_t));
1614 +
1615 + spl_console_init();
1616 +
1617 + spl_debug("SPL: initializing\n");
1618 +
1619 +#if 0
1620 + spl_debug("CP0_CONFIG: %08x\n", read_c0_config());
1621 + spl_debug("CP0_CONFIG1: %08x\n", read_c0_config1());
1622 + spl_debug("CP0_CONFIG2: %08x\n", read_c0_config2());
1623 + spl_debug("CP0_CONFIG3: %08x\n", read_c0_config3());
1624 + spl_debug("CP0_CONFIG6: %08x\n", read_c0_config6());
1625 + spl_debug("CP0_CONFIG7: %08x\n", read_c0_config7());
1626 + spl_debug("CP0_STATUS: %08x\n", read_c0_status());
1627 + spl_debug("CP0_PRID: %08x\n", read_c0_prid());
1628 +#endif
1629 +
1630 + board_early_init_f();
1631 + timer_init();
1632 +
1633 + memset(&spl, 0, sizeof(spl));
1634 +
1635 + ret = spl_load(&spl);
1636 + if (ret)
1637 + goto hang;
1638 +
1639 + spl_debug("SPL: U-Boot entry %08lx\n", spl.entry_addr);
1640 + spl_puts("SPL: jumping to U-Boot\n");
1641 +
1642 + flush_cache(spl.entry_addr, spl.entry_size);
1643 + spl_sync();
1644 +
1645 + uboot = (void *) spl.entry_addr;
1646 + uboot();
1647 +
1648 +hang:
1649 + spl_puts("SPL: cannot start U-Boot\n");
1650 +
1651 + for (;;)
1652 + ;
1653 +}
1654 diff --git a/arch/mips/cpu/mips32/lantiq-common/start.S b/arch/mips/cpu/mips32/lantiq-common/start.S
1655 new file mode 100644
1656 index 0000000..481d739
1657 --- /dev/null
1658 +++ b/arch/mips/cpu/mips32/lantiq-common/start.S
1659 @@ -0,0 +1,143 @@
1660 +/*
1661 + * Copyright (C) 2010 Lantiq Deutschland GmbH
1662 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
1663 + *
1664 + * SPDX-License-Identifier: GPL-2.0+
1665 + */
1666 +
1667 +#include <config.h>
1668 +#include <asm/regdef.h>
1669 +#include <asm/mipsregs.h>
1670 +
1671 +#define S_PRIdCoID 16 /* Company ID (R) */
1672 +#define M_PRIdCoID (0xff << S_PRIdCoID)
1673 +#define S_PRIdImp 8 /* Implementation ID (R) */
1674 +#define M_PRIdImp (0xff << S_PRIdImp)
1675 +
1676 +#define K_CacheAttrCWTnWA 0 /* Cacheable, write-thru, no write allocate */
1677 +#define K_CacheAttrCWTWA 1 /* Cacheable, write-thru, write allocate */
1678 +#define K_CacheAttrU 2 /* Uncached */
1679 +#define K_CacheAttrC 3 /* Cacheable */
1680 +#define K_CacheAttrCN 3 /* Cacheable, non-coherent */
1681 +#define K_CacheAttrCCE 4 /* Cacheable, coherent, exclusive */
1682 +#define K_CacheAttrCCS 5 /* Cacheable, coherent, shared */
1683 +#define K_CacheAttrCCU 6 /* Cacheable, coherent, update */
1684 +#define K_CacheAttrUA 7 /* Uncached accelerated */
1685 +
1686 +#define S_ConfigK23 28 /* Kseg2/3 coherency algorithm (FM MMU only) (R/W) */
1687 +#define M_ConfigK23 (0x7 << S_ConfigK23)
1688 +#define W_ConfigK23 3
1689 +#define S_ConfigKU 25 /* Kuseg coherency algorithm (FM MMU only) (R/W) */
1690 +#define M_ConfigKU (0x7 << S_ConfigKU)
1691 +#define W_ConfigKU 3
1692 +
1693 +#define S_ConfigMM 18 /* Merge mode (implementation specific) */
1694 +#define M_ConfigMM (0x1 << S_ConfigMM)
1695 +
1696 +#define S_StatusBEV 22 /* Enable Boot Exception Vectors (R/W) */
1697 +#define M_StatusBEV (0x1 << S_StatusBEV)
1698 +
1699 +#define S_StatusFR 26 /* Enable 64-bit FPRs (R/W) */
1700 +#define M_StatusFR (0x1 << S_StatusFR)
1701 +
1702 +#define S_ConfigK0 0 /* Kseg0 coherency algorithm (R/W) */
1703 +#define M_ConfigK0 (0x7 << S_ConfigK0)
1704 +
1705 +#define CONFIG0_MIPS32_64_MSK 0x8000ffff
1706 +#define STATUS_MIPS32_64_MSK 0xfffcffff
1707 +
1708 +#define STATUS_MIPS24K 0
1709 +#define CONFIG0_MIPS24K ((K_CacheAttrCN << S_ConfigK23) |\
1710 + (K_CacheAttrCN << S_ConfigKU) |\
1711 + (M_ConfigMM))
1712 +
1713 +#define STATUS_MIPS34K 0
1714 +#define CONFIG0_MIPS34K ((K_CacheAttrCN << S_ConfigK23) |\
1715 + (K_CacheAttrCN << S_ConfigKU) |\
1716 + (M_ConfigMM))
1717 +
1718 +#define STATUS_MIPS32_64 (M_StatusBEV | M_StatusFR)
1719 +#define CONFIG0_MIPS32_64 (K_CacheAttrCN << S_ConfigK0)
1720 +
1721 +#ifdef CONFIG_SOC_XWAY_DANUBE
1722 +#define CONFIG0_LANTIQ (CONFIG0_MIPS24K | CONFIG0_MIPS32_64)
1723 +#define STATUS_LANTIQ (STATUS_MIPS24K | STATUS_MIPS32_64)
1724 +#endif
1725 +
1726 +#ifdef CONFIG_SOC_XWAY_VRX200
1727 +#define CONFIG0_LANTIQ (CONFIG0_MIPS34K | CONFIG0_MIPS32_64)
1728 +#define STATUS_LANTIQ (STATUS_MIPS34K | STATUS_MIPS32_64)
1729 +#endif
1730 +
1731 +
1732 + .set noreorder
1733 +
1734 + .globl _start
1735 + .text
1736 +_start:
1737 + /* Entry point */
1738 + b main
1739 + nop
1740 +
1741 + /* Lantiq SoC Boot config word */
1742 + .org 0x10
1743 +#ifdef CONFIG_SYS_XWAY_EBU_BOOTCFG
1744 + .word CONFIG_SYS_XWAY_EBU_BOOTCFG
1745 +#else
1746 + .word 0
1747 +#endif
1748 + .word 0
1749 +
1750 + .align 4
1751 +main:
1752 +
1753 + /* Init Timer */
1754 + mtc0 zero, CP0_COUNT
1755 + mtc0 zero, CP0_COMPARE
1756 +
1757 + /* Setup MIPS24K/MIPS34K specifics (implementation dependent fields) */
1758 + mfc0 t0, CP0_CONFIG
1759 + li t1, CONFIG0_MIPS32_64_MSK
1760 + and t0, t1
1761 + li t1, CONFIG0_LANTIQ
1762 + or t0, t1
1763 + mtc0 t0, CP0_CONFIG
1764 +
1765 + mfc0 t0, CP0_STATUS
1766 + li t1, STATUS_MIPS32_64_MSK
1767 + and t0, t1
1768 + li t1, STATUS_LANTIQ
1769 + or t0, t1
1770 + mtc0 t0, CP0_STATUS
1771 +
1772 + /* Initialize CGU */
1773 + la t9, ltq_cgu_init
1774 + jalr t9
1775 + nop
1776 +
1777 + /* Initialize memory controller */
1778 + la t9, ltq_mem_init
1779 + jalr t9
1780 + nop
1781 +
1782 + /* Initialize caches... */
1783 + la t9, mips_cache_reset
1784 + jalr t9
1785 + nop
1786 +
1787 + /* Clear BSS */
1788 + la t1, __bss_start
1789 + la t2, __bss_end
1790 + sub t1, 4
1791 +1:
1792 + addi t1, 4
1793 + bltl t1, t2, 1b
1794 + sw zero, 0(t1)
1795 +
1796 + /* Setup stack pointer and force alignment on a 16 byte boundary */
1797 + li t0, (CONFIG_SPL_STACK_BASE & ~0xF)
1798 + la sp, 0(t0)
1799 +
1800 + la t9, spl_lantiq_init
1801 + jr t9
1802 + nop
1803 diff --git a/arch/mips/cpu/mips32/lantiq-common/u-boot-spl.lds b/arch/mips/cpu/mips32/lantiq-common/u-boot-spl.lds
1804 new file mode 100644
1805 index 0000000..97c8fa8
1806 --- /dev/null
1807 +++ b/arch/mips/cpu/mips32/lantiq-common/u-boot-spl.lds
1808 @@ -0,0 +1,48 @@
1809 +/*
1810 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
1811 + *
1812 + * SPDX-License-Identifier: GPL-2.0+
1813 + */
1814 +
1815 +MEMORY { .spl_mem : ORIGIN = CONFIG_SPL_TEXT_BASE, \
1816 + LENGTH = CONFIG_SPL_MAX_SIZE }
1817 +MEMORY { .bss_mem : ORIGIN = CONFIG_SPL_BSS_BASE, \
1818 + LENGTH = CONFIG_SPL_BSS_MAX_SIZE }
1819 +
1820 +OUTPUT_FORMAT("elf32-tradbigmips", "elf32-tradbigmips", "elf32-tradlittlemips")
1821 +OUTPUT_ARCH(mips)
1822 +ENTRY(_start)
1823 +SECTIONS
1824 +{
1825 + . = ALIGN(4);
1826 + .text : {
1827 + *(.text*)
1828 + } > .spl_mem
1829 +
1830 + . = ALIGN(4);
1831 + .rodata : {
1832 + *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*)))
1833 + } > .spl_mem
1834 +
1835 + . = ALIGN(4);
1836 + .data : {
1837 + *(SORT_BY_ALIGNMENT(.data*))
1838 + *(SORT_BY_ALIGNMENT(.sdata*))
1839 + } > .spl_mem
1840 +
1841 + . = ALIGN(4);
1842 + __image_copy_end = .;
1843 + uboot_end_data = .;
1844 +
1845 + .bss : {
1846 + __bss_start = .;
1847 + *(.bss*)
1848 + *(.sbss*)
1849 + . = ALIGN(4);
1850 + __bss_end = .;
1851 + } > .bss_mem
1852 +
1853 + . = ALIGN(4);
1854 + __end = .;
1855 + uboot_end = .;
1856 +}
1857 diff --git a/arch/mips/cpu/mips32/start.S b/arch/mips/cpu/mips32/start.S
1858 index 70ad198..091a4e2 100644
1859 --- a/arch/mips/cpu/mips32/start.S
1860 +++ b/arch/mips/cpu/mips32/start.S
1861 @@ -105,7 +105,7 @@ reset:
1862 mtc0 zero, CP0_COUNT
1863 mtc0 zero, CP0_COMPARE
1864
1865 -#ifndef CONFIG_SKIP_LOWLEVEL_INIT
1866 +#if !defined(CONFIG_SKIP_LOWLEVEL_INIT) || defined(CONFIG_SYS_DISABLE_CACHE)
1867 /* CONFIG0 register */
1868 li t0, CONF_CM_UNCACHED
1869 mtc0 t0, CP0_CONFIG
1870 diff --git a/arch/mips/cpu/mips32/vrx200/Makefile b/arch/mips/cpu/mips32/vrx200/Makefile
1871 new file mode 100644
1872 index 0000000..714dc69
1873 --- /dev/null
1874 +++ b/arch/mips/cpu/mips32/vrx200/Makefile
1875 @@ -0,0 +1,32 @@
1876 +#
1877 +# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de
1878 +#
1879 +# SPDX-License-Identifier: GPL-2.0+
1880 +#
1881 +
1882 +include $(TOPDIR)/config.mk
1883 +
1884 +LIB = $(obj)lib$(SOC).o
1885 +
1886 +COBJS-y += cgu.o chipid.o dcdc.o ebu.o gphy.o mem.o pmu.o rcu.o
1887 +SOBJS-y += cgu_init.o mem_init.o
1888 +SOBJS-y += gphy_fw.o
1889 +
1890 +COBJS := $(COBJS-y)
1891 +SOBJS := $(SOBJS-y)
1892 +SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
1893 +OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
1894 +
1895 +all: $(LIB)
1896 +
1897 +$(LIB): $(obj).depend $(OBJS)
1898 + $(call cmd_link_o_target, $(OBJS))
1899 +
1900 +#########################################################################
1901 +
1902 +# defines $(obj).depend target
1903 +include $(SRCTREE)/rules.mk
1904 +
1905 +sinclude $(obj).depend
1906 +
1907 +#########################################################################
1908 diff --git a/arch/mips/cpu/mips32/vrx200/cgu.c b/arch/mips/cpu/mips32/vrx200/cgu.c
1909 new file mode 100644
1910 index 0000000..799c902
1911 --- /dev/null
1912 +++ b/arch/mips/cpu/mips32/vrx200/cgu.c
1913 @@ -0,0 +1,208 @@
1914 +/*
1915 + * Copyright (C) 2010 Lantiq Deutschland GmbH
1916 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
1917 + *
1918 + * SPDX-License-Identifier: GPL-2.0+
1919 + */
1920 +
1921 +#include <common.h>
1922 +#include <asm/arch/soc.h>
1923 +#include <asm/arch/gphy.h>
1924 +#include <asm/lantiq/clk.h>
1925 +#include <asm/lantiq/io.h>
1926 +
1927 +#define LTQ_CGU_PLL1_PLLN_SHIFT 6
1928 +#define LTQ_CGU_PLL1_PLLN_MASK (0x3F << LTQ_CGU_PLL1_PLLN_SHIFT)
1929 +#define LTQ_CGU_PLL1_PLLM_SHIFT 2
1930 +#define LTQ_CGU_PLL1_PLLM_MASK (0xF << LTQ_CGU_PLL1_PLLM_SHIFT)
1931 +#define LTQ_CGU_PLL1_PLLL (1 << 1)
1932 +#define LTQ_CGU_PLL1_PLL_EN 1
1933 +
1934 +#define LTQ_CGU_SYS_OCP_SHIFT 0
1935 +#define LTQ_CGU_SYS_OCP_MASK (0x3 << LTQ_CGU_SYS_OCP_SHIFT)
1936 +#define LTQ_CGU_SYS_CPU_SHIFT 4
1937 +#define LTQ_CGU_SYS_CPU_MASK (0xF << LTQ_CGU_SYS_CPU_SHIFT)
1938 +
1939 +#define LTQ_CGU_UPDATE 1
1940 +
1941 +#define LTQ_CGU_IFCLK_GPHY_SEL_SHIFT 2
1942 +#define LTQ_CGU_IFCLK_GPHY_SEL_MASK (0x7 << LTQ_CGU_IFCLK_GPHY_SEL_SHIFT)
1943 +
1944 +struct ltq_cgu_regs {
1945 + u32 rsvd0;
1946 + u32 pll0_cfg; /* PLL0 config */
1947 + u32 pll1_cfg; /* PLL1 config */
1948 + u32 sys; /* System clock */
1949 + u32 clk_fsr; /* Clock frequency select */
1950 + u32 clk_gsr; /* Clock gating status */
1951 + u32 clk_gcr0; /* Clock gating control 0 */
1952 + u32 clk_gcr1; /* Clock gating control 1 */
1953 + u32 update; /* CGU update control */
1954 + u32 if_clk; /* Interface clock */
1955 + u32 ddr; /* DDR memory control */
1956 + u32 ct1_sr; /* CT status 1 */
1957 + u32 ct_kval; /* CT K value */
1958 + u32 pcm_cr; /* PCM control */
1959 + u32 pci_cr; /* PCI clock control */
1960 + u32 rsvd1;
1961 + u32 gphy1_cfg; /* GPHY1 config */
1962 + u32 gphy0_cfg; /* GPHY0 config */
1963 + u32 rsvd2[6];
1964 + u32 pll2_cfg; /* PLL2 config */
1965 +};
1966 +
1967 +static struct ltq_cgu_regs *ltq_cgu_regs =
1968 + (struct ltq_cgu_regs *) CKSEG1ADDR(LTQ_CGU_BASE);
1969 +
1970 +static inline u32 ltq_cgu_sys_readl(u32 mask, u32 shift)
1971 +{
1972 + return (ltq_readl(&ltq_cgu_regs->sys) & mask) >> shift;
1973 +}
1974 +
1975 +unsigned long ltq_get_io_region_clock(void)
1976 +{
1977 + unsigned int ocp_sel;
1978 + unsigned long clk, cpu_clk;
1979 +
1980 + cpu_clk = ltq_get_cpu_clock();
1981 +
1982 + ocp_sel = ltq_cgu_sys_readl(LTQ_CGU_SYS_OCP_MASK,
1983 + LTQ_CGU_SYS_OCP_SHIFT);
1984 +
1985 + switch (ocp_sel) {
1986 + case 0:
1987 + /* OCP ratio 1 */
1988 + clk = cpu_clk;
1989 + break;
1990 + case 2:
1991 + /* OCP ratio 2 */
1992 + clk = cpu_clk / 2;
1993 + break;
1994 + case 3:
1995 + /* OCP ratio 2.5 */
1996 + clk = (cpu_clk * 2) / 5;
1997 + break;
1998 + case 4:
1999 + /* OCP ratio 3 */
2000 + clk = cpu_clk / 3;
2001 + break;
2002 + default:
2003 + clk = 0;
2004 + break;
2005 + }
2006 +
2007 + return clk;
2008 +}
2009 +
2010 +unsigned long ltq_get_cpu_clock(void)
2011 +{
2012 + unsigned int cpu_sel;
2013 + unsigned long clk;
2014 +
2015 + cpu_sel = ltq_cgu_sys_readl(LTQ_CGU_SYS_CPU_MASK,
2016 + LTQ_CGU_SYS_CPU_SHIFT);
2017 +
2018 + switch (cpu_sel) {
2019 + case 0:
2020 + clk = CLOCK_600_MHZ;
2021 + break;
2022 + case 1:
2023 + clk = CLOCK_500_MHZ;
2024 + break;
2025 + case 2:
2026 + clk = CLOCK_393_MHZ;
2027 + break;
2028 + case 3:
2029 + clk = CLOCK_333_MHZ;
2030 + break;
2031 + case 5:
2032 + case 6:
2033 + clk = CLOCK_197_MHZ;
2034 + break;
2035 + case 7:
2036 + clk = CLOCK_166_MHZ;
2037 + break;
2038 + case 4:
2039 + case 8:
2040 + case 9:
2041 + clk = CLOCK_125_MHZ;
2042 + break;
2043 + default:
2044 + clk = 0;
2045 + break;
2046 + }
2047 +
2048 + return clk;
2049 +}
2050 +
2051 +unsigned long ltq_get_bus_clock(void)
2052 +{
2053 + return ltq_get_io_region_clock();
2054 +}
2055 +
2056 +void ltq_cgu_gphy_clk_src(enum ltq_gphy_clk clk)
2057 +{
2058 + ltq_clrbits(&ltq_cgu_regs->if_clk, LTQ_CGU_IFCLK_GPHY_SEL_MASK);
2059 + ltq_setbits(&ltq_cgu_regs->if_clk, clk << LTQ_CGU_IFCLK_GPHY_SEL_SHIFT);
2060 +}
2061 +
2062 +static inline int ltq_cgu_pll1_locked(void)
2063 +{
2064 + u32 pll1_cfg = ltq_readl(&ltq_cgu_regs->pll1_cfg);
2065 +
2066 + return pll1_cfg & LTQ_CGU_PLL1_PLLL;
2067 +}
2068 +
2069 +static inline void ltq_cgu_pll1_restart(unsigned m, unsigned n)
2070 +{
2071 + u32 pll1_cfg;
2072 +
2073 + ltq_clrbits(&ltq_cgu_regs->pll1_cfg, LTQ_CGU_PLL1_PLL_EN);
2074 + ltq_setbits(&ltq_cgu_regs->update, LTQ_CGU_UPDATE);
2075 +
2076 + pll1_cfg = ltq_readl(&ltq_cgu_regs->pll1_cfg);
2077 + pll1_cfg &= ~(LTQ_CGU_PLL1_PLLN_MASK | LTQ_CGU_PLL1_PLLM_MASK);
2078 + pll1_cfg |= n << LTQ_CGU_PLL1_PLLN_SHIFT;
2079 + pll1_cfg |= m << LTQ_CGU_PLL1_PLLM_SHIFT;
2080 + pll1_cfg |= LTQ_CGU_PLL1_PLL_EN;
2081 + ltq_writel(&ltq_cgu_regs->pll1_cfg, pll1_cfg);
2082 + ltq_setbits(&ltq_cgu_regs->update, LTQ_CGU_UPDATE);
2083 +
2084 + __udelay(1000);
2085 +}
2086 +
2087 +/*
2088 + * From chapter 9 in errata sheet:
2089 + *
2090 + * Under certain condition, the PLL1 may failed to enter into lock
2091 + * status by hardware default N, M setting.
2092 + *
2093 + * Since system always starts from PLL0, the system software can run
2094 + * and re-program the PLL1 settings.
2095 + */
2096 +static void ltq_cgu_pll1_init(void)
2097 +{
2098 + unsigned i;
2099 + const unsigned pll1_m[] = { 1, 2, 3, 4 };
2100 + const unsigned pll1_n[] = { 21, 32, 43, 54 };
2101 +
2102 + /* Check if PLL1 has locked with hardware default settings */
2103 + if (ltq_cgu_pll1_locked())
2104 + return;
2105 +
2106 + for (i = 0; i < 4; i++) {
2107 + ltq_cgu_pll1_restart(pll1_m[i], pll1_n[i]);
2108 +
2109 + if (ltq_cgu_pll1_locked())
2110 + goto done;
2111 + }
2112 +
2113 +done:
2114 + /* Restart with hardware default values M=5, N=64 */
2115 + ltq_cgu_pll1_restart(5, 64);
2116 +}
2117 +
2118 +void ltq_pll_init(void)
2119 +{
2120 + ltq_cgu_pll1_init();
2121 +}
2122 diff --git a/arch/mips/cpu/mips32/vrx200/cgu_init.S b/arch/mips/cpu/mips32/vrx200/cgu_init.S
2123 new file mode 100644
2124 index 0000000..190ef89
2125 --- /dev/null
2126 +++ b/arch/mips/cpu/mips32/vrx200/cgu_init.S
2127 @@ -0,0 +1,119 @@
2128 +/*
2129 + * Copyright (C) 2010 Lantiq Deutschland GmbH
2130 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
2131 + *
2132 + * SPDX-License-Identifier: GPL-2.0+
2133 + */
2134 +
2135 +#include <config.h>
2136 +#include <asm/asm.h>
2137 +#include <asm/regdef.h>
2138 +#include <asm/addrspace.h>
2139 +#include <asm/arch/soc.h>
2140 +
2141 +/* RCU module register */
2142 +#define LTQ_RCU_RST_REQ 0x0010 /* Reset request */
2143 +#define LTQ_RCU_RST_REQ_VALUE ((1 << 14) | (1 << 1))
2144 +
2145 +/* CGU module register */
2146 +#define LTQ_CGU_PLL0_CFG 0x0004 /* PLL0 config */
2147 +#define LTQ_CGU_PLL1_CFG 0x0008 /* PLL1 config */
2148 +#define LTQ_CGU_PLL2_CFG 0x0060 /* PLL2 config */
2149 +#define LTQ_CGU_SYS 0x000C /* System clock */
2150 +#define LTQ_CGU_CLK_FSR 0x0010 /* Clock frequency select */
2151 +#define LTQ_CGU_UPDATE 0x0020 /* Clock update control */
2152 +
2153 +/* Valid SYS.CPU values */
2154 +#define LTQ_CGU_SYS_CPU_SHIFT 4
2155 +#define LTQ_CGU_SYS_CPU_600_MHZ 0x0
2156 +#define LTQ_CGU_SYS_CPU_500_MHZ 0x1
2157 +#define LTQ_CGU_SYS_CPU_393_MHZ 0x2
2158 +#define LTQ_CGU_SYS_CPU_333_MHZ 0x3
2159 +#define LTQ_CGU_SYS_CPU_197_MHZ 0x5
2160 +#define LTQ_CGU_SYS_CPU_166_MHZ 0x7
2161 +#define LTQ_CGU_SYS_CPU_125_MHZ 0x9
2162 +
2163 +/* Valid SYS.OCP values */
2164 +#define LTQ_CGU_SYS_OCP_SHIFT 0
2165 +#define LTQ_CGU_SYS_OCP_1 0x0
2166 +#define LTQ_CGU_SYS_OCP_2 0x2
2167 +#define LTQ_CGU_SYS_OCP_2_5 0x3
2168 +#define LTQ_CGU_SYS_OCP_3 0x4
2169 +
2170 +/* Valid CLK_FSR.ETH values */
2171 +#define LTQ_CGU_CLK_FSR_ETH_SHIFT 24
2172 +#define LTQ_CGU_CLK_FSR_ETH_50_MHZ 0x0
2173 +#define LTQ_CGU_CLK_FSR_ETH_25_MHZ 0x1
2174 +#define LTQ_CGU_CLK_FSR_ETH_2_5_MHZ 0x2
2175 +#define LTQ_CGU_CLK_FSR_ETH_125_MHZ 0x3
2176 +
2177 +/* Valid CLK_FSR.PPE values */
2178 +#define LTQ_CGU_CLK_FSR_PPE_SHIFT 16
2179 +#define LTQ_CGU_CLK_FSR_PPE_500_MHZ 0x0 /* Overclock frequency */
2180 +#define LTQ_CGU_CLK_FSR_PPE_450_MHZ 0x1 /* High frequency */
2181 +#define LTQ_CGU_CLK_FSR_PPE_400_MHZ 0x2 /* Low frequency */
2182 +
2183 +#if (CONFIG_SYS_CLOCK_MODE == LTQ_CLK_CPU_500_DDR_250)
2184 +#define LTQ_CGU_SYS_CPU_CONFIG LTQ_CGU_SYS_CPU_500_MHZ
2185 +#define LTQ_CGU_SYS_OCP_CONFIG LTQ_CGU_SYS_OCP_2
2186 +#define LTQ_CGU_CLK_FSR_ETH_CONFIG LTQ_CGU_CLK_FSR_ETH_125_MHZ
2187 +#define LTQ_CGU_CLK_FSR_PPE_CONFIG LTQ_CGU_CLK_FSR_PPE_450_MHZ
2188 +#else
2189 +#error "Invalid system clock configuration!"
2190 +#endif
2191 +
2192 +/* Build register values */
2193 +#define LTQ_CGU_SYS_VALUE ((LTQ_CGU_SYS_CPU_CONFIG << \
2194 + LTQ_CGU_SYS_CPU_SHIFT) | \
2195 + LTQ_CGU_SYS_OCP_CONFIG)
2196 +
2197 +#define LTQ_CGU_CLK_FSR_VALUE ((LTQ_CGU_CLK_FSR_ETH_CONFIG << \
2198 + LTQ_CGU_CLK_FSR_ETH_SHIFT) | \
2199 + (LTQ_CGU_CLK_FSR_PPE_CONFIG << \
2200 + LTQ_CGU_CLK_FSR_PPE_SHIFT))
2201 +
2202 + .set noreorder
2203 +
2204 +LEAF(ltq_cgu_init)
2205 + /* Load current CGU register values */
2206 + li t0, (LTQ_CGU_BASE | KSEG1)
2207 + lw t1, LTQ_CGU_SYS(t0)
2208 + lw t2, LTQ_CGU_CLK_FSR(t0)
2209 +
2210 + /* Load target CGU register values */
2211 + li t3, LTQ_CGU_SYS_VALUE
2212 + li t4, LTQ_CGU_CLK_FSR_VALUE
2213 +
2214 + /* Only update registers if values differ */
2215 + bne t1, t3, update
2216 + nop
2217 + beq t2, t4, finished
2218 + nop
2219 +
2220 +update:
2221 + /* Store target register values */
2222 + sw t3, LTQ_CGU_SYS(t0)
2223 + sw t4, LTQ_CGU_CLK_FSR(t0)
2224 +
2225 + /* Perform software reset to activate new clock config */
2226 +#if 0
2227 + li t0, (LTQ_RCU_BASE | KSEG1)
2228 + lw t1, LTQ_RCU_RST_REQ(t0)
2229 + or t1, LTQ_RCU_RST_REQ_VALUE
2230 + sw t1, LTQ_RCU_RST_REQ(t0)
2231 +#else
2232 + li t1, 1
2233 + sw t1, LTQ_CGU_UPDATE(t0)
2234 +#endif
2235 +
2236 +#if 0
2237 +wait_reset:
2238 + b wait_reset
2239 + nop
2240 +#endif
2241 +
2242 +finished:
2243 + jr ra
2244 + nop
2245 +
2246 + END(ltq_cgu_init)
2247 diff --git a/arch/mips/cpu/mips32/vrx200/chipid.c b/arch/mips/cpu/mips32/vrx200/chipid.c
2248 new file mode 100644
2249 index 0000000..f916e87
2250 --- /dev/null
2251 +++ b/arch/mips/cpu/mips32/vrx200/chipid.c
2252 @@ -0,0 +1,62 @@
2253 +/*
2254 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
2255 + *
2256 + * SPDX-License-Identifier: GPL-2.0+
2257 + */
2258 +
2259 +#include <common.h>
2260 +#include <asm/lantiq/io.h>
2261 +#include <asm/lantiq/chipid.h>
2262 +#include <asm/arch/soc.h>
2263 +
2264 +#define LTQ_CHIPID_VERSION_SHIFT 28
2265 +#define LTQ_CHIPID_VERSION_MASK (0x7 << LTQ_CHIPID_VERSION_SHIFT)
2266 +#define LTQ_CHIPID_PNUM_SHIFT 12
2267 +#define LTQ_CHIPID_PNUM_MASK (0xFFFF << LTQ_CHIPID_PNUM_SHIFT)
2268 +
2269 +struct ltq_chipid_regs {
2270 + u32 manid; /* Manufacturer identification */
2271 + u32 chipid; /* Chip identification */
2272 +};
2273 +
2274 +static struct ltq_chipid_regs *ltq_chipid_regs =
2275 + (struct ltq_chipid_regs *) CKSEG1ADDR(LTQ_CHIPID_BASE);
2276 +
2277 +unsigned int ltq_chip_version_get(void)
2278 +{
2279 + u32 chipid;
2280 +
2281 + chipid = ltq_readl(&ltq_chipid_regs->chipid);
2282 +
2283 + return (chipid & LTQ_CHIPID_VERSION_MASK) >> LTQ_CHIPID_VERSION_SHIFT;
2284 +}
2285 +
2286 +unsigned int ltq_chip_partnum_get(void)
2287 +{
2288 + u32 chipid;
2289 +
2290 + chipid = ltq_readl(&ltq_chipid_regs->chipid);
2291 +
2292 + return (chipid & LTQ_CHIPID_PNUM_MASK) >> LTQ_CHIPID_PNUM_SHIFT;
2293 +}
2294 +
2295 +const char *ltq_chip_partnum_str(void)
2296 +{
2297 + enum ltq_chip_partnum partnum = ltq_chip_partnum_get();
2298 +
2299 + switch (partnum) {
2300 + case LTQ_SOC_VRX268:
2301 + case LTQ_SOC_VRX268_2:
2302 + return "VRX268";
2303 + case LTQ_SOC_VRX288:
2304 + case LTQ_SOC_VRX288_2:
2305 + return "VRX288";
2306 + case LTQ_SOC_GRX288:
2307 + case LTQ_SOC_GRX288_2:
2308 + return "GRX288";
2309 + default:
2310 + printf("Unknown partnum: %x\n", partnum);
2311 + }
2312 +
2313 + return "";
2314 +}
2315 diff --git a/arch/mips/cpu/mips32/vrx200/config.mk b/arch/mips/cpu/mips32/vrx200/config.mk
2316 new file mode 100644
2317 index 0000000..442156a
2318 --- /dev/null
2319 +++ b/arch/mips/cpu/mips32/vrx200/config.mk
2320 @@ -0,0 +1,30 @@
2321 +#
2322 +# Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
2323 +#
2324 +# SPDX-License-Identifier: GPL-2.0+
2325 +#
2326 +
2327 +PF_CPPFLAGS_XRX := $(call cc-option,-mtune=34kc,)
2328 +PLATFORM_CPPFLAGS += $(PF_CPPFLAGS_XRX)
2329 +
2330 +ifdef CONFIG_SPL_BUILD
2331 +PF_ABICALLS := -mno-abicalls
2332 +PF_PIC := -fno-pic
2333 +PF_PIE :=
2334 +USE_PRIVATE_LIBGCC := yes
2335 +endif
2336 +
2337 +LIBS-y += $(CPUDIR)/lantiq-common/liblantiq-common.o
2338 +
2339 +ifndef CONFIG_SPL_BUILD
2340 +ifdef CONFIG_SYS_BOOT_SFSPL
2341 +ALL-y += $(obj)u-boot.ltq.sfspl
2342 +ALL-$(CONFIG_SPL_LZO_SUPPORT) += $(obj)u-boot.ltq.lzo.sfspl
2343 +ALL-$(CONFIG_SPL_LZMA_SUPPORT) += $(obj)u-boot.ltq.lzma.sfspl
2344 +endif
2345 +ifdef CONFIG_SYS_BOOT_NORSPL
2346 +ALL-y += $(obj)u-boot.ltq.norspl
2347 +ALL-$(CONFIG_SPL_LZO_SUPPORT) += $(obj)u-boot.ltq.lzo.norspl
2348 +ALL-$(CONFIG_SPL_LZMA_SUPPORT) += $(obj)u-boot.ltq.lzma.norspl
2349 +endif
2350 +endif
2351 diff --git a/arch/mips/cpu/mips32/vrx200/dcdc.c b/arch/mips/cpu/mips32/vrx200/dcdc.c
2352 new file mode 100644
2353 index 0000000..11ca0d7
2354 --- /dev/null
2355 +++ b/arch/mips/cpu/mips32/vrx200/dcdc.c
2356 @@ -0,0 +1,106 @@
2357 +/*
2358 + * Copyright (C) 2010 Lantiq Deutschland GmbH
2359 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
2360 + *
2361 + * SPDX-License-Identifier: GPL-2.0+
2362 + */
2363 +
2364 +#include <common.h>
2365 +#include <asm/arch/soc.h>
2366 +#include <asm/lantiq/io.h>
2367 +
2368 +#define LTQ_DCDC_CLK_SET0_CLK_SEL_P (1 << 6)
2369 +#define LTQ_DCDC_CLK_SET1_SEL_DIV25 (1 << 5)
2370 +#define LTQ_DCDC_CONF_TEST_DIG_PID_FREEZE (1 << 5)
2371 +
2372 +struct ltq_dcdc_regs {
2373 + u8 b0_coeh; /* Coefficient b0 */
2374 + u8 b0_coel; /* Coefficient b0 */
2375 + u8 b1_coeh; /* Coefficient b1 */
2376 + u8 b1_coel; /* Coefficient b1 */
2377 + u8 b2_coeh; /* Coefficient b2 */
2378 + u8 b2_coel; /* Coefficient b2 */
2379 + u8 clk_set0; /* Clock setup */
2380 + u8 clk_set1; /* Clock setup */
2381 + u8 pwm_confh; /* Configure PWM */
2382 + u8 pwm_confl; /* Configure PWM */
2383 + u8 bias_vreg0; /* Bias and regulator setup */
2384 + u8 bias_vreg1; /* Bias and regulator setup */
2385 + u8 adc_gen0; /* ADC and general control */
2386 + u8 adc_gen1; /* ADC and general control */
2387 + u8 adc_con0; /* ADC and general config */
2388 + u8 adc_con1; /* ADC and general config */
2389 + u8 conf_test_ana; /* not documented */
2390 + u8 conf_test_dig; /* not documented */
2391 + u8 dcdc_status; /* not documented */
2392 + u8 pid_status; /* not documented */
2393 + u8 duty_cycle; /* not documented */
2394 + u8 non_ov_delay; /* not documented */
2395 + u8 analog_gain; /* not documented */
2396 + u8 duty_cycle_max_sat; /* not documented */
2397 + u8 duty_cycle_min_sat; /* not documented */
2398 + u8 duty_cycle_max; /* not documented */
2399 + u8 duty_cycle_min; /* not documented */
2400 + u8 error_max; /* not documented */
2401 + u8 error_read; /* not documented */
2402 + u8 delay_deglitch; /* not documented */
2403 + u8 latch_control; /* not documented */
2404 + u8 rsvd[240];
2405 + u8 osc_conf; /* OSC general config */
2406 + u8 osc_stat; /* OSC general status */
2407 +};
2408 +
2409 +static struct ltq_dcdc_regs *ltq_dcdc_regs =
2410 + (struct ltq_dcdc_regs *) CKSEG1ADDR(LTQ_DCDC_BASE);
2411 +
2412 +void ltq_dcdc_init(unsigned int dig_ref)
2413 +{
2414 + u8 dig_ref_cur, val;
2415 +
2416 + /* Set duty cycle max sat. to 70/90, enable PID freeze */
2417 + ltq_writeb(&ltq_dcdc_regs->duty_cycle_max_sat, 0x5A);
2418 + ltq_writeb(&ltq_dcdc_regs->duty_cycle_min_sat, 0x46);
2419 + val = ltq_readb(&ltq_dcdc_regs->conf_test_dig);
2420 + val |= LTQ_DCDC_CONF_TEST_DIG_PID_FREEZE;
2421 + ltq_writeb(&ltq_dcdc_regs->conf_test_dig, val);
2422 +
2423 + /* Program new coefficients */
2424 + ltq_writeb(&ltq_dcdc_regs->b0_coeh, 0x00);
2425 + ltq_writeb(&ltq_dcdc_regs->b0_coel, 0x00);
2426 + ltq_writeb(&ltq_dcdc_regs->b1_coeh, 0xFF);
2427 + ltq_writeb(&ltq_dcdc_regs->b1_coel, 0xE6);
2428 + ltq_writeb(&ltq_dcdc_regs->b2_coeh, 0x00);
2429 + ltq_writeb(&ltq_dcdc_regs->b2_coel, 0x1B);
2430 + ltq_writeb(&ltq_dcdc_regs->non_ov_delay, 0x8B);
2431 +
2432 + /* Set duty cycle max sat. to 60/108, disable PID freeze */
2433 + ltq_writeb(&ltq_dcdc_regs->duty_cycle_max_sat, 0x6C);
2434 + ltq_writeb(&ltq_dcdc_regs->duty_cycle_min_sat, 0x3C);
2435 + val = ltq_readb(&ltq_dcdc_regs->conf_test_dig);
2436 + val &= ~LTQ_DCDC_CONF_TEST_DIG_PID_FREEZE;
2437 + ltq_writeb(&ltq_dcdc_regs->conf_test_dig, val);
2438 +
2439 + /* Init clock and DLL settings */
2440 + val = ltq_readb(&ltq_dcdc_regs->clk_set0);
2441 + val |= LTQ_DCDC_CLK_SET0_CLK_SEL_P;
2442 + ltq_writeb(&ltq_dcdc_regs->clk_set0, val);
2443 + val = ltq_readb(&ltq_dcdc_regs->clk_set1);
2444 + val |= LTQ_DCDC_CLK_SET1_SEL_DIV25;
2445 + ltq_writeb(&ltq_dcdc_regs->clk_set1, val);
2446 + ltq_writeb(&ltq_dcdc_regs->pwm_confh, 0xF9);
2447 +
2448 + wmb();
2449 +
2450 + /* Adapt value of digital reference of DCDC converter */
2451 + dig_ref_cur = ltq_readb(&ltq_dcdc_regs->bias_vreg1);
2452 +
2453 + while (dig_ref_cur != dig_ref) {
2454 + if (dig_ref >= dig_ref_cur)
2455 + dig_ref_cur++;
2456 + else if (dig_ref < dig_ref_cur)
2457 + dig_ref_cur--;
2458 +
2459 + ltq_writeb(&ltq_dcdc_regs->bias_vreg1, dig_ref_cur);
2460 + __udelay(1000);
2461 + }
2462 +}
2463 diff --git a/arch/mips/cpu/mips32/vrx200/ebu.c b/arch/mips/cpu/mips32/vrx200/ebu.c
2464 new file mode 100644
2465 index 0000000..4ab3cf1
2466 --- /dev/null
2467 +++ b/arch/mips/cpu/mips32/vrx200/ebu.c
2468 @@ -0,0 +1,111 @@
2469 +/*
2470 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
2471 + *
2472 + * SPDX-License-Identifier: GPL-2.0+
2473 + */
2474 +
2475 +#include <common.h>
2476 +#include <asm/arch/soc.h>
2477 +#include <asm/lantiq/io.h>
2478 +
2479 +#define EBU_ADDRSEL_MASK(mask) ((mask & 0xf) << 4)
2480 +#define EBU_ADDRSEL_REGEN (1 << 0)
2481 +
2482 +#define EBU_CON_WRDIS (1 << 31)
2483 +#define EBU_CON_AGEN_DEMUX (0x0 << 24)
2484 +#define EBU_CON_AGEN_MUX (0x2 << 24)
2485 +#define EBU_CON_SETUP (1 << 22)
2486 +#define EBU_CON_WAIT_DIS (0x0 << 20)
2487 +#define EBU_CON_WAIT_ASYNC (0x1 << 20)
2488 +#define EBU_CON_WAIT_SYNC (0x2 << 20)
2489 +#define EBU_CON_WINV (1 << 19)
2490 +#define EBU_CON_PW_8BIT (0x0 << 16)
2491 +#define EBU_CON_PW_16BIT (0x1 << 16)
2492 +#define EBU_CON_ALEC(cycles) ((cycles & 0x3) << 14)
2493 +#define EBU_CON_BCGEN_CS (0x0 << 12)
2494 +#define EBU_CON_BCGEN_INTEL (0x1 << 12)
2495 +#define EBU_CON_BCGEN_MOTOROLA (0x2 << 12)
2496 +#define EBU_CON_WAITWRC(cycles) ((cycles & 0x7) << 8)
2497 +#define EBU_CON_WAITRDC(cycles) ((cycles & 0x3) << 6)
2498 +#define EBU_CON_HOLDC(cycles) ((cycles & 0x3) << 4)
2499 +#define EBU_CON_RECOVC(cycles) ((cycles & 0x3) << 2)
2500 +#define EBU_CON_CMULT_1 0x0
2501 +#define EBU_CON_CMULT_4 0x1
2502 +#define EBU_CON_CMULT_8 0x2
2503 +#define EBU_CON_CMULT_16 0x3
2504 +
2505 +#if defined(CONFIG_LTQ_SUPPORT_NOR_FLASH)
2506 +#define ebu_region0_enable 1
2507 +#else
2508 +#define ebu_region0_enable 0
2509 +#endif
2510 +
2511 +#if defined(CONFIG_LTQ_SUPPORT_NAND_FLASH)
2512 +#define ebu_region1_enable 1
2513 +#else
2514 +#define ebu_region1_enable 0
2515 +#endif
2516 +
2517 +struct ltq_ebu_regs {
2518 + u32 clc;
2519 + u32 rsvd0;
2520 + u32 id;
2521 + u32 rsvd1;
2522 + u32 con;
2523 + u32 rsvd2[3];
2524 + u32 addr_sel_0;
2525 + u32 addr_sel_1;
2526 + u32 addr_sel_2;
2527 + u32 addr_sel_3;
2528 + u32 rsvd3[12];
2529 + u32 con_0;
2530 + u32 con_1;
2531 + u32 con_2;
2532 + u32 con_3;
2533 +};
2534 +
2535 +static struct ltq_ebu_regs *ltq_ebu_regs =
2536 + (struct ltq_ebu_regs *) CKSEG1ADDR(LTQ_EBU_BASE);
2537 +
2538 +void ltq_ebu_init(void)
2539 +{
2540 + if (ebu_region0_enable) {
2541 + /*
2542 + * Map EBU region 0 to range 0x10000000-0x13ffffff and enable
2543 + * region control. This supports up to 32 MiB NOR flash in
2544 + * bank 0.
2545 + */
2546 + ltq_writel(&ltq_ebu_regs->addr_sel_0, LTQ_EBU_REGION0_BASE |
2547 + EBU_ADDRSEL_MASK(1) | EBU_ADDRSEL_REGEN);
2548 +
2549 + ltq_writel(&ltq_ebu_regs->con_0, EBU_CON_AGEN_DEMUX |
2550 + EBU_CON_WAIT_DIS | EBU_CON_PW_16BIT |
2551 + EBU_CON_ALEC(3) | EBU_CON_BCGEN_INTEL |
2552 + EBU_CON_WAITWRC(7) | EBU_CON_WAITRDC(3) |
2553 + EBU_CON_HOLDC(3) | EBU_CON_RECOVC(3) |
2554 + EBU_CON_CMULT_16);
2555 + } else
2556 + ltq_clrbits(&ltq_ebu_regs->addr_sel_0, EBU_ADDRSEL_REGEN);
2557 +
2558 + if (ebu_region1_enable) {
2559 + /*
2560 + * Map EBU region 1 to range 0x14000000-0x13ffffff and enable
2561 + * region control. This supports NAND flash in bank 1.
2562 + */
2563 + ltq_writel(&ltq_ebu_regs->addr_sel_1, LTQ_EBU_REGION1_BASE |
2564 + EBU_ADDRSEL_MASK(3) | EBU_ADDRSEL_REGEN);
2565 +
2566 + ltq_writel(&ltq_ebu_regs->con_1, EBU_CON_AGEN_DEMUX |
2567 + EBU_CON_SETUP | EBU_CON_WAIT_DIS | EBU_CON_PW_8BIT |
2568 + EBU_CON_ALEC(3) | EBU_CON_BCGEN_INTEL |
2569 + EBU_CON_WAITWRC(2) | EBU_CON_WAITRDC(2) |
2570 + EBU_CON_HOLDC(1) | EBU_CON_RECOVC(1) |
2571 + EBU_CON_CMULT_4);
2572 + } else
2573 + ltq_clrbits(&ltq_ebu_regs->addr_sel_1, EBU_ADDRSEL_REGEN);
2574 +}
2575 +
2576 +void *flash_swap_addr(unsigned long addr)
2577 +{
2578 + return (void *)(addr ^ 2);
2579 +}
2580 diff --git a/arch/mips/cpu/mips32/vrx200/fw_phy11g_a1x.blob b/arch/mips/cpu/mips32/vrx200/fw_phy11g_a1x.blob
2581 new file mode 100644
2582 index 0000000..cdf3d30
2583 Binary files /dev/null and b/arch/mips/cpu/mips32/vrx200/fw_phy11g_a1x.blob differ
2584 diff --git a/arch/mips/cpu/mips32/vrx200/fw_phy11g_a2x.blob b/arch/mips/cpu/mips32/vrx200/fw_phy11g_a2x.blob
2585 new file mode 100644
2586 index 0000000..1559081
2587 Binary files /dev/null and b/arch/mips/cpu/mips32/vrx200/fw_phy11g_a2x.blob differ
2588 diff --git a/arch/mips/cpu/mips32/vrx200/fw_phy22f_a1x.blob b/arch/mips/cpu/mips32/vrx200/fw_phy22f_a1x.blob
2589 new file mode 100644
2590 index 0000000..02b88a0
2591 Binary files /dev/null and b/arch/mips/cpu/mips32/vrx200/fw_phy22f_a1x.blob differ
2592 diff --git a/arch/mips/cpu/mips32/vrx200/fw_phy22f_a2x.blob b/arch/mips/cpu/mips32/vrx200/fw_phy22f_a2x.blob
2593 new file mode 100644
2594 index 0000000..eeab2ab
2595 Binary files /dev/null and b/arch/mips/cpu/mips32/vrx200/fw_phy22f_a2x.blob differ
2596 diff --git a/arch/mips/cpu/mips32/vrx200/gphy.c b/arch/mips/cpu/mips32/vrx200/gphy.c
2597 new file mode 100644
2598 index 0000000..269ca5d
2599 --- /dev/null
2600 +++ b/arch/mips/cpu/mips32/vrx200/gphy.c
2601 @@ -0,0 +1,58 @@
2602 +/*
2603 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
2604 + *
2605 + * SPDX-License-Identifier: GPL-2.0+
2606 + */
2607 +
2608 +#include <common.h>
2609 +#include <asm/lantiq/io.h>
2610 +#include <asm/arch/soc.h>
2611 +#include <asm/arch/gphy.h>
2612 +
2613 +static inline void ltq_gphy_copy(const void *fw_start, const void *fw_end,
2614 + ulong dst_addr)
2615 +{
2616 + const ulong fw_len = (ulong) fw_end - (ulong) fw_start;
2617 + const ulong addr = CKSEG1ADDR(dst_addr);
2618 +
2619 + debug("ltq_gphy_copy: addr %08lx, fw_start %p, fw_end %p\n",
2620 + addr, fw_start, fw_end);
2621 +
2622 + memcpy((void *) addr, fw_start, fw_len);
2623 +}
2624 +
2625 +void ltq_gphy_phy11g_a1x_load(ulong addr)
2626 +{
2627 + extern ulong __ltq_fw_phy11g_a1x_start;
2628 + extern ulong __ltq_fw_phy11g_a1x_end;
2629 +
2630 + ltq_gphy_copy(&__ltq_fw_phy11g_a1x_start, &__ltq_fw_phy11g_a1x_end,
2631 + addr);
2632 +}
2633 +
2634 +void ltq_gphy_phy11g_a2x_load(ulong addr)
2635 +{
2636 + extern ulong __ltq_fw_phy11g_a2x_start;
2637 + extern ulong __ltq_fw_phy11g_a2x_end;
2638 +
2639 + ltq_gphy_copy(&__ltq_fw_phy11g_a2x_start, &__ltq_fw_phy11g_a2x_end,
2640 + addr);
2641 +}
2642 +
2643 +void ltq_gphy_phy22f_a1x_load(ulong addr)
2644 +{
2645 + extern ulong __ltq_fw_phy22f_a1x_start;
2646 + extern ulong __ltq_fw_phy22f_a1x_end;
2647 +
2648 + ltq_gphy_copy(&__ltq_fw_phy22f_a1x_start, &__ltq_fw_phy22f_a1x_end,
2649 + addr);
2650 +}
2651 +
2652 +void ltq_gphy_phy22f_a2x_load(ulong addr)
2653 +{
2654 + extern ulong __ltq_fw_phy22f_a2x_start;
2655 + extern ulong __ltq_fw_phy22f_a2x_end;
2656 +
2657 + ltq_gphy_copy(&__ltq_fw_phy22f_a2x_start, &__ltq_fw_phy22f_a2x_end,
2658 + addr);
2659 +}
2660 diff --git a/arch/mips/cpu/mips32/vrx200/gphy_fw.S b/arch/mips/cpu/mips32/vrx200/gphy_fw.S
2661 new file mode 100644
2662 index 0000000..3a0417a
2663 --- /dev/null
2664 +++ b/arch/mips/cpu/mips32/vrx200/gphy_fw.S
2665 @@ -0,0 +1,27 @@
2666 +/*
2667 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
2668 + *
2669 + * SPDX-License-Identifier: GPL-2.0+
2670 + */
2671 +
2672 +#include <asm/asm.h>
2673 +
2674 + .section .rodata.__ltq_fw_phy11g_a1x
2675 +EXPORT(__ltq_fw_phy11g_a1x_start)
2676 + .incbin "fw_phy11g_a1x.blob"
2677 +EXPORT(__ltq_fw_phy11g_a1x_end)
2678 +
2679 + .section .rodata.__ltq_fw_phy11g_a2x
2680 +EXPORT(__ltq_fw_phy11g_a2x_start)
2681 + .incbin "fw_phy11g_a2x.blob"
2682 +EXPORT(__ltq_fw_phy11g_a2x_end)
2683 +
2684 + .section .rodata.__ltq_fw_phy22f_a1x
2685 +EXPORT(__ltq_fw_phy22f_a1x_start)
2686 + .incbin "fw_phy22f_a1x.blob"
2687 +EXPORT(__ltq_fw_phy22f_a1x_end)
2688 +
2689 + .section .rodata.__ltq_fw_phy22f_a2x
2690 +EXPORT(__ltq_fw_phy22f_a2x_start)
2691 + .incbin "fw_phy22f_a2x.blob"
2692 +EXPORT(__ltq_fw_phy22f_a2x_end)
2693 diff --git a/arch/mips/cpu/mips32/vrx200/mem.c b/arch/mips/cpu/mips32/vrx200/mem.c
2694 new file mode 100644
2695 index 0000000..c3e14ab
2696 --- /dev/null
2697 +++ b/arch/mips/cpu/mips32/vrx200/mem.c
2698 @@ -0,0 +1,57 @@
2699 +/*
2700 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
2701 + *
2702 + * SPDX-License-Identifier: GPL-2.0+
2703 + */
2704 +
2705 +#include <common.h>
2706 +#include <asm/arch/soc.h>
2707 +#include <asm/lantiq/io.h>
2708 +
2709 +#define LTQ_CCR03_EIGHT_BANK_MODE (1 << 0)
2710 +#define LTQ_CCR08_CS_MAP_SHIFT 24
2711 +#define LTQ_CCR08_CS_MAP_MASK (0x3 << LTQ_CCR08_CS_MAP_SHIFT)
2712 +#define LTQ_CCR11_COLUMN_SIZE_SHIFT 24
2713 +#define LTQ_CCR11_COLUMN_SIZE_MASK (0x7 << LTQ_CCR11_COLUMN_SIZE_SHIFT)
2714 +#define LTQ_CCR11_ADDR_PINS_MASK 0x7
2715 +#define LTQ_CCR15_MAX_COL_REG_SHIFT 24
2716 +#define LTQ_CCR15_MAX_COL_REG_MASK (0xF << LTQ_CCR15_MAX_COL_REG_SHIFT)
2717 +#define LTQ_CCR16_MAX_ROW_REG_MASK 0xF
2718 +
2719 +static void *ltq_mc_ddr_base = (void *) CKSEG1ADDR(LTQ_MC_DDR_BASE);
2720 +
2721 +static inline u32 ltq_mc_ccr_read(u32 index)
2722 +{
2723 + return ltq_readl(ltq_mc_ddr_base + LTQ_MC_DDR_CCR_OFFSET(index));
2724 +}
2725 +
2726 +phys_size_t initdram(int board_type)
2727 +{
2728 + u32 max_col_reg, max_row_reg, column_size, addr_pins;
2729 + u32 banks, cs_map;
2730 + phys_size_t size;
2731 +
2732 + banks = (ltq_mc_ccr_read(3) & LTQ_CCR03_EIGHT_BANK_MODE) ? 8 : 4;
2733 +
2734 + cs_map = (ltq_mc_ccr_read(8) & LTQ_CCR08_CS_MAP_MASK) >>
2735 + LTQ_CCR08_CS_MAP_SHIFT;
2736 +
2737 + column_size = (ltq_mc_ccr_read(11) & LTQ_CCR11_COLUMN_SIZE_MASK) >>
2738 + LTQ_CCR11_COLUMN_SIZE_SHIFT;
2739 +
2740 + addr_pins = ltq_mc_ccr_read(11) & LTQ_CCR11_ADDR_PINS_MASK;
2741 +
2742 + max_col_reg = (ltq_mc_ccr_read(15) & LTQ_CCR15_MAX_COL_REG_MASK) >>
2743 + LTQ_CCR15_MAX_COL_REG_SHIFT;
2744 +
2745 + max_row_reg = ltq_mc_ccr_read(16) & LTQ_CCR16_MAX_ROW_REG_MASK;
2746 +
2747 + /*
2748 + * size (bytes) = 2 ^ rowsize * 2 ^ colsize * banks * chipselects
2749 + * * datawidth (bytes)
2750 + */
2751 + size = (2 << (max_col_reg - column_size - 1)) *
2752 + (2 << (max_row_reg - addr_pins - 1)) * banks * cs_map * 2;
2753 +
2754 + return size;
2755 +}
2756 diff --git a/arch/mips/cpu/mips32/vrx200/mem_init.S b/arch/mips/cpu/mips32/vrx200/mem_init.S
2757 new file mode 100644
2758 index 0000000..a296845
2759 --- /dev/null
2760 +++ b/arch/mips/cpu/mips32/vrx200/mem_init.S
2761 @@ -0,0 +1,233 @@
2762 +/*
2763 + * Copyright (C) 2010 Lantiq Deutschland GmbH
2764 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
2765 + *
2766 + * SPDX-License-Identifier: GPL-2.0+
2767 + */
2768 +
2769 +#include <config.h>
2770 +#include <asm/asm.h>
2771 +#include <asm/regdef.h>
2772 +#include <asm/addrspace.h>
2773 +#include <asm/arch/soc.h>
2774 +
2775 +/* Must be configured in BOARDDIR */
2776 +#include <ddr_settings.h>
2777 +
2778 +#define LTQ_MC_DDR_START (1 << 8)
2779 +#define LTQ_MC_DDR_DLL_LOCK_IND 1
2780 +
2781 +#define CCS_ALWAYS_LAST 0x0430
2782 +#define CCS_AHBM_CR_BURST_EN (1 << 2)
2783 +#define CCS_FPIM_CR_BURST_EN (1 << 1)
2784 +
2785 +#define CCR03_EIGHT_BANK_MODE (1 << 0)
2786 +
2787 + /* Store given value in MC DDR CCRx register */
2788 + .macro ccr_sw num, val
2789 + li t1, \val
2790 + sw t1, LTQ_MC_DDR_CCR_OFFSET(\num)(t0)
2791 + .endm
2792 +
2793 +LEAF(ltq_mem_init)
2794 + /* Load MC DDR module base */
2795 + li t0, (LTQ_MC_DDR_BASE | KSEG1)
2796 +
2797 + /* Put memory controller in inactive mode */
2798 + sw zero, LTQ_MC_DDR_CCR_OFFSET(7)(t0)
2799 +
2800 + /* Init MC DDR CCR registers with values from ddr_settings.h */
2801 + ccr_sw 0, MC_CCR00_VALUE
2802 + ccr_sw 1, MC_CCR01_VALUE
2803 + ccr_sw 2, MC_CCR02_VALUE
2804 + ccr_sw 3, MC_CCR03_VALUE
2805 + ccr_sw 4, MC_CCR04_VALUE
2806 + ccr_sw 5, MC_CCR05_VALUE
2807 + ccr_sw 6, MC_CCR06_VALUE
2808 + ccr_sw 7, MC_CCR07_VALUE
2809 + ccr_sw 8, MC_CCR08_VALUE
2810 + ccr_sw 9, MC_CCR09_VALUE
2811 +
2812 + ccr_sw 10, MC_CCR10_VALUE
2813 + ccr_sw 11, MC_CCR11_VALUE
2814 + ccr_sw 12, MC_CCR12_VALUE
2815 + ccr_sw 13, MC_CCR13_VALUE
2816 + ccr_sw 14, MC_CCR14_VALUE
2817 + ccr_sw 15, MC_CCR15_VALUE
2818 + ccr_sw 16, MC_CCR16_VALUE
2819 + ccr_sw 17, MC_CCR17_VALUE
2820 + ccr_sw 18, MC_CCR18_VALUE
2821 + ccr_sw 19, MC_CCR19_VALUE
2822 +
2823 + ccr_sw 20, MC_CCR20_VALUE
2824 + ccr_sw 21, MC_CCR21_VALUE
2825 + ccr_sw 22, MC_CCR22_VALUE
2826 + ccr_sw 23, MC_CCR23_VALUE
2827 + ccr_sw 24, MC_CCR24_VALUE
2828 + ccr_sw 25, MC_CCR25_VALUE
2829 + ccr_sw 26, MC_CCR26_VALUE
2830 + ccr_sw 27, MC_CCR27_VALUE
2831 + ccr_sw 28, MC_CCR28_VALUE
2832 + ccr_sw 29, MC_CCR29_VALUE
2833 +
2834 + ccr_sw 30, MC_CCR30_VALUE
2835 + ccr_sw 31, MC_CCR31_VALUE
2836 + ccr_sw 32, MC_CCR32_VALUE
2837 + ccr_sw 33, MC_CCR33_VALUE
2838 + ccr_sw 34, MC_CCR34_VALUE
2839 + ccr_sw 35, MC_CCR35_VALUE
2840 + ccr_sw 36, MC_CCR36_VALUE
2841 + ccr_sw 37, MC_CCR37_VALUE
2842 + ccr_sw 38, MC_CCR38_VALUE
2843 + ccr_sw 39, MC_CCR39_VALUE
2844 +
2845 + ccr_sw 40, MC_CCR40_VALUE
2846 + ccr_sw 41, MC_CCR41_VALUE
2847 + ccr_sw 42, MC_CCR42_VALUE
2848 + ccr_sw 43, MC_CCR43_VALUE
2849 + ccr_sw 44, MC_CCR44_VALUE
2850 + ccr_sw 45, MC_CCR45_VALUE
2851 + ccr_sw 46, MC_CCR46_VALUE
2852 +
2853 + ccr_sw 52, MC_CCR52_VALUE
2854 + ccr_sw 53, MC_CCR53_VALUE
2855 + ccr_sw 54, MC_CCR54_VALUE
2856 + ccr_sw 55, MC_CCR55_VALUE
2857 + ccr_sw 56, MC_CCR56_VALUE
2858 + ccr_sw 57, MC_CCR57_VALUE
2859 + ccr_sw 58, MC_CCR58_VALUE
2860 + ccr_sw 59, MC_CCR59_VALUE
2861 +
2862 + ccr_sw 60, MC_CCR60_VALUE
2863 + ccr_sw 61, MC_CCR61_VALUE
2864 +
2865 + /* Disable bursts between FPI Master bus and XBAR bus */
2866 + li t4, (LTQ_MC_GLOBAL_BASE | KSEG1)
2867 + li t5, CCS_AHBM_CR_BURST_EN
2868 + sw t5, CCS_ALWAYS_LAST(t4)
2869 +
2870 + /* Init abort condition for DRAM probe */
2871 + move t4, zero
2872 +
2873 + /*
2874 + * Put memory controller in active mode and start initialitation
2875 + * sequence for connected DDR-SDRAM device
2876 + */
2877 +mc_start:
2878 + lw t1, LTQ_MC_DDR_CCR_OFFSET(7)(t0)
2879 + li t2, LTQ_MC_DDR_START
2880 + or t1, t1, t2
2881 + sw t1, LTQ_MC_DDR_CCR_OFFSET(7)(t0)
2882 +
2883 + /*
2884 + * Wait until DLL has locked and core is ready for data transfers.
2885 + * DLL lock indication is in register CCR47 and CCR48
2886 + */
2887 +wait_ready:
2888 + li t1, LTQ_MC_DDR_DLL_LOCK_IND
2889 + lw t2, LTQ_MC_DDR_CCR_OFFSET(47)(t0)
2890 + and t2, t2, t1
2891 + bne t1, t2, wait_ready
2892 +
2893 + lw t2, LTQ_MC_DDR_CCR_OFFSET(48)(t0)
2894 + and t2, t2, t1
2895 + bne t1, t2, wait_ready
2896 +
2897 +#ifdef CONFIG_SYS_DRAM_PROBE
2898 +dram_probe:
2899 + /* Initialization is finished after the second MC start */
2900 + bnez t4, mc_finished
2901 +
2902 + /*
2903 + * Preload register values for CCR03 and CCR11. Initial settings
2904 + * are 8-bank mode enabled, 14 use address row bits, 10 used
2905 + * column address bits.
2906 + */
2907 + li t1, CONFIG_SYS_SDRAM_BASE_UC
2908 + li t5, MC_CCR03_VALUE
2909 + li t6, MC_CCR11_VALUE
2910 + addi t4, t4, 1
2911 +
2912 + /*
2913 + * Store test values to DRAM at offsets 0 and 2^13 (bit 2 in bank select
2914 + * address BA[3]) and read back the value at offset 0. If the resulting
2915 + * value is equal to 1 we can skip to the next test. Otherwise
2916 + * the 8-bank mode does not work with the current DRAM device,
2917 + * thus we need to clear the according bit in register CCR03.
2918 + */
2919 + li t2, 1
2920 + sw t2, 0x0(t1)
2921 + li t3, (1 << 13)
2922 + add t3, t3, t1
2923 + sw zero, 0(t3)
2924 + lw t3, 0(t1)
2925 + bnez t3, row_col_test
2926 +
2927 + /* Clear CCR03.EIGHT_BANK_MODE */
2928 + li t3, ~CCR03_EIGHT_BANK_MODE
2929 + and t5, t5, t3
2930 +
2931 +row_col_test:
2932 + /*
2933 + * Store test values to DRAM at offsets 0, 2^27 (bit 13 of row address
2934 + * RA[14]) and 2^26 (bit 12 of RA[14]). The chosen test values
2935 + * represent the difference between max. row address bits (14) and used
2936 + * row address bits. Then the read back value at offset 0 indicates
2937 + * the useable row address bits with the current DRAM device. This
2938 + * value must be set in the CCR11 register.
2939 + */
2940 + sw zero, 0(t1)
2941 +
2942 + li t2, 1
2943 + li t3, (1 << 27)
2944 + add t3, t3, t1
2945 + sw t2, 0(t3)
2946 +
2947 + li t2, 2
2948 + li t3, (1 << 26)
2949 + add t3, t3, t1
2950 + sw t2, 0(t3)
2951 +
2952 + /* Update CCR11.ADDR_PINS */
2953 + lw t3, 0(t1)
2954 + add t6, t6, t3
2955 +
2956 + /*
2957 + * Store test values to DRAM at offsets 0, 2^10 (bit 9 of column address
2958 + * CA[10]) and 2^9 (bit 8 of CA[10]). The chosen test values represent
2959 + * the difference between max. column address bits (12) and used
2960 + * column address bits. Then the read back value at offset 0 indicates
2961 + * the useable column address bits with the current DRAM device. This
2962 + * value must be set in the CCR11 register.
2963 + */
2964 + sw zero, 0(t1)
2965 +
2966 + li t2, 1
2967 + li t3, (1 << 10)
2968 + add t3, t3, t1
2969 + sw t2, 0(t3)
2970 +
2971 + li t2, 2
2972 + li t3, (1 << 9)
2973 + add t3, t3, t1
2974 + sw t2, 0(t3)
2975 +
2976 + /* Update CCR11.COLUMN_SIZE */
2977 + lw t3, 0(t1)
2978 + sll t3, t3, 24
2979 + add t6, t6, t3
2980 +
2981 + /* Put memory controller in inactive mode */
2982 + sw zero, LTQ_MC_DDR_CCR_OFFSET(7)(t0)
2983 +
2984 + /* Update CCR03 and CCR11 and restart memory controller initialiation */
2985 + sw t5, LTQ_MC_DDR_CCR_OFFSET(3)(t0)
2986 + sw t6, LTQ_MC_DDR_CCR_OFFSET(11)(t0)
2987 + b mc_start
2988 +
2989 +mc_finished:
2990 +#endif /* CONFIG_SYS_DRAM_PROBE */
2991 +
2992 + jr ra
2993 +
2994 + END(ltq_mem_init)
2995 diff --git a/arch/mips/cpu/mips32/vrx200/pmu.c b/arch/mips/cpu/mips32/vrx200/pmu.c
2996 new file mode 100644
2997 index 0000000..a144473
2998 --- /dev/null
2999 +++ b/arch/mips/cpu/mips32/vrx200/pmu.c
3000 @@ -0,0 +1,130 @@
3001 +/*
3002 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
3003 + *
3004 + * SPDX-License-Identifier: GPL-2.0+
3005 + */
3006 +
3007 +#include <common.h>
3008 +#include <asm/lantiq/io.h>
3009 +#include <asm/lantiq/pm.h>
3010 +#include <asm/arch/soc.h>
3011 +
3012 +#define LTQ_PMU_PWDCR_RESERVED ((1 << 13) | (1 << 4))
3013 +
3014 +#define LTQ_PMU_PWDCR_PCIELOC_EN (1 << 31)
3015 +#define LTQ_PMU_PWDCR_GPHY (1 << 30)
3016 +#define LTQ_PMU_PWDCR_PPE_TOP (1 << 29)
3017 +#define LTQ_PMU_PWDCR_SWITCH (1 << 28)
3018 +#define LTQ_PMU_PWDCR_USB1 (1 << 27)
3019 +#define LTQ_PMU_PWDCR_USB1_PHY (1 << 26)
3020 +#define LTQ_PMU_PWDCR_TDM (1 << 25)
3021 +#define LTQ_PMU_PWDCR_PPE_DPLUS (1 << 24)
3022 +#define LTQ_PMU_PWDCR_PPE_DPLUM (1 << 23)
3023 +#define LTQ_PMU_PWDCR_PPE_EMA (1 << 22)
3024 +#define LTQ_PMU_PWDCR_PPE_TC (1 << 21)
3025 +#define LTQ_PMU_PWDCR_DEU (1 << 20)
3026 +#define LTQ_PMU_PWDCR_PPE_SLL01 (1 << 19)
3027 +#define LTQ_PMU_PWDCR_PPE_QSB (1 << 18)
3028 +#define LTQ_PMU_PWDCR_UART1 (1 << 17)
3029 +#define LTQ_PMU_PWDCR_SDIO (1 << 16)
3030 +#define LTQ_PMU_PWDCR_AHBM (1 << 15)
3031 +#define LTQ_PMU_PWDCR_FPIM (1 << 14)
3032 +#define LTQ_PMU_PWDCR_GPTC (1 << 12)
3033 +#define LTQ_PMU_PWDCR_LEDC (1 << 11)
3034 +#define LTQ_PMU_PWDCR_EBU (1 << 10)
3035 +#define LTQ_PMU_PWDCR_DSL (1 << 9)
3036 +#define LTQ_PMU_PWDCR_SPI (1 << 8)
3037 +#define LTQ_PMU_PWDCR_USIF (1 << 7)
3038 +#define LTQ_PMU_PWDCR_USB0 (1 << 6)
3039 +#define LTQ_PMU_PWDCR_DMA (1 << 5)
3040 +#define LTQ_PMU_PWDCR_DFEV1 (1 << 3)
3041 +#define LTQ_PMU_PWDCR_DFEV0 (1 << 2)
3042 +#define LTQ_PMU_PWDCR_FPIS (1 << 1)
3043 +#define LTQ_PMU_PWDCR_USB0_PHY (1 << 0)
3044 +
3045 +struct ltq_pmu_regs {
3046 + u32 rsvd0[7];
3047 + u32 pwdcr; /* Power down control */
3048 + u32 sr; /* Power down status */
3049 + u32 pwdcr1; /* Power down control 1 */
3050 + u32 sr1; /* Power down status 1 */
3051 +};
3052 +
3053 +static struct ltq_pmu_regs *ltq_pmu_regs =
3054 + (struct ltq_pmu_regs *) CKSEG1ADDR(LTQ_PMU_BASE);
3055 +
3056 +u32 ltq_pm_map(enum ltq_pm_modules module)
3057 +{
3058 + u32 val;
3059 +
3060 + switch (module) {
3061 + case LTQ_PM_CORE:
3062 + val = LTQ_PMU_PWDCR_UART1 | LTQ_PMU_PWDCR_FPIM |
3063 + LTQ_PMU_PWDCR_LEDC | LTQ_PMU_PWDCR_EBU;
3064 + break;
3065 + case LTQ_PM_DMA:
3066 + val = LTQ_PMU_PWDCR_DMA;
3067 + break;
3068 + case LTQ_PM_ETH:
3069 + val = LTQ_PMU_PWDCR_GPHY | LTQ_PMU_PWDCR_PPE_TOP |
3070 + LTQ_PMU_PWDCR_SWITCH | LTQ_PMU_PWDCR_PPE_DPLUS |
3071 + LTQ_PMU_PWDCR_PPE_DPLUM | LTQ_PMU_PWDCR_PPE_EMA |
3072 + LTQ_PMU_PWDCR_PPE_TC | LTQ_PMU_PWDCR_PPE_SLL01 |
3073 + LTQ_PMU_PWDCR_PPE_QSB;
3074 + break;
3075 + case LTQ_PM_SPI:
3076 + val = LTQ_PMU_PWDCR_SPI;
3077 + break;
3078 + default:
3079 + val = 0;
3080 + break;
3081 + }
3082 +
3083 + return val;
3084 +}
3085 +
3086 +int ltq_pm_enable(enum ltq_pm_modules module)
3087 +{
3088 + const unsigned long timeout = 1000;
3089 + unsigned long timebase;
3090 + u32 sr, val;
3091 +
3092 + val = ltq_pm_map(module);
3093 + if (unlikely(!val))
3094 + return 1;
3095 +
3096 + ltq_clrbits(&ltq_pmu_regs->pwdcr, val);
3097 +
3098 + timebase = get_timer(0);
3099 +
3100 + do {
3101 + sr = ltq_readl(&ltq_pmu_regs->sr);
3102 + if (~sr & val)
3103 + return 0;
3104 + } while (get_timer(timebase) < timeout);
3105 +
3106 + return 1;
3107 +}
3108 +
3109 +int ltq_pm_disable(enum ltq_pm_modules module)
3110 +{
3111 + u32 val;
3112 +
3113 + val = ltq_pm_map(module);
3114 + if (unlikely(!val))
3115 + return 1;
3116 +
3117 + ltq_setbits(&ltq_pmu_regs->pwdcr, val);
3118 +
3119 + return 0;
3120 +}
3121 +
3122 +void ltq_pmu_init(void)
3123 +{
3124 + u32 set, clr;
3125 +
3126 + clr = ltq_pm_map(LTQ_PM_CORE);
3127 + set = ~(LTQ_PMU_PWDCR_RESERVED | clr);
3128 +
3129 + ltq_clrsetbits(&ltq_pmu_regs->pwdcr, clr, set);
3130 +}
3131 diff --git a/arch/mips/cpu/mips32/vrx200/rcu.c b/arch/mips/cpu/mips32/vrx200/rcu.c
3132 new file mode 100644
3133 index 0000000..763f287
3134 --- /dev/null
3135 +++ b/arch/mips/cpu/mips32/vrx200/rcu.c
3136 @@ -0,0 +1,194 @@
3137 +/*
3138 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
3139 + *
3140 + * SPDX-License-Identifier: GPL-2.0+
3141 + */
3142 +
3143 +#include <common.h>
3144 +#include <asm/lantiq/io.h>
3145 +#include <asm/lantiq/reset.h>
3146 +#include <asm/lantiq/cpu.h>
3147 +#include <asm/arch/soc.h>
3148 +
3149 +#define LTQ_RCU_RD_GPHY0 (1 << 31) /* GPHY0 */
3150 +#define LTQ_RCU_RD_SRST (1 << 30) /* Global SW Reset */
3151 +#define LTQ_RCU_RD_GPHY1 (1 << 29) /* GPHY1 */
3152 +#define LTQ_RCU_RD_ENMIP2 (1 << 28) /* Enable NMI of PLL2 */
3153 +#define LTQ_RCU_RD_REG25_PD (1 << 26) /* Power down 2.5V regulator */
3154 +#define LTQ_RCU_RD_ENDINIT (1 << 25) /* FPI slave bus access */
3155 +#define LTQ_RCU_RD_PPE_ATM_TC (1 << 23) /* PPE ATM TC */
3156 +#define LTQ_RCU_RD_PCIE (1 << 22) /* PCI-E core */
3157 +#define LTQ_RCU_RD_ETHSW (1 << 21) /* Ethernet switch */
3158 +#define LTQ_RCU_RD_DSP_DEN (1 << 20) /* Enable DSP JTAG */
3159 +#define LTQ_RCU_RD_TDM (1 << 19) /* TDM module interface */
3160 +#define LTQ_RCU_RD_ENMIP1 (1 << 18) /* Enable NMI of PLL1 */
3161 +#define LTQ_RCU_RD_SWBCK (1 << 17) /* Switch backward compat */
3162 +#define LTQ_RCU_RD_HSNAND (1 << 16) /* HSNAND controller */
3163 +#define LTQ_RCU_RD_ENMIP0 (1 << 15) /* Enable NMI of PLL0 */
3164 +#define LTQ_RCU_RD_MC (1 << 14) /* Memory Controller */
3165 +#define LTQ_RCU_RD_PCI (1 << 13) /* PCI core */
3166 +#define LTQ_RCU_RD_PCIE_PHY (1 << 12) /* PCI-E Phy */
3167 +#define LTQ_RCU_RD_DFE_CORE (1 << 11) /* DFE core */
3168 +#define LTQ_RCU_RD_SDIO (1 << 10) /* SDIO core */
3169 +#define LTQ_RCU_RD_DMA (1 << 9) /* DMA core */
3170 +#define LTQ_RCU_RD_PPE (1 << 8) /* PPE core */
3171 +#define LTQ_RCU_RD_DFE (1 << 7) /* DFE core */
3172 +#define LTQ_RCU_RD_AHB (1 << 6) /* AHB bus */
3173 +#define LTQ_RCU_RD_HRST_CFG (1 << 5) /* HW reset configuration */
3174 +#define LTQ_RCU_RD_USB (1 << 4) /* USB and Phy core */
3175 +#define LTQ_RCU_RD_PPE_DSP (1 << 3) /* PPE DSP interface */
3176 +#define LTQ_RCU_RD_FPI (1 << 2) /* FPI bus */
3177 +#define LTQ_RCU_RD_CPU (1 << 1) /* CPU subsystem */
3178 +#define LTQ_RCU_RD_HRST (1 << 0) /* HW reset via HRST pin */
3179 +
3180 +#define LTQ_RCU_STAT_BOOT_SHIFT 17
3181 +#define LTQ_RCU_STAT_BOOT_MASK (0xF << LTQ_RCU_STAT_BOOT_SHIFT)
3182 +#define LTQ_RCU_STAT_BOOT_H (1 << 12)
3183 +
3184 +#define LTQ_RCU_GP_STRAP_CLOCKSOURCE (1 << 15)
3185 +
3186 +struct ltq_rcu_regs {
3187 + u32 rsvd0[4];
3188 + u32 req; /* Reset request */
3189 + u32 stat; /* Reset status */
3190 + u32 usb0_cfg; /* USB0 configure */
3191 + u32 gp_strap; /* GPIO strapping */
3192 + u32 gfs_add0; /* GPHY0 firmware base addr */
3193 + u32 stat2; /* SLIC and USB reset status */
3194 + u32 pci_rdy; /* PCI boot ready */
3195 + u32 ppe_conf; /* PPE ethernet config */
3196 + u32 pcie_phy_con; /* PCIE PHY config/status */
3197 + u32 usb1_cfg; /* USB1 configure */
3198 + u32 usb_ana_cfg1a; /* USB analog config 1a */
3199 + u32 usb_ana_cfg1b; /* USB analog config 1b */
3200 + u32 rsvd1;
3201 + u32 gf_mdio_add; /* GPHY0/1 MDIO address */
3202 + u32 req2; /* SLIC and USB reset request */
3203 + u32 ahb_endian; /* AHB bus endianess */
3204 + u32 rsvd2[4];
3205 + u32 gcc; /* General CPU config */
3206 + u32 rsvd3;
3207 + u32 gfs_add1; /* GPHY1 firmware base addr */
3208 +};
3209 +
3210 +static struct ltq_rcu_regs *ltq_rcu_regs =
3211 + (struct ltq_rcu_regs *) CKSEG1ADDR(LTQ_RCU_BASE);
3212 +
3213 +u32 ltq_reset_map(enum ltq_reset_modules module)
3214 +{
3215 + u32 val;
3216 +
3217 + switch (module) {
3218 + case LTQ_RESET_CORE:
3219 + case LTQ_RESET_SOFT:
3220 + val = LTQ_RCU_RD_SRST | LTQ_RCU_RD_CPU | LTQ_RCU_RD_ENMIP2 |
3221 + LTQ_RCU_RD_GPHY1 | LTQ_RCU_RD_GPHY0;
3222 + break;
3223 + case LTQ_RESET_DMA:
3224 + val = LTQ_RCU_RD_DMA;
3225 + break;
3226 + case LTQ_RESET_ETH:
3227 + val = LTQ_RCU_RD_PPE | LTQ_RCU_RD_ETHSW;
3228 + break;
3229 + case LTQ_RESET_PHY:
3230 + val = LTQ_RCU_RD_GPHY1 | LTQ_RCU_RD_GPHY0;
3231 + break;
3232 + case LTQ_RESET_HARD:
3233 + val = LTQ_RCU_RD_HRST;
3234 + break;
3235 + default:
3236 + val = 0;
3237 + break;
3238 + }
3239 +
3240 + return val;
3241 +}
3242 +
3243 +int ltq_reset_activate(enum ltq_reset_modules module)
3244 +{
3245 + u32 val;
3246 +
3247 + val = ltq_reset_map(module);
3248 + if (unlikely(!val))
3249 + return 1;
3250 +
3251 + ltq_setbits(&ltq_rcu_regs->req, val);
3252 +
3253 + return 0;
3254 +}
3255 +
3256 +int ltq_reset_deactivate(enum ltq_reset_modules module)