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
6 Signed-off-by: Luka Perkov <luka@openwrt.org>
7 Signed-off-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
17 +/u-boot.ltq.lzma.norspl
18 +/u-boot.ltq.lzo.norspl
27 @@ -435,6 +435,12 @@ $(obj)u-boot.bin: $(obj)u-boot
28 $(OBJCOPY) ${OBJCFLAGS} -O binary $< $@
31 +$(obj)u-boot.bin.lzma: $(obj)u-boot.bin
32 + cat $< | lzma -9 -f - > $@
34 +$(obj)u-boot.bin.lzo: $(obj)u-boot.bin
35 + cat $< | lzop -9 -f - > $@
37 $(obj)u-boot.ldr: $(obj)u-boot
39 $(LDR) -T $(CONFIG_BFIN_CPU) -c $@ $< $(LDR_FLAGS)
40 @@ -454,13 +460,23 @@ ifndef CONFIG_SYS_UBOOT_START
41 CONFIG_SYS_UBOOT_START := 0
44 -$(obj)u-boot.img: $(obj)u-boot.bin
45 - $(obj)tools/mkimage -A $(ARCH) -T firmware -C none \
46 +define GEN_UBOOT_IMAGE
47 + $(obj)tools/mkimage -A $(ARCH) -T firmware -C $(1) \
48 -O u-boot -a $(CONFIG_SYS_TEXT_BASE) \
49 -e $(CONFIG_SYS_UBOOT_START) \
50 -n $(shell sed -n -e 's/.*U_BOOT_VERSION//p' $(VERSION_FILE) | \
51 sed -e 's/"[ ]*$$/ for $(BOARD) board"/') \
55 +$(obj)u-boot.img: $(obj)u-boot.bin
56 + $(call GEN_UBOOT_IMAGE,none)
58 +$(obj)u-boot.lzma.img: $(obj)u-boot.bin.lzma
59 + $(call GEN_UBOOT_IMAGE,lzma)
61 +$(obj)u-boot.lzo.img: $(obj)u-boot.bin.lzo
62 + $(call GEN_UBOOT_IMAGE,lzo)
64 $(obj)u-boot.imx: $(obj)u-boot.bin depend
65 $(MAKE) -C $(SRCTREE)/arch/arm/imx-common $(OBJTREE)/u-boot.imx
66 @@ -571,6 +587,27 @@ $(obj)u-boot-img-spl-at-end.bin: $(obj)s
67 conv=notrunc 2>/dev/null
68 cat $(obj)u-boot-pad.img $(obj)spl/u-boot-spl.bin > $@
70 +$(obj)u-boot.ltq.sfspl: $(obj)u-boot.img $(obj)spl/u-boot-spl.bin
71 + $(obj)tools/ltq-boot-image -t sfspl -e $(CONFIG_SPL_TEXT_BASE) \
72 + -s $(obj)spl/u-boot-spl.bin -u $< -o $@
74 +$(obj)u-boot.ltq.lzo.sfspl: $(obj)u-boot.lzo.img $(obj)spl/u-boot-spl.bin
75 + $(obj)tools/ltq-boot-image -t sfspl -e $(CONFIG_SPL_TEXT_BASE) \
76 + -s $(obj)spl/u-boot-spl.bin -u $< -o $@
78 +$(obj)u-boot.ltq.lzma.sfspl: $(obj)u-boot.lzma.img $(obj)spl/u-boot-spl.bin
79 + $(obj)tools/ltq-boot-image -t sfspl -e $(CONFIG_SPL_TEXT_BASE) \
80 + -s $(obj)spl/u-boot-spl.bin -u $< -o $@
82 +$(obj)u-boot.ltq.norspl: $(obj)u-boot.img $(obj)spl/u-boot-spl.bin
83 + cat $(obj)spl/u-boot-spl.bin $< > $@
85 +$(obj)u-boot.ltq.lzo.norspl: $(obj)u-boot.lzo.img $(obj)spl/u-boot-spl.bin
86 + cat $(obj)spl/u-boot-spl.bin $< > $@
88 +$(obj)u-boot.ltq.lzma.norspl: $(obj)u-boot.lzma.img $(obj)spl/u-boot-spl.bin
89 + cat $(obj)spl/u-boot-spl.bin $< > $@
91 ifeq ($(CONFIG_SANDBOX),y)
93 cd $(LNDIR) && $(CC) $(SYMS) -T $(obj)u-boot.lds \
96 @@ -468,6 +468,11 @@ The following options need to be configu
98 CONF_CM_CACHABLE_ACCELERATED
100 + CONFIG_SYS_MIPS_CACHE_EXT_INIT
102 + Enable this to use extended cache initialization for recent
105 CONFIG_SYS_XWAY_EBU_BOOTCFG
107 Special option for Lantiq XWAY SoCs for booting from NOR flash.
108 --- a/arch/mips/config.mk
109 +++ b/arch/mips/config.mk
110 @@ -45,9 +45,13 @@ PLATFORM_CPPFLAGS += -DCONFIG_MIPS -D__M
111 # On the other hand, we want PIC in the U-Boot code to relocate it from ROM
112 # to RAM. $28 is always used as gp.
114 -PLATFORM_CPPFLAGS += -G 0 -mabicalls -fpic $(ENDIANNESS)
115 +PF_ABICALLS ?= -mabicalls
119 +PLATFORM_CPPFLAGS += -G 0 $(PF_ABICALLS) $(PF_PIC) $(ENDIANNESS)
120 PLATFORM_CPPFLAGS += -msoft-float
121 PLATFORM_LDFLAGS += -G 0 -static -n -nostdlib $(ENDIANNESS)
122 PLATFORM_RELFLAGS += -ffunction-sections -fdata-sections
123 -LDFLAGS_FINAL += --gc-sections -pie
124 +LDFLAGS_FINAL += --gc-sections $(PF_PIE)
125 OBJCFLAGS += --remove-section=.dynsym
126 --- a/arch/mips/cpu/mips32/cache.S
127 +++ b/arch/mips/cpu/mips32/cache.S
130 #define MIPS_MAX_CACHE_SIZE 0x10000
132 +#ifdef CONFIG_SYS_MIPS_CACHE_EXT_INIT
133 +#define INDEX_BASE 0x9fc00000
135 #define INDEX_BASE CKSEG0
138 .macro cache_op op addr
142 LEAF(mips_init_icache)
144 +#ifdef CONFIG_SYS_MIPS_CACHE_EXT_INIT
145 + mtc0 zero, CP0_ITAGLO
149 /* clear tag to invalidate */
150 PTR_LI t0, INDEX_BASE
152 @@ -90,7 +98,11 @@ LEAF(mips_init_icache)
154 LEAF(mips_init_dcache)
156 +#ifdef CONFIG_SYS_MIPS_CACHE_EXT_INIT
157 + mtc0 zero, CP0_DTAGLO
162 PTR_LI t0, INDEX_BASE
165 +++ b/arch/mips/cpu/mips32/danube/Makefile
168 +# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de
170 +# SPDX-License-Identifier: GPL-2.0+
173 +include $(TOPDIR)/config.mk
175 +LIB = $(obj)lib$(SOC).o
177 +COBJS-y += cgu.o chipid.o ebu.o mem.o pmu.o rcu.o
178 +SOBJS-y += cgu_init.o mem_init.o
182 +SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
183 +OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
187 +$(LIB): $(obj).depend $(OBJS)
188 + $(call cmd_link_o_target, $(OBJS))
190 +#########################################################################
192 +# defines $(obj).depend target
193 +include $(SRCTREE)/rules.mk
195 +sinclude $(obj).depend
197 +#########################################################################
199 +++ b/arch/mips/cpu/mips32/danube/cgu.c
202 + * Copyright (C) 2007-2010 Lantiq Deutschland GmbH
203 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
205 + * SPDX-License-Identifier: GPL-2.0+
209 +#include <asm/arch/soc.h>
210 +#include <asm/lantiq/clk.h>
211 +#include <asm/lantiq/io.h>
213 +#define LTQ_CGU_SYS_DDR_MASK 0x0003
214 +#define LTQ_CGU_SYS_DDR_SHIFT 0
215 +#define LTQ_CGU_SYS_CPU0_MASK 0x000C
216 +#define LTQ_CGU_SYS_CPU0_SHIFT 2
217 +#define LTQ_CGU_SYS_FPI_MASK 0x0040
218 +#define LTQ_CGU_SYS_FPI_SHIFT 6
220 +struct ltq_cgu_regs {
222 + u32 pll0_cfg; /* PLL0 config */
223 + u32 pll1_cfg; /* PLL1 config */
224 + u32 pll2_cfg; /* PLL2 config */
225 + u32 sys; /* System clock */
226 + u32 update; /* CGU update control */
227 + u32 if_clk; /* Interface clock */
228 + u32 osc_con; /* Update OSC Control */
229 + u32 smd; /* SDRAM Memory Control */
231 + u32 pcm_cr; /* PCM control */
232 + u32 pci_cr; /* PCI clock control */
235 +static struct ltq_cgu_regs *ltq_cgu_regs =
236 + (struct ltq_cgu_regs *) CKSEG1ADDR(LTQ_CGU_BASE);
238 +static inline u32 ltq_cgu_sys_readl(u32 mask, u32 shift)
240 + return (ltq_readl(<q_cgu_regs->sys) & mask) >> shift;
243 +unsigned long ltq_get_io_region_clock(void)
248 + ddr_sel = ltq_cgu_sys_readl(LTQ_CGU_SYS_DDR_MASK,
249 + LTQ_CGU_SYS_DDR_SHIFT);
253 + clk = CLOCK_166_MHZ;
256 + clk = CLOCK_133_MHZ;
259 + clk = CLOCK_111_MHZ;
262 + clk = CLOCK_83_MHZ;
272 +unsigned long ltq_get_cpu_clock(void)
277 + cpu0_sel = ltq_cgu_sys_readl(LTQ_CGU_SYS_CPU0_MASK,
278 + LTQ_CGU_SYS_CPU0_SHIFT);
280 + switch (cpu0_sel) {
281 + /* Same as PLL0 output (333,33 MHz) */
283 + clk = CLOCK_333_MHZ;
285 + /* 1/1 fixed ratio to DDR clock */
287 + clk = ltq_get_io_region_clock();
289 + /* 1/2 fixed ratio to DDR clock */
291 + clk = ltq_get_io_region_clock() << 1;
301 +unsigned long ltq_get_bus_clock(void)
306 + fpi_sel = ltq_cgu_sys_readl(LTQ_CGU_SYS_FPI_MASK,
307 + LTQ_CGU_SYS_FPI_SHIFT);
310 + /* Half the DDR clock */
311 + clk = ltq_get_io_region_clock() >> 1;
313 + /* Same as DDR clock */
314 + clk = ltq_get_io_region_clock();
319 +++ b/arch/mips/cpu/mips32/danube/cgu_init.S
322 + * Copyright (C) 2007-2010 Lantiq Deutschland GmbH
323 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
325 + * SPDX-License-Identifier: GPL-2.0+
329 +#include <asm/asm.h>
330 +#include <asm/regdef.h>
331 +#include <asm/addrspace.h>
332 +#include <asm/arch/soc.h>
334 +/* RCU module register */
335 +#define LTQ_RCU_RST_REQ 0x0010
336 +#define LTQ_RCU_RST_STAT 0x0014
337 +#define LTQ_RCU_RST_REQ_VALUE 0x40000008
338 +#define LTQ_RCU_RST_STAT_XTAL_F 0x20000
340 +/* CGU module register */
341 +#define LTQ_CGU_PLL0_CFG 0x0004 /* PLL0 config */
342 +#define LTQ_CGU_PLL1_CFG 0x0008 /* PLL1 config */
343 +#define LTQ_CGU_PLL2_CFG 0x000C /* PLL2 config */
344 +#define LTQ_CGU_SYS 0x0010 /* System clock */
346 +/* Valid SYS.CPU0/1 values */
347 +#define LTQ_CGU_SYS_CPU0_SHIFT 2
348 +#define LTQ_CGU_SYS_CPU1_SHIFT 4
349 +#define LTQ_CGU_SYS_CPU_PLL0 0x0
350 +#define LTQ_CGU_SYS_CPU_DDR_EQUAL 0x1
351 +#define LTQ_CGU_SYS_CPU_DDR_TWICE 0x2
353 +/* Valid SYS.DDR values */
354 +#define LTQ_CGU_SYS_DDR_SHIFT 0
355 +#define LTQ_CGU_SYS_DDR_167_MHZ 0x0
356 +#define LTQ_CGU_SYS_DDR_133_MHZ 0x1
357 +#define LTQ_CGU_SYS_DDR_111_MHZ 0x2
358 +#define LTQ_CGU_SYS_DDR_83_MHZ 0x3
360 +/* Valid SYS.FPI values */
361 +#define LTQ_CGU_SYS_FPI_SHIFT 6
362 +#define LTQ_CGU_SYS_FPI_DDR_EQUAL 0x0
363 +#define LTQ_CGU_SYS_FPI_DDR_HALF 0x1
365 +/* Valid SYS.PPE values */
366 +#define LTQ_CGU_SYS_PPE_SHIFT 7
367 +#define LTQ_CGU_SYS_PPE_266_MHZ 0x0
368 +#define LTQ_CGU_SYS_PPE_240_MHZ 0x1
369 +#define LTQ_CGU_SYS_PPE_222_MHZ 0x2
370 +#define LTQ_CGU_SYS_PPE_133_MHZ 0x3
372 +#if (CONFIG_SYS_CLOCK_MODE == LTQ_CLK_CPU_333_DDR_167)
373 +#define LTQ_CGU_SYS_CPU_CONFIG LTQ_CGU_SYS_CPU_DDR_TWICE
374 +#define LTQ_CGU_SYS_DDR_CONFIG LTQ_CGU_SYS_DDR_167_MHZ
375 +#define LTQ_CGU_SYS_FPI_CONFIG LTQ_CGU_SYS_FPI_DDR_HALF
376 +#define LTQ_CGU_SYS_PPE_CONFIG LTQ_CGU_SYS_PPE_266_MHZ
377 +#elif (CONFIG_SYS_CLOCK_MODE == LTQ_CLK_CPU_111_DDR_111)
378 +#define LTQ_CGU_SYS_CPU_CONFIG LTQ_CGU_SYS_CPU_DDR_EQUAL
379 +#define LTQ_CGU_SYS_DDR_CONFIG LTQ_CGU_SYS_DDR_111_MHZ
380 +#define LTQ_CGU_SYS_FPI_CONFIG LTQ_CGU_SYS_FPI_DDR_HALF
381 +#define LTQ_CGU_SYS_PPE_CONFIG LTQ_CGU_SYS_PPE_133_MHZ
383 +#error "Invalid system clock configuration!"
386 +/* Build register values */
387 +#define LTQ_CGU_SYS_VALUE ((LTQ_CGU_SYS_PPE_CONFIG << \
388 + LTQ_CGU_SYS_PPE_SHIFT) | \
389 + (LTQ_CGU_SYS_FPI_CONFIG << \
390 + LTQ_CGU_SYS_FPI_SHIFT) | \
391 + (LTQ_CGU_SYS_CPU_CONFIG << \
392 + LTQ_CGU_SYS_CPU1_SHIFT) | \
393 + (LTQ_CGU_SYS_CPU_CONFIG << \
394 + LTQ_CGU_SYS_CPU0_SHIFT) | \
395 + LTQ_CGU_SYS_DDR_CONFIG)
397 +/* Reset values for PLL registers for usage with 35.328 MHz crystal */
398 +#define PLL0_35MHZ_CONFIG 0x9D861059
399 +#define PLL1_35MHZ_CONFIG 0x1A260CD9
400 +#define PLL2_35MHZ_CONFIG 0x8000f1e5
402 +/* Reset values for PLL registers for usage with 36 MHz crystal */
403 +#define PLL0_36MHZ_CONFIG 0x1000125D
404 +#define PLL1_36MHZ_CONFIG 0x1B1E0C99
405 +#define PLL2_36MHZ_CONFIG 0x8002f2a1
408 + /* Load current CGU register value */
409 + li t0, (LTQ_CGU_BASE | KSEG1)
410 + lw t1, LTQ_CGU_SYS(t0)
412 + /* Load target CGU register values */
413 + li t3, LTQ_CGU_SYS_VALUE
415 + /* Only update registers if values differ */
416 + beq t1, t3, finished
419 + * Check whether the XTAL_F bit in RST_STAT register is set or not.
420 + * This bit is latched in via pin strapping. If bit is set then
421 + * clock source is a 36 MHz crystal. Otherwise a 35.328 MHz crystal.
423 + li t1, (LTQ_RCU_BASE | KSEG1)
424 + lw t2, LTQ_RCU_RST_STAT(t1)
425 + and t2, t2, LTQ_RCU_RST_STAT_XTAL_F
426 + beq t2, LTQ_RCU_RST_STAT_XTAL_F, boot_36mhz
429 + /* Configure PLL for 35.328 MHz */
430 + li t2, PLL0_35MHZ_CONFIG
431 + sw t2, LTQ_CGU_PLL0_CFG(t0)
432 + li t2, PLL1_35MHZ_CONFIG
433 + sw t2, LTQ_CGU_PLL1_CFG(t0)
434 + li t2, PLL2_35MHZ_CONFIG
435 + sw t2, LTQ_CGU_PLL2_CFG(t0)
440 + /* Configure PLL for 36 MHz */
441 + li t2, PLL0_36MHZ_CONFIG
442 + sw t2, LTQ_CGU_PLL0_CFG(t0)
443 + li t2, PLL1_36MHZ_CONFIG
444 + sw t2, LTQ_CGU_PLL1_CFG(t0)
445 + li t2, PLL2_36MHZ_CONFIG
446 + sw t2, LTQ_CGU_PLL2_CFG(t0)
449 + /* Store new clock config */
450 + sw t3, LTQ_CGU_SYS(t0)
452 + /* Perform software reset to activate new clock config */
453 + li t2, LTQ_RCU_RST_REQ_VALUE
454 + sw t2, LTQ_RCU_RST_REQ(t1)
464 +++ b/arch/mips/cpu/mips32/danube/chipid.c
467 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
469 + * SPDX-License-Identifier: GPL-2.0+
473 +#include <asm/lantiq/io.h>
474 +#include <asm/lantiq/chipid.h>
475 +#include <asm/arch/soc.h>
477 +#define LTQ_CHIPID_VERSION_SHIFT 28
478 +#define LTQ_CHIPID_VERSION_MASK (0xF << LTQ_CHIPID_VERSION_SHIFT)
479 +#define LTQ_CHIPID_PNUM_SHIFT 12
480 +#define LTQ_CHIPID_PNUM_MASK (0xFFFF << LTQ_CHIPID_PNUM_SHIFT)
482 +struct ltq_chipid_regs {
483 + u32 manid; /* Manufacturer identification */
484 + u32 chipid; /* Chip identification */
487 +static struct ltq_chipid_regs *ltq_chipid_regs =
488 + (struct ltq_chipid_regs *) CKSEG1ADDR(LTQ_CHIPID_BASE);
490 +unsigned int ltq_chip_version_get(void)
494 + chipid = ltq_readl(<q_chipid_regs->chipid);
496 + return (chipid & LTQ_CHIPID_VERSION_MASK) >> LTQ_CHIPID_VERSION_SHIFT;
499 +unsigned int ltq_chip_partnum_get(void)
503 + chipid = ltq_readl(<q_chipid_regs->chipid);
505 + return (chipid & LTQ_CHIPID_PNUM_MASK) >> LTQ_CHIPID_PNUM_SHIFT;
508 +const char *ltq_chip_partnum_str(void)
510 + enum ltq_chip_partnum partnum = ltq_chip_partnum_get();
513 + case LTQ_SOC_DANUBE:
515 + case LTQ_SOC_DANUBE_S:
517 + case LTQ_SOC_TWINPASS:
520 + printf("Unknown partnum: %x\n", partnum);
526 +++ b/arch/mips/cpu/mips32/danube/config.mk
529 +# Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
531 +# SPDX-License-Identifier: GPL-2.0+
534 +PF_CPPFLAGS_DANUBE := $(call cc-option,-mtune=24kec,)
535 +PLATFORM_CPPFLAGS += $(PF_CPPFLAGS_DANUBE)
537 +ifdef CONFIG_SPL_BUILD
538 +PF_ABICALLS := -mno-abicalls
541 +USE_PRIVATE_LIBGCC := yes
544 +LIBS-y += $(CPUDIR)/lantiq-common/liblantiq-common.o
546 +ifndef CONFIG_SPL_BUILD
547 +ifdef CONFIG_SYS_BOOT_NORSPL
548 +ALL-y += $(obj)u-boot.ltq.norspl
549 +ALL-$(CONFIG_SPL_LZO_SUPPORT) += $(obj)u-boot.ltq.lzo.norspl
550 +ALL-$(CONFIG_SPL_LZMA_SUPPORT) += $(obj)u-boot.ltq.lzma.norspl
554 +++ b/arch/mips/cpu/mips32/danube/ebu.c
557 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
559 + * SPDX-License-Identifier: GPL-2.0+
563 +#include <asm/arch/soc.h>
564 +#include <asm/lantiq/io.h>
566 +#define EBU_ADDRSEL_MASK(mask) ((mask & 0xf) << 4)
567 +#define EBU_ADDRSEL_REGEN (1 << 0)
569 +#define EBU_CON_WRDIS (1 << 31)
570 +#define EBU_CON_AGEN_DEMUX (0x0 << 24)
571 +#define EBU_CON_AGEN_MUX (0x2 << 24)
572 +#define EBU_CON_SETUP (1 << 22)
573 +#define EBU_CON_WAIT_DIS (0x0 << 20)
574 +#define EBU_CON_WAIT_ASYNC (0x1 << 20)
575 +#define EBU_CON_WAIT_SYNC (0x2 << 20)
576 +#define EBU_CON_WINV (1 << 19)
577 +#define EBU_CON_PW_8BIT (0x0 << 16)
578 +#define EBU_CON_PW_16BIT (0x1 << 16)
579 +#define EBU_CON_ALEC(cycles) ((cycles & 0x3) << 14)
580 +#define EBU_CON_BCGEN_CS (0x0 << 12)
581 +#define EBU_CON_BCGEN_INTEL (0x1 << 12)
582 +#define EBU_CON_BCGEN_MOTOROLA (0x2 << 12)
583 +#define EBU_CON_WAITWRC(cycles) ((cycles & 0x7) << 8)
584 +#define EBU_CON_WAITRDC(cycles) ((cycles & 0x3) << 6)
585 +#define EBU_CON_HOLDC(cycles) ((cycles & 0x3) << 4)
586 +#define EBU_CON_RECOVC(cycles) ((cycles & 0x3) << 2)
587 +#define EBU_CON_CMULT_1 0x0
588 +#define EBU_CON_CMULT_4 0x1
589 +#define EBU_CON_CMULT_8 0x2
590 +#define EBU_CON_CMULT_16 0x3
592 +#if defined(CONFIG_LTQ_SUPPORT_NOR_FLASH)
593 +#define ebu_region0_enable 1
595 +#define ebu_region0_enable 0
598 +#if defined(CONFIG_LTQ_SUPPORT_NAND_FLASH)
599 +#define ebu_region1_enable 1
601 +#define ebu_region1_enable 0
604 +struct ltq_ebu_regs {
616 +static struct ltq_ebu_regs *ltq_ebu_regs =
617 + (struct ltq_ebu_regs *) CKSEG1ADDR(LTQ_EBU_BASE);
619 +void ltq_ebu_init(void)
621 + if (ebu_region0_enable) {
623 + * Map EBU region 0 to range 0x10000000-0x13ffffff and enable
624 + * region control. This supports up to 32 MiB NOR flash in
627 + ltq_writel(<q_ebu_regs->addr_sel_0, LTQ_EBU_REGION0_BASE |
628 + EBU_ADDRSEL_MASK(1) | EBU_ADDRSEL_REGEN);
630 + ltq_writel(<q_ebu_regs->con_0, EBU_CON_AGEN_DEMUX |
631 + EBU_CON_WAIT_DIS | EBU_CON_PW_16BIT |
632 + EBU_CON_ALEC(3) | EBU_CON_BCGEN_INTEL |
633 + EBU_CON_WAITWRC(7) | EBU_CON_WAITRDC(3) |
634 + EBU_CON_HOLDC(3) | EBU_CON_RECOVC(3) |
637 + ltq_clrbits(<q_ebu_regs->addr_sel_0, EBU_ADDRSEL_REGEN);
639 + if (ebu_region1_enable) {
641 + * Map EBU region 1 to range 0x14000000-0x13ffffff and enable
642 + * region control. This supports NAND flash in bank 1.
644 + ltq_writel(<q_ebu_regs->addr_sel_1, LTQ_EBU_REGION1_BASE |
645 + EBU_ADDRSEL_MASK(3) | EBU_ADDRSEL_REGEN);
647 + ltq_writel(<q_ebu_regs->con_1, EBU_CON_AGEN_DEMUX |
648 + EBU_CON_SETUP | EBU_CON_WAIT_DIS | EBU_CON_PW_8BIT |
649 + EBU_CON_ALEC(3) | EBU_CON_BCGEN_INTEL |
650 + EBU_CON_WAITWRC(2) | EBU_CON_WAITRDC(2) |
651 + EBU_CON_HOLDC(1) | EBU_CON_RECOVC(1) |
654 + ltq_clrbits(<q_ebu_regs->addr_sel_1, EBU_ADDRSEL_REGEN);
657 +void *flash_swap_addr(unsigned long addr)
659 + return (void *)(addr ^ 2);
662 +++ b/arch/mips/cpu/mips32/danube/mem.c
665 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
667 + * SPDX-License-Identifier: GPL-2.0+
671 +#include <asm/arch/soc.h>
672 +#include <asm/lantiq/io.h>
674 +static void *ltq_mc_ddr_base = (void *) CKSEG1ADDR(LTQ_MC_DDR_BASE);
676 +static inline u32 ltq_mc_dc_read(u32 index)
678 + return ltq_readl(ltq_mc_ddr_base + LTQ_MC_DDR_DC_OFFSET(index));
681 +phys_size_t initdram(int board_type)
683 + u32 col, row, dc04, dc19, dc20;
685 + dc04 = ltq_mc_dc_read(4);
686 + dc19 = ltq_mc_dc_read(19);
687 + dc20 = ltq_mc_dc_read(20);
689 + row = (dc04 & 0xF) - ((dc19 & 0x700) >> 8);
690 + col = ((dc04 & 0xF00) >> 8) - (dc20 & 0x7);
692 + return (1 << (row + col)) * 4 * 2;
695 +++ b/arch/mips/cpu/mips32/danube/mem_init.S
698 + * Copyright (C) 2007-2010 Lantiq Deutschland GmbH
699 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
701 + * SPDX-License-Identifier: GPL-2.0+
705 +#include <asm/asm.h>
706 +#include <asm/regdef.h>
707 +#include <asm/addrspace.h>
708 +#include <asm/arch/soc.h>
710 +/* Must be configured in BOARDDIR */
711 +#include <ddr_settings.h>
713 +#define LTQ_MC_GEN_ERRCAUSE 0x0010
714 +#define LTQ_MC_GEN_ERRADDR 0x0020
715 +#define LTQ_MC_GEN_CON 0x0060
716 +#define LTQ_MC_GEN_STAT 0x0070
717 +#define LTQ_MC_GEN_CON_SRAM_DDR_ENABLE 0x5
718 +#define LTQ_MC_GEN_STAT_DLCK_PWRON 0xC
720 +#define LTQ_MC_DDR_DC03_MC_START 0x100
722 + /* Store given value in MC DDR CCRx register */
723 + .macro dc_sw num, val
725 + sw t2, LTQ_MC_DDR_DC_OFFSET(\num)(t1)
729 + /* Load MC General and MC DDR module base */
730 + li t0, (LTQ_MC_GEN_BASE | KSEG1)
731 + li t1, (LTQ_MC_DDR_BASE | KSEG1)
733 + /* Clear access error log registers */
734 + sw zero, LTQ_MC_GEN_ERRCAUSE(t0)
735 + sw zero, LTQ_MC_GEN_ERRADDR(t0)
737 + /* Enable DDR and SRAM module in memory controller */
738 + li t2, LTQ_MC_GEN_CON_SRAM_DDR_ENABLE
739 + sw t2, LTQ_MC_GEN_CON(t0)
741 + /* Clear start bit of DDR memory controller */
742 + sw zero, LTQ_MC_DDR_DC_OFFSET(3)(t1)
744 + /* Init memory controller registers with values ddr_settings.h */
745 + dc_sw 0, MC_DC00_VALUE
746 + dc_sw 1, MC_DC01_VALUE
747 + dc_sw 2, MC_DC02_VALUE
748 + dc_sw 4, MC_DC04_VALUE
749 + dc_sw 5, MC_DC05_VALUE
750 + dc_sw 6, MC_DC06_VALUE
751 + dc_sw 7, MC_DC07_VALUE
752 + dc_sw 8, MC_DC08_VALUE
753 + dc_sw 9, MC_DC09_VALUE
755 + dc_sw 10, MC_DC10_VALUE
756 + dc_sw 11, MC_DC11_VALUE
757 + dc_sw 12, MC_DC12_VALUE
758 + dc_sw 13, MC_DC13_VALUE
759 + dc_sw 14, MC_DC14_VALUE
760 + dc_sw 15, MC_DC15_VALUE
761 + dc_sw 16, MC_DC16_VALUE
762 + dc_sw 17, MC_DC17_VALUE
763 + dc_sw 18, MC_DC18_VALUE
764 + dc_sw 19, MC_DC19_VALUE
766 + dc_sw 20, MC_DC20_VALUE
767 + dc_sw 21, MC_DC21_VALUE
768 + dc_sw 22, MC_DC22_VALUE
769 + dc_sw 23, MC_DC23_VALUE
770 + dc_sw 24, MC_DC24_VALUE
771 + dc_sw 25, MC_DC25_VALUE
772 + dc_sw 26, MC_DC26_VALUE
773 + dc_sw 27, MC_DC27_VALUE
774 + dc_sw 28, MC_DC28_VALUE
775 + dc_sw 29, MC_DC29_VALUE
777 + dc_sw 30, MC_DC30_VALUE
778 + dc_sw 31, MC_DC31_VALUE
779 + dc_sw 32, MC_DC32_VALUE
780 + dc_sw 33, MC_DC33_VALUE
781 + dc_sw 34, MC_DC34_VALUE
782 + dc_sw 35, MC_DC35_VALUE
783 + dc_sw 36, MC_DC36_VALUE
784 + dc_sw 37, MC_DC37_VALUE
785 + dc_sw 38, MC_DC38_VALUE
786 + dc_sw 39, MC_DC39_VALUE
788 + dc_sw 40, MC_DC40_VALUE
789 + dc_sw 41, MC_DC41_VALUE
790 + dc_sw 42, MC_DC42_VALUE
791 + dc_sw 43, MC_DC43_VALUE
792 + dc_sw 44, MC_DC44_VALUE
793 + dc_sw 45, MC_DC45_VALUE
794 + dc_sw 46, MC_DC46_VALUE
796 + /* Set start bit of DDR memory controller */
797 + li t2, LTQ_MC_DDR_DC03_MC_START
798 + sw t2, LTQ_MC_DDR_DC_OFFSET(3)(t1)
800 + /* Wait until DLL has locked and core is ready for data transfers */
802 + lw t2, LTQ_MC_GEN_STAT(t0)
803 + li t3, LTQ_MC_GEN_STAT_DLCK_PWRON
805 + bne t2, t3, wait_ready
812 +++ b/arch/mips/cpu/mips32/danube/pmu.c
815 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
817 + * SPDX-License-Identifier: GPL-2.0+
821 +#include <asm/lantiq/io.h>
822 +#include <asm/lantiq/pm.h>
823 +#include <asm/arch/soc.h>
825 +#define LTQ_PMU_PWDCR_RESERVED 0xFD0C001C
827 +#define LTQ_PMU_PWDCR_TDM (1 << 25)
828 +#define LTQ_PMU_PWDCR_PPE_ENET0 (1 << 23)
829 +#define LTQ_PMU_PWDCR_PPE_ENET1 (1 << 22)
830 +#define LTQ_PMU_PWDCR_PPE_TC (1 << 21)
831 +#define LTQ_PMU_PWDCR_DEU (1 << 20)
832 +#define LTQ_PMU_PWDCR_UART1 (1 << 17)
833 +#define LTQ_PMU_PWDCR_SDIO (1 << 16)
834 +#define LTQ_PMU_PWDCR_AHB (1 << 15)
835 +#define LTQ_PMU_PWDCR_FPI0 (1 << 14)
836 +#define LTQ_PMU_PWDCR_PPE (1 << 13)
837 +#define LTQ_PMU_PWDCR_GPTC (1 << 12)
838 +#define LTQ_PMU_PWDCR_LEDC (1 << 11)
839 +#define LTQ_PMU_PWDCR_EBU (1 << 10)
840 +#define LTQ_PMU_PWDCR_DSL (1 << 9)
841 +#define LTQ_PMU_PWDCR_SPI (1 << 8)
842 +#define LTQ_PMU_PWDCR_UART0 (1 << 7)
843 +#define LTQ_PMU_PWDCR_USB (1 << 6)
844 +#define LTQ_PMU_PWDCR_DMA (1 << 5)
845 +#define LTQ_PMU_PWDCR_FPI1 (1 << 1)
846 +#define LTQ_PMU_PWDCR_USB_PHY (1 << 0)
848 +struct ltq_pmu_regs {
856 +static struct ltq_pmu_regs *ltq_pmu_regs =
857 + (struct ltq_pmu_regs *) CKSEG1ADDR(LTQ_PMU_BASE);
859 +u32 ltq_pm_map(enum ltq_pm_modules module)
865 + val = LTQ_PMU_PWDCR_UART1 | LTQ_PMU_PWDCR_FPI0 |
866 + LTQ_PMU_PWDCR_LEDC | LTQ_PMU_PWDCR_EBU;
869 + val = LTQ_PMU_PWDCR_DMA;
872 + val = LTQ_PMU_PWDCR_PPE_ENET0 | LTQ_PMU_PWDCR_PPE_TC |
876 + val = LTQ_PMU_PWDCR_SPI;
886 +int ltq_pm_enable(enum ltq_pm_modules module)
888 + const unsigned long timeout = 1000;
889 + unsigned long timebase;
892 + val = ltq_pm_map(module);
893 + if (unlikely(!val))
896 + ltq_clrbits(<q_pmu_regs->pwdcr, val);
898 + timebase = get_timer(0);
901 + sr = ltq_readl(<q_pmu_regs->sr);
904 + } while (get_timer(timebase) < timeout);
909 +int ltq_pm_disable(enum ltq_pm_modules module)
913 + val = ltq_pm_map(module);
914 + if (unlikely(!val))
917 + ltq_setbits(<q_pmu_regs->pwdcr, val);
922 +void ltq_pmu_init(void)
926 + clr = ltq_pm_map(LTQ_PM_CORE);
927 + set = ~(LTQ_PMU_PWDCR_RESERVED | clr);
929 + ltq_clrsetbits(<q_pmu_regs->pwdcr, clr, set);
932 +++ b/arch/mips/cpu/mips32/danube/rcu.c
935 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
937 + * SPDX-License-Identifier: GPL-2.0+
941 +#include <asm/lantiq/io.h>
942 +#include <asm/lantiq/reset.h>
943 +#include <asm/lantiq/cpu.h>
944 +#include <asm/arch/soc.h>
946 +#define LTQ_RCU_RD_SRST (1 << 30) /* Global SW Reset */
947 +#define LTQ_RCU_RD_MC (1 << 14) /* Memory Controller */
948 +#define LTQ_RCU_RD_PCI (1 << 13) /* PCI core */
949 +#define LTQ_RCU_RD_DFE_AFE (1 << 12) /* Voice DFE/AFE */
950 +#define LTQ_RCU_RD_DSL_AFE (1 << 11) /* DSL AFE */
951 +#define LTQ_RCU_RD_SDIO (1 << 10) /* SDIO core */
952 +#define LTQ_RCU_RD_DMA (1 << 9) /* DMA core */
953 +#define LTQ_RCU_RD_PPE (1 << 8) /* PPE core */
954 +#define LTQ_RCU_RD_ARC_DFE (1 << 7) /* ARC/DFE core */
955 +#define LTQ_RCU_RD_AHB (1 << 6) /* AHB bus */
956 +#define LTQ_RCU_RD_ENET_MAC1 (1 << 5) /* Ethernet MAC1 */
957 +#define LTQ_RCU_RD_USB (1 << 4) /* USB and Phy core */
958 +#define LTQ_RCU_RD_CPU1 (1 << 3) /* CPU1 subsystem */
959 +#define LTQ_RCU_RD_FPI (1 << 2) /* FPI bus */
960 +#define LTQ_RCU_RD_CPU0 (1 << 1) /* CPU0 subsystem */
961 +#define LTQ_RCU_RD_HRST (1 << 0) /* HW reset via HRST pin */
963 +#define LTQ_RCU_STAT_BOOT_SHIFT 18
964 +#define LTQ_RCU_STAT_BOOT_MASK (0x7 << LTQ_RCU_STAT_BOOT_SHIFT)
966 +struct ltq_rcu_regs {
968 + u32 req; /* Reset request */
969 + u32 stat; /* Reset status */
970 + u32 usb_cfg; /* USB configure */
972 + u32 pci_rdy; /* PCI boot ready */
975 +static struct ltq_rcu_regs *ltq_rcu_regs =
976 + (struct ltq_rcu_regs *) CKSEG1ADDR(LTQ_RCU_BASE);
978 +u32 ltq_reset_map(enum ltq_reset_modules module)
983 + case LTQ_RESET_CORE:
984 + case LTQ_RESET_SOFT:
985 + val = LTQ_RCU_RD_SRST | LTQ_RCU_RD_CPU1;
987 + case LTQ_RESET_DMA:
988 + val = LTQ_RCU_RD_DMA;
990 + case LTQ_RESET_ETH:
991 + val = LTQ_RCU_RD_PPE;
993 + case LTQ_RESET_HARD:
994 + val = LTQ_RCU_RD_HRST;
1004 +int ltq_reset_activate(enum ltq_reset_modules module)
1008 + val = ltq_reset_map(module);
1009 + if (unlikely(!val))
1012 + ltq_setbits(<q_rcu_regs->req, val);
1017 +int ltq_reset_deactivate(enum ltq_reset_modules module)
1021 + val = ltq_reset_map(module);
1022 + if (unlikely(!val))
1025 + ltq_clrbits(<q_rcu_regs->req, val);
1030 +enum ltq_boot_select ltq_boot_select(void)
1033 + unsigned int bootstrap;
1035 + stat = ltq_readl(<q_rcu_regs->stat);
1036 + bootstrap = (stat & LTQ_RCU_STAT_BOOT_MASK) >> LTQ_RCU_STAT_BOOT_SHIFT;
1038 + switch (bootstrap) {
1040 + return BOOT_NOR_NO_BOOTROM;
1054 + return BOOT_RMII0;
1056 + return BOOT_UNKNOWN;
1060 +++ b/arch/mips/cpu/mips32/lantiq-common/Makefile
1063 +# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de
1065 +# SPDX-License-Identifier: GPL-2.0+
1068 +include $(TOPDIR)/config.mk
1070 +LIB = $(obj)liblantiq-common.o
1073 +COBJS-y = cpu.o pmu.o
1074 +COBJS-$(CONFIG_SPL_BUILD) += spl.o
1075 +SOBJS-y = lowlevel_init.o
1077 +COBJS := $(COBJS-y)
1078 +SOBJS := $(SOBJS-y)
1079 +SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
1080 +OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
1081 +START := $(addprefix $(obj),$(START))
1085 +$(LIB): $(obj).depend $(OBJS)
1086 + $(call cmd_link_o_target, $(OBJS))
1088 +#########################################################################
1090 +# defines $(obj).depend target
1091 +include $(SRCTREE)/rules.mk
1093 +sinclude $(obj).depend
1095 +#########################################################################
1097 +++ b/arch/mips/cpu/mips32/lantiq-common/cpu.c
1100 + * Copyright (C) 2012-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
1102 + * SPDX-License-Identifier: GPL-2.0+
1105 +#include <common.h>
1106 +#include <asm/lantiq/chipid.h>
1107 +#include <asm/lantiq/clk.h>
1108 +#include <asm/lantiq/reset.h>
1109 +#include <asm/lantiq/cpu.h>
1111 +static const char ltq_bootsel_strings[][16] = {
1113 + "NOR w/o BootROM",
1115 + "UART w/o EEPROM",
1125 +const char *ltq_boot_select_str(void)
1126 +{ enum ltq_boot_select bootsel = ltq_boot_select();
1128 + if (bootsel > BOOT_UNKNOWN)
1129 + bootsel = BOOT_UNKNOWN;
1131 + return ltq_bootsel_strings[bootsel];
1134 +void ltq_chip_print_info(void)
1138 + printf("SoC: Lantiq %s v1.%u\n", ltq_chip_partnum_str(),
1139 + ltq_chip_version_get());
1140 + printf("CPU: %s MHz\n", strmhz(buf, ltq_get_cpu_clock()));
1141 + printf("IO: %s MHz\n", strmhz(buf, ltq_get_io_region_clock()));
1142 + printf("BUS: %s MHz\n", strmhz(buf, ltq_get_bus_clock()));
1143 + printf("BOOT: %s\n", ltq_boot_select_str());
1146 +int arch_cpu_init(void)
1154 +void _machine_restart(void)
1156 + ltq_reset_activate(LTQ_RESET_CORE);
1159 +++ b/arch/mips/cpu/mips32/lantiq-common/lowlevel_init.S
1162 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
1164 + * SPDX-License-Identifier: GPL-2.0+
1167 +#include <asm/asm.h>
1168 +#include <asm/regdef.h>
1170 +NESTED(lowlevel_init, 0, ra)
1173 + la t7, ltq_cgu_init
1176 + la t7, ltq_mem_init
1180 + END(lowlevel_init)
1182 +++ b/arch/mips/cpu/mips32/lantiq-common/pmu.c
1185 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
1187 + * SPDX-License-Identifier: GPL-2.0+
1190 +#include <common.h>
1191 +#include <asm/lantiq/pm.h>
1194 +++ b/arch/mips/cpu/mips32/lantiq-common/spl.c
1197 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
1199 + * SPDX-License-Identifier: GPL-2.0+
1202 +#include <common.h>
1204 +#include <version.h>
1205 +#include <spi_flash.h>
1206 +#include <linux/compiler.h>
1207 +#include <lzma/LzmaDec.h>
1208 +#include <linux/lzo.h>
1209 +#include <asm/mipsregs.h>
1211 +#if defined(CONFIG_LTQ_SPL_CONSOLE)
1212 +#define spl_has_console 1
1214 +#if defined(CONFIG_LTQ_SPL_DEBUG)
1215 +#define spl_has_debug 1
1217 +#define spl_has_debug 0
1221 +#define spl_has_console 0
1222 +#define spl_has_debug 0
1225 +#define spl_debug(fmt, args...) \
1227 + if (spl_has_debug) \
1228 + printf(fmt, ##args); \
1231 +#define spl_puts(msg) \
1233 + if (spl_has_console) \
1237 +#if defined(CONFIG_LTQ_SUPPORT_SPL_SPI_FLASH) && defined(CONFIG_SYS_BOOT_SFSPL)
1238 +#define spl_boot_spi_flash 1
1240 +#define spl_boot_spi_flash 0
1241 +#ifndef CONFIG_SPL_SPI_BUS
1242 +#define CONFIG_SPL_SPI_BUS 0
1244 +#ifndef CONFIG_SPL_SPI_CS
1245 +#define CONFIG_SPL_SPI_CS 0
1247 +#ifndef CONFIG_SPL_SPI_MAX_HZ
1248 +#define CONFIG_SPL_SPI_MAX_HZ 0
1250 +#ifndef CONFIG_SPL_SPI_MODE
1251 +#define CONFIG_SPL_SPI_MODE 0
1255 +#if defined(CONFIG_LTQ_SUPPORT_SPL_NOR_FLASH) && defined(CONFIG_SYS_BOOT_NORSPL)
1256 +#define spl_boot_nor_flash 1
1258 +#define spl_boot_nor_flash 0
1261 +#define spl_sync() __asm__ __volatile__("sync");
1272 +DECLARE_GLOBAL_DATA_PTR;
1274 +/* Emulated malloc area needed for LZMA allocator in BSS */
1275 +static u8 *spl_mem_ptr __maybe_unused;
1276 +static size_t spl_mem_size __maybe_unused;
1278 +static int spl_is_comp_lzma(const struct spl_image *spl)
1280 +#if defined(CONFIG_LTQ_SPL_COMP_LZMA)
1281 + return spl->comp == IH_COMP_LZMA;
1287 +static int spl_is_comp_lzo(const struct spl_image *spl)
1289 +#if defined(CONFIG_LTQ_SPL_COMP_LZO)
1290 + return spl->comp == IH_COMP_LZO;
1296 +static int spl_is_compressed(const struct spl_image *spl)
1298 + if (spl_is_comp_lzma(spl))
1301 + if (spl_is_comp_lzo(spl))
1307 +static void spl_console_init(void)
1309 + if (!spl_has_console)
1312 + gd->flags |= GD_FLG_RELOC;
1313 + gd->baudrate = CONFIG_BAUDRATE;
1317 + gd->have_console = 1;
1319 + spl_puts("\nU-Boot SPL " PLAIN_VERSION " (" U_BOOT_DATE " - " \
1320 + U_BOOT_TIME ")\n");
1323 +static int spl_parse_image(const image_header_t *hdr, struct spl_image *spl)
1325 + spl_puts("SPL: checking U-Boot image\n");
1327 + if (!image_check_magic(hdr)) {
1328 + spl_puts("SPL: invalid magic\n");
1332 + if (!image_check_hcrc(hdr)) {
1333 + spl_puts("SPL: invalid header CRC\n");
1337 + spl->data_addr += image_get_header_size();
1338 + spl->entry_addr = image_get_load(hdr);
1339 + spl->data_size = image_get_data_size(hdr);
1340 + spl->data_crc = image_get_dcrc(hdr);
1341 + spl->comp = image_get_comp(hdr);
1343 + spl_debug("SPL: data %08lx, size %lu, entry %08lx, comp %u\n",
1344 + spl->data_addr, spl->data_size, spl->entry_addr, spl->comp);
1349 +static int spl_check_data(const struct spl_image *spl, ulong loadaddr)
1351 + ulong dcrc = crc32(0, (unsigned char *)loadaddr, spl->data_size);
1353 + if (dcrc != spl->data_crc) {
1354 + spl_puts("SPL: invalid data CRC\n");
1361 +static void *spl_lzma_alloc(void *p, size_t size)
1365 + if (size > spl_mem_size)
1368 + ret = spl_mem_ptr;
1369 + spl_mem_ptr += size;
1370 + spl_mem_size -= size;
1375 +static void spl_lzma_free(void *p, void *addr)
1379 +static int spl_copy_image(struct spl_image *spl)
1381 + spl_puts("SPL: copying U-Boot to RAM\n");
1383 + memcpy((void *) spl->entry_addr, (const void *) spl->data_addr,
1386 + spl->entry_size = spl->data_size;
1391 +static int spl_uncompress_lzma(struct spl_image *spl, unsigned long loadaddr)
1394 + const Byte *prop = (const Byte *) loadaddr;
1395 + const Byte *src = (const Byte *) loadaddr + LZMA_PROPS_SIZE +
1397 + Byte *dest = (Byte *) spl->entry_addr;
1398 + SizeT dest_len = 0xFFFFFFFF;
1399 + SizeT src_len = spl->data_size - LZMA_PROPS_SIZE;
1400 + ELzmaStatus status = 0;
1403 + spl_puts("SPL: decompressing U-Boot with LZMA\n");
1405 + alloc.Alloc = spl_lzma_alloc;
1406 + alloc.Free = spl_lzma_free;
1407 + spl_mem_ptr = (u8 *) CONFIG_SPL_MALLOC_BASE;
1408 + spl_mem_size = CONFIG_SPL_MALLOC_MAX_SIZE;
1410 + res = LzmaDecode(dest, &dest_len, src, &src_len, prop, LZMA_PROPS_SIZE,
1411 + LZMA_FINISH_ANY, &status, &alloc);
1415 + spl->entry_size = dest_len;
1420 +static int spl_uncompress_lzo(struct spl_image *spl, unsigned long loadaddr)
1425 + spl_puts("SPL: decompressing U-Boot with LZO\n");
1427 + ret = lzop_decompress(
1428 + (const unsigned char*) loadaddr, spl->data_size,
1429 + (unsigned char *) spl->entry_addr, &len);
1431 + spl->entry_size = len;
1436 +static int spl_uncompress(struct spl_image *spl, unsigned long loadaddr)
1440 + if (spl_is_comp_lzma(spl))
1441 + ret = spl_uncompress_lzma(spl, loadaddr);
1442 + else if (spl_is_comp_lzo(spl))
1443 + ret = spl_uncompress_lzo(spl, loadaddr);
1450 +static int spl_load_spi_flash(struct spl_image *spl)
1452 + struct spi_flash sf = { 0 };
1453 + image_header_t hdr;
1455 + unsigned long loadaddr;
1460 + * - 12 byte non-volatile bootstrap header
1462 + * - 12 byte non-volatile bootstrap header
1463 + * - 64 byte U-Boot mkimage header
1466 + spl->data_addr = image_copy_end() - CONFIG_SPL_TEXT_BASE + 24;
1468 + spl_puts("SPL: probing SPI flash\n");
1471 + ret = spl_spi_flash_probe(&sf);
1475 + spl_debug("SPL: reading image header at offset %lx\n", spl->data_addr);
1477 + ret = spi_flash_read(&sf, spl->data_addr, sizeof(hdr), &hdr);
1481 + spl_debug("SPL: checking image header at offset %lx\n", spl->data_addr);
1483 + ret = spl_parse_image(&hdr, spl);
1487 + if (spl_is_compressed(spl))
1488 + loadaddr = CONFIG_LOADADDR;
1490 + loadaddr = spl->entry_addr;
1492 + spl_puts("SPL: loading U-Boot to RAM\n");
1494 + ret = spi_flash_read(&sf, spl->data_addr, spl->data_size,
1495 + (void *) loadaddr);
1497 + if (!spl_check_data(spl, loadaddr))
1500 + if (spl_is_compressed(spl))
1501 + ret = spl_uncompress(spl, loadaddr);
1506 +static int spl_load_nor_flash(struct spl_image *spl)
1508 + const image_header_t *hdr;
1515 + * - 64 byte U-Boot mkimage header
1518 + spl->data_addr = image_copy_end();
1519 + hdr = (const image_header_t *) image_copy_end();
1521 + spl_debug("SPL: checking image header at address %p\n", hdr);
1523 + ret = spl_parse_image(hdr, spl);
1527 + if (spl_is_compressed(spl))
1528 + ret = spl_uncompress(spl, spl->data_addr);
1530 + ret = spl_copy_image(spl);
1535 +static int spl_load(struct spl_image *spl)
1539 + if (spl_boot_spi_flash)
1540 + ret = spl_load_spi_flash(spl);
1541 + else if (spl_boot_nor_flash)
1542 + ret = spl_load_nor_flash(spl);
1549 +void __noreturn spl_lantiq_init(void)
1551 + void (*uboot)(void) __noreturn;
1552 + struct spl_image spl;
1558 + memset((void *)gd, 0, sizeof(gd_t));
1560 + spl_console_init();
1562 + spl_debug("SPL: initializing\n");
1565 + spl_debug("CP0_CONFIG: %08x\n", read_c0_config());
1566 + spl_debug("CP0_CONFIG1: %08x\n", read_c0_config1());
1567 + spl_debug("CP0_CONFIG2: %08x\n", read_c0_config2());
1568 + spl_debug("CP0_CONFIG3: %08x\n", read_c0_config3());
1569 + spl_debug("CP0_CONFIG6: %08x\n", read_c0_config6());
1570 + spl_debug("CP0_CONFIG7: %08x\n", read_c0_config7());
1571 + spl_debug("CP0_STATUS: %08x\n", read_c0_status());
1572 + spl_debug("CP0_PRID: %08x\n", read_c0_prid());
1575 + board_early_init_f();
1578 + memset(&spl, 0, sizeof(spl));
1580 + ret = spl_load(&spl);
1584 + spl_debug("SPL: U-Boot entry %08lx\n", spl.entry_addr);
1585 + spl_puts("SPL: jumping to U-Boot\n");
1587 + flush_cache(spl.entry_addr, spl.entry_size);
1590 + uboot = (void *) spl.entry_addr;
1594 + spl_puts("SPL: cannot start U-Boot\n");
1600 +++ b/arch/mips/cpu/mips32/lantiq-common/start.S
1603 + * Copyright (C) 2010 Lantiq Deutschland GmbH
1604 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
1606 + * SPDX-License-Identifier: GPL-2.0+
1609 +#include <config.h>
1610 +#include <asm/regdef.h>
1611 +#include <asm/mipsregs.h>
1613 +#define S_PRIdCoID 16 /* Company ID (R) */
1614 +#define M_PRIdCoID (0xff << S_PRIdCoID)
1615 +#define S_PRIdImp 8 /* Implementation ID (R) */
1616 +#define M_PRIdImp (0xff << S_PRIdImp)
1618 +#define K_CacheAttrCWTnWA 0 /* Cacheable, write-thru, no write allocate */
1619 +#define K_CacheAttrCWTWA 1 /* Cacheable, write-thru, write allocate */
1620 +#define K_CacheAttrU 2 /* Uncached */
1621 +#define K_CacheAttrC 3 /* Cacheable */
1622 +#define K_CacheAttrCN 3 /* Cacheable, non-coherent */
1623 +#define K_CacheAttrCCE 4 /* Cacheable, coherent, exclusive */
1624 +#define K_CacheAttrCCS 5 /* Cacheable, coherent, shared */
1625 +#define K_CacheAttrCCU 6 /* Cacheable, coherent, update */
1626 +#define K_CacheAttrUA 7 /* Uncached accelerated */
1628 +#define S_ConfigK23 28 /* Kseg2/3 coherency algorithm (FM MMU only) (R/W) */
1629 +#define M_ConfigK23 (0x7 << S_ConfigK23)
1630 +#define W_ConfigK23 3
1631 +#define S_ConfigKU 25 /* Kuseg coherency algorithm (FM MMU only) (R/W) */
1632 +#define M_ConfigKU (0x7 << S_ConfigKU)
1633 +#define W_ConfigKU 3
1635 +#define S_ConfigMM 18 /* Merge mode (implementation specific) */
1636 +#define M_ConfigMM (0x1 << S_ConfigMM)
1638 +#define S_StatusBEV 22 /* Enable Boot Exception Vectors (R/W) */
1639 +#define M_StatusBEV (0x1 << S_StatusBEV)
1641 +#define S_StatusFR 26 /* Enable 64-bit FPRs (R/W) */
1642 +#define M_StatusFR (0x1 << S_StatusFR)
1644 +#define S_ConfigK0 0 /* Kseg0 coherency algorithm (R/W) */
1645 +#define M_ConfigK0 (0x7 << S_ConfigK0)
1647 +#define CONFIG0_MIPS32_64_MSK 0x8000ffff
1648 +#define STATUS_MIPS32_64_MSK 0xfffcffff
1650 +#define STATUS_MIPS24K 0
1651 +#define CONFIG0_MIPS24K ((K_CacheAttrCN << S_ConfigK23) |\
1652 + (K_CacheAttrCN << S_ConfigKU) |\
1655 +#define STATUS_MIPS34K 0
1656 +#define CONFIG0_MIPS34K ((K_CacheAttrCN << S_ConfigK23) |\
1657 + (K_CacheAttrCN << S_ConfigKU) |\
1660 +#define STATUS_MIPS32_64 (M_StatusBEV | M_StatusFR)
1661 +#define CONFIG0_MIPS32_64 (K_CacheAttrCN << S_ConfigK0)
1663 +#ifdef CONFIG_SOC_XWAY_DANUBE
1664 +#define CONFIG0_LANTIQ (CONFIG0_MIPS24K | CONFIG0_MIPS32_64)
1665 +#define STATUS_LANTIQ (STATUS_MIPS24K | STATUS_MIPS32_64)
1668 +#ifdef CONFIG_SOC_XWAY_VRX200
1669 +#define CONFIG0_LANTIQ (CONFIG0_MIPS34K | CONFIG0_MIPS32_64)
1670 +#define STATUS_LANTIQ (STATUS_MIPS34K | STATUS_MIPS32_64)
1683 + /* Lantiq SoC Boot config word */
1685 +#ifdef CONFIG_SYS_XWAY_EBU_BOOTCFG
1686 + .word CONFIG_SYS_XWAY_EBU_BOOTCFG
1696 + mtc0 zero, CP0_COUNT
1697 + mtc0 zero, CP0_COMPARE
1699 + /* Setup MIPS24K/MIPS34K specifics (implementation dependent fields) */
1700 + mfc0 t0, CP0_CONFIG
1701 + li t1, CONFIG0_MIPS32_64_MSK
1703 + li t1, CONFIG0_LANTIQ
1705 + mtc0 t0, CP0_CONFIG
1707 + mfc0 t0, CP0_STATUS
1708 + li t1, STATUS_MIPS32_64_MSK
1710 + li t1, STATUS_LANTIQ
1712 + mtc0 t0, CP0_STATUS
1714 + /* Initialize CGU */
1715 + la t9, ltq_cgu_init
1719 + /* Initialize memory controller */
1720 + la t9, ltq_mem_init
1724 + /* Initialize caches... */
1725 + la t9, mips_cache_reset
1730 + la t1, __bss_start
1738 + /* Setup stack pointer and force alignment on a 16 byte boundary */
1739 + li t0, (CONFIG_SPL_STACK_BASE & ~0xF)
1742 + la t9, spl_lantiq_init
1746 +++ b/arch/mips/cpu/mips32/lantiq-common/u-boot-spl.lds
1749 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
1751 + * SPDX-License-Identifier: GPL-2.0+
1754 +MEMORY { .spl_mem : ORIGIN = CONFIG_SPL_TEXT_BASE, \
1755 + LENGTH = CONFIG_SPL_MAX_SIZE }
1756 +MEMORY { .bss_mem : ORIGIN = CONFIG_SPL_BSS_BASE, \
1757 + LENGTH = CONFIG_SPL_BSS_MAX_SIZE }
1759 +OUTPUT_FORMAT("elf32-tradbigmips", "elf32-tradbigmips", "elf32-tradlittlemips")
1771 + *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*)))
1776 + *(SORT_BY_ALIGNMENT(.data*))
1777 + *(SORT_BY_ALIGNMENT(.sdata*))
1781 + __image_copy_end = .;
1782 + uboot_end_data = .;
1796 --- a/arch/mips/cpu/mips32/start.S
1797 +++ b/arch/mips/cpu/mips32/start.S
1798 @@ -105,7 +105,7 @@ reset:
1799 mtc0 zero, CP0_COUNT
1800 mtc0 zero, CP0_COMPARE
1802 -#ifndef CONFIG_SKIP_LOWLEVEL_INIT
1803 +#if !defined(CONFIG_SKIP_LOWLEVEL_INIT) || defined(CONFIG_SYS_DISABLE_CACHE)
1804 /* CONFIG0 register */
1805 li t0, CONF_CM_UNCACHED
1808 +++ b/arch/mips/cpu/mips32/vrx200/Makefile
1811 +# Copyright (C) 2000-2011 Wolfgang Denk, DENX Software Engineering, wd@denx.de
1813 +# SPDX-License-Identifier: GPL-2.0+
1816 +include $(TOPDIR)/config.mk
1818 +LIB = $(obj)lib$(SOC).o
1820 +COBJS-y += cgu.o chipid.o dcdc.o ebu.o gphy.o mem.o pmu.o rcu.o
1821 +SOBJS-y += cgu_init.o mem_init.o
1822 +SOBJS-y += gphy_fw.o
1824 +COBJS := $(COBJS-y)
1825 +SOBJS := $(SOBJS-y)
1826 +SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
1827 +OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
1831 +$(LIB): $(obj).depend $(OBJS)
1832 + $(call cmd_link_o_target, $(OBJS))
1834 +#########################################################################
1836 +# defines $(obj).depend target
1837 +include $(SRCTREE)/rules.mk
1839 +sinclude $(obj).depend
1841 +#########################################################################
1843 +++ b/arch/mips/cpu/mips32/vrx200/cgu.c
1846 + * Copyright (C) 2010 Lantiq Deutschland GmbH
1847 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
1849 + * SPDX-License-Identifier: GPL-2.0+
1852 +#include <common.h>
1853 +#include <asm/arch/soc.h>
1854 +#include <asm/arch/gphy.h>
1855 +#include <asm/lantiq/clk.h>
1856 +#include <asm/lantiq/io.h>
1858 +#define LTQ_CGU_PLL1_PLLN_SHIFT 6
1859 +#define LTQ_CGU_PLL1_PLLN_MASK (0x3F << LTQ_CGU_PLL1_PLLN_SHIFT)
1860 +#define LTQ_CGU_PLL1_PLLM_SHIFT 2
1861 +#define LTQ_CGU_PLL1_PLLM_MASK (0xF << LTQ_CGU_PLL1_PLLM_SHIFT)
1862 +#define LTQ_CGU_PLL1_PLLL (1 << 1)
1863 +#define LTQ_CGU_PLL1_PLL_EN 1
1865 +#define LTQ_CGU_SYS_OCP_SHIFT 0
1866 +#define LTQ_CGU_SYS_OCP_MASK (0x3 << LTQ_CGU_SYS_OCP_SHIFT)
1867 +#define LTQ_CGU_SYS_CPU_SHIFT 4
1868 +#define LTQ_CGU_SYS_CPU_MASK (0xF << LTQ_CGU_SYS_CPU_SHIFT)
1870 +#define LTQ_CGU_UPDATE 1
1872 +#define LTQ_CGU_IFCLK_GPHY_SEL_SHIFT 2
1873 +#define LTQ_CGU_IFCLK_GPHY_SEL_MASK (0x7 << LTQ_CGU_IFCLK_GPHY_SEL_SHIFT)
1875 +struct ltq_cgu_regs {
1877 + u32 pll0_cfg; /* PLL0 config */
1878 + u32 pll1_cfg; /* PLL1 config */
1879 + u32 sys; /* System clock */
1880 + u32 clk_fsr; /* Clock frequency select */
1881 + u32 clk_gsr; /* Clock gating status */
1882 + u32 clk_gcr0; /* Clock gating control 0 */
1883 + u32 clk_gcr1; /* Clock gating control 1 */
1884 + u32 update; /* CGU update control */
1885 + u32 if_clk; /* Interface clock */
1886 + u32 ddr; /* DDR memory control */
1887 + u32 ct1_sr; /* CT status 1 */
1888 + u32 ct_kval; /* CT K value */
1889 + u32 pcm_cr; /* PCM control */
1890 + u32 pci_cr; /* PCI clock control */
1892 + u32 gphy1_cfg; /* GPHY1 config */
1893 + u32 gphy0_cfg; /* GPHY0 config */
1895 + u32 pll2_cfg; /* PLL2 config */
1898 +static struct ltq_cgu_regs *ltq_cgu_regs =
1899 + (struct ltq_cgu_regs *) CKSEG1ADDR(LTQ_CGU_BASE);
1901 +static inline u32 ltq_cgu_sys_readl(u32 mask, u32 shift)
1903 + return (ltq_readl(<q_cgu_regs->sys) & mask) >> shift;
1906 +unsigned long ltq_get_io_region_clock(void)
1908 + unsigned int ocp_sel;
1909 + unsigned long clk, cpu_clk;
1911 + cpu_clk = ltq_get_cpu_clock();
1913 + ocp_sel = ltq_cgu_sys_readl(LTQ_CGU_SYS_OCP_MASK,
1914 + LTQ_CGU_SYS_OCP_SHIFT);
1916 + switch (ocp_sel) {
1923 + clk = cpu_clk / 2;
1926 + /* OCP ratio 2.5 */
1927 + clk = (cpu_clk * 2) / 5;
1931 + clk = cpu_clk / 3;
1941 +unsigned long ltq_get_cpu_clock(void)
1943 + unsigned int cpu_sel;
1944 + unsigned long clk;
1946 + cpu_sel = ltq_cgu_sys_readl(LTQ_CGU_SYS_CPU_MASK,
1947 + LTQ_CGU_SYS_CPU_SHIFT);
1949 + switch (cpu_sel) {
1951 + clk = CLOCK_600_MHZ;
1954 + clk = CLOCK_500_MHZ;
1957 + clk = CLOCK_393_MHZ;
1960 + clk = CLOCK_333_MHZ;
1964 + clk = CLOCK_197_MHZ;
1967 + clk = CLOCK_166_MHZ;
1972 + clk = CLOCK_125_MHZ;
1982 +unsigned long ltq_get_bus_clock(void)
1984 + return ltq_get_io_region_clock();
1987 +void ltq_cgu_gphy_clk_src(enum ltq_gphy_clk clk)
1989 + ltq_clrbits(<q_cgu_regs->if_clk, LTQ_CGU_IFCLK_GPHY_SEL_MASK);
1990 + ltq_setbits(<q_cgu_regs->if_clk, clk << LTQ_CGU_IFCLK_GPHY_SEL_SHIFT);
1993 +static inline int ltq_cgu_pll1_locked(void)
1995 + u32 pll1_cfg = ltq_readl(<q_cgu_regs->pll1_cfg);
1997 + return pll1_cfg & LTQ_CGU_PLL1_PLLL;
2000 +static inline void ltq_cgu_pll1_restart(unsigned m, unsigned n)
2004 + ltq_clrbits(<q_cgu_regs->pll1_cfg, LTQ_CGU_PLL1_PLL_EN);
2005 + ltq_setbits(<q_cgu_regs->update, LTQ_CGU_UPDATE);
2007 + pll1_cfg = ltq_readl(<q_cgu_regs->pll1_cfg);
2008 + pll1_cfg &= ~(LTQ_CGU_PLL1_PLLN_MASK | LTQ_CGU_PLL1_PLLM_MASK);
2009 + pll1_cfg |= n << LTQ_CGU_PLL1_PLLN_SHIFT;
2010 + pll1_cfg |= m << LTQ_CGU_PLL1_PLLM_SHIFT;
2011 + pll1_cfg |= LTQ_CGU_PLL1_PLL_EN;
2012 + ltq_writel(<q_cgu_regs->pll1_cfg, pll1_cfg);
2013 + ltq_setbits(<q_cgu_regs->update, LTQ_CGU_UPDATE);
2019 + * From chapter 9 in errata sheet:
2021 + * Under certain condition, the PLL1 may failed to enter into lock
2022 + * status by hardware default N, M setting.
2024 + * Since system always starts from PLL0, the system software can run
2025 + * and re-program the PLL1 settings.
2027 +static void ltq_cgu_pll1_init(void)
2030 + const unsigned pll1_m[] = { 1, 2, 3, 4 };
2031 + const unsigned pll1_n[] = { 21, 32, 43, 54 };
2033 + /* Check if PLL1 has locked with hardware default settings */
2034 + if (ltq_cgu_pll1_locked())
2037 + for (i = 0; i < 4; i++) {
2038 + ltq_cgu_pll1_restart(pll1_m[i], pll1_n[i]);
2040 + if (ltq_cgu_pll1_locked())
2045 + /* Restart with hardware default values M=5, N=64 */
2046 + ltq_cgu_pll1_restart(5, 64);
2049 +void ltq_pll_init(void)
2051 + ltq_cgu_pll1_init();
2054 +++ b/arch/mips/cpu/mips32/vrx200/cgu_init.S
2057 + * Copyright (C) 2010 Lantiq Deutschland GmbH
2058 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
2060 + * SPDX-License-Identifier: GPL-2.0+
2063 +#include <config.h>
2064 +#include <asm/asm.h>
2065 +#include <asm/regdef.h>
2066 +#include <asm/addrspace.h>
2067 +#include <asm/arch/soc.h>
2069 +/* RCU module register */
2070 +#define LTQ_RCU_RST_REQ 0x0010 /* Reset request */
2071 +#define LTQ_RCU_RST_REQ_VALUE ((1 << 14) | (1 << 1))
2073 +/* CGU module register */
2074 +#define LTQ_CGU_PLL0_CFG 0x0004 /* PLL0 config */
2075 +#define LTQ_CGU_PLL1_CFG 0x0008 /* PLL1 config */
2076 +#define LTQ_CGU_PLL2_CFG 0x0060 /* PLL2 config */
2077 +#define LTQ_CGU_SYS 0x000C /* System clock */
2078 +#define LTQ_CGU_CLK_FSR 0x0010 /* Clock frequency select */
2079 +#define LTQ_CGU_UPDATE 0x0020 /* Clock update control */
2081 +/* Valid SYS.CPU values */
2082 +#define LTQ_CGU_SYS_CPU_SHIFT 4
2083 +#define LTQ_CGU_SYS_CPU_600_MHZ 0x0
2084 +#define LTQ_CGU_SYS_CPU_500_MHZ 0x1
2085 +#define LTQ_CGU_SYS_CPU_393_MHZ 0x2
2086 +#define LTQ_CGU_SYS_CPU_333_MHZ 0x3
2087 +#define LTQ_CGU_SYS_CPU_197_MHZ 0x5
2088 +#define LTQ_CGU_SYS_CPU_166_MHZ 0x7
2089 +#define LTQ_CGU_SYS_CPU_125_MHZ 0x9
2091 +/* Valid SYS.OCP values */
2092 +#define LTQ_CGU_SYS_OCP_SHIFT 0
2093 +#define LTQ_CGU_SYS_OCP_1 0x0
2094 +#define LTQ_CGU_SYS_OCP_2 0x2
2095 +#define LTQ_CGU_SYS_OCP_2_5 0x3
2096 +#define LTQ_CGU_SYS_OCP_3 0x4
2098 +/* Valid CLK_FSR.ETH values */
2099 +#define LTQ_CGU_CLK_FSR_ETH_SHIFT 24
2100 +#define LTQ_CGU_CLK_FSR_ETH_50_MHZ 0x0
2101 +#define LTQ_CGU_CLK_FSR_ETH_25_MHZ 0x1
2102 +#define LTQ_CGU_CLK_FSR_ETH_2_5_MHZ 0x2
2103 +#define LTQ_CGU_CLK_FSR_ETH_125_MHZ 0x3
2105 +/* Valid CLK_FSR.PPE values */
2106 +#define LTQ_CGU_CLK_FSR_PPE_SHIFT 16
2107 +#define LTQ_CGU_CLK_FSR_PPE_500_MHZ 0x0 /* Overclock frequency */
2108 +#define LTQ_CGU_CLK_FSR_PPE_450_MHZ 0x1 /* High frequency */
2109 +#define LTQ_CGU_CLK_FSR_PPE_400_MHZ 0x2 /* Low frequency */
2111 +#if (CONFIG_SYS_CLOCK_MODE == LTQ_CLK_CPU_500_DDR_250)
2112 +#define LTQ_CGU_SYS_CPU_CONFIG LTQ_CGU_SYS_CPU_500_MHZ
2113 +#define LTQ_CGU_SYS_OCP_CONFIG LTQ_CGU_SYS_OCP_2
2114 +#define LTQ_CGU_CLK_FSR_ETH_CONFIG LTQ_CGU_CLK_FSR_ETH_125_MHZ
2115 +#define LTQ_CGU_CLK_FSR_PPE_CONFIG LTQ_CGU_CLK_FSR_PPE_450_MHZ
2117 +#error "Invalid system clock configuration!"
2120 +/* Build register values */
2121 +#define LTQ_CGU_SYS_VALUE ((LTQ_CGU_SYS_CPU_CONFIG << \
2122 + LTQ_CGU_SYS_CPU_SHIFT) | \
2123 + LTQ_CGU_SYS_OCP_CONFIG)
2125 +#define LTQ_CGU_CLK_FSR_VALUE ((LTQ_CGU_CLK_FSR_ETH_CONFIG << \
2126 + LTQ_CGU_CLK_FSR_ETH_SHIFT) | \
2127 + (LTQ_CGU_CLK_FSR_PPE_CONFIG << \
2128 + LTQ_CGU_CLK_FSR_PPE_SHIFT))
2133 + /* Load current CGU register values */
2134 + li t0, (LTQ_CGU_BASE | KSEG1)
2135 + lw t1, LTQ_CGU_SYS(t0)
2136 + lw t2, LTQ_CGU_CLK_FSR(t0)
2138 + /* Load target CGU register values */
2139 + li t3, LTQ_CGU_SYS_VALUE
2140 + li t4, LTQ_CGU_CLK_FSR_VALUE
2142 + /* Only update registers if values differ */
2143 + bne t1, t3, update
2145 + beq t2, t4, finished
2149 + /* Store target register values */
2150 + sw t3, LTQ_CGU_SYS(t0)
2151 + sw t4, LTQ_CGU_CLK_FSR(t0)
2153 + /* Perform software reset to activate new clock config */
2155 + li t0, (LTQ_RCU_BASE | KSEG1)
2156 + lw t1, LTQ_RCU_RST_REQ(t0)
2157 + or t1, LTQ_RCU_RST_REQ_VALUE
2158 + sw t1, LTQ_RCU_RST_REQ(t0)
2161 + sw t1, LTQ_CGU_UPDATE(t0)
2176 +++ b/arch/mips/cpu/mips32/vrx200/chipid.c
2179 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
2181 + * SPDX-License-Identifier: GPL-2.0+
2184 +#include <common.h>
2185 +#include <asm/lantiq/io.h>
2186 +#include <asm/lantiq/chipid.h>
2187 +#include <asm/arch/soc.h>
2189 +#define LTQ_CHIPID_VERSION_SHIFT 28
2190 +#define LTQ_CHIPID_VERSION_MASK (0x7 << LTQ_CHIPID_VERSION_SHIFT)
2191 +#define LTQ_CHIPID_PNUM_SHIFT 12
2192 +#define LTQ_CHIPID_PNUM_MASK (0xFFFF << LTQ_CHIPID_PNUM_SHIFT)
2194 +struct ltq_chipid_regs {
2195 + u32 manid; /* Manufacturer identification */
2196 + u32 chipid; /* Chip identification */
2199 +static struct ltq_chipid_regs *ltq_chipid_regs =
2200 + (struct ltq_chipid_regs *) CKSEG1ADDR(LTQ_CHIPID_BASE);
2202 +unsigned int ltq_chip_version_get(void)
2206 + chipid = ltq_readl(<q_chipid_regs->chipid);
2208 + return (chipid & LTQ_CHIPID_VERSION_MASK) >> LTQ_CHIPID_VERSION_SHIFT;
2211 +unsigned int ltq_chip_partnum_get(void)
2215 + chipid = ltq_readl(<q_chipid_regs->chipid);
2217 + return (chipid & LTQ_CHIPID_PNUM_MASK) >> LTQ_CHIPID_PNUM_SHIFT;
2220 +const char *ltq_chip_partnum_str(void)
2222 + enum ltq_chip_partnum partnum = ltq_chip_partnum_get();
2224 + switch (partnum) {
2225 + case LTQ_SOC_VRX268:
2226 + case LTQ_SOC_VRX268_2:
2228 + case LTQ_SOC_VRX288:
2229 + case LTQ_SOC_VRX288_2:
2231 + case LTQ_SOC_GRX288:
2232 + case LTQ_SOC_GRX288_2:
2235 + printf("Unknown partnum: %x\n", partnum);
2241 +++ b/arch/mips/cpu/mips32/vrx200/config.mk
2244 +# Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
2246 +# SPDX-License-Identifier: GPL-2.0+
2249 +PF_CPPFLAGS_XRX := $(call cc-option,-mtune=34kc,)
2250 +PLATFORM_CPPFLAGS += $(PF_CPPFLAGS_XRX)
2252 +ifdef CONFIG_SPL_BUILD
2253 +PF_ABICALLS := -mno-abicalls
2256 +USE_PRIVATE_LIBGCC := yes
2259 +LIBS-y += $(CPUDIR)/lantiq-common/liblantiq-common.o
2261 +ifndef CONFIG_SPL_BUILD
2262 +ifdef CONFIG_SYS_BOOT_SFSPL
2263 +ALL-y += $(obj)u-boot.ltq.sfspl
2264 +ALL-$(CONFIG_SPL_LZO_SUPPORT) += $(obj)u-boot.ltq.lzo.sfspl
2265 +ALL-$(CONFIG_SPL_LZMA_SUPPORT) += $(obj)u-boot.ltq.lzma.sfspl
2267 +ifdef CONFIG_SYS_BOOT_NORSPL
2268 +ALL-y += $(obj)u-boot.ltq.norspl
2269 +ALL-$(CONFIG_SPL_LZO_SUPPORT) += $(obj)u-boot.ltq.lzo.norspl
2270 +ALL-$(CONFIG_SPL_LZMA_SUPPORT) += $(obj)u-boot.ltq.lzma.norspl
2274 +++ b/arch/mips/cpu/mips32/vrx200/dcdc.c
2277 + * Copyright (C) 2010 Lantiq Deutschland GmbH
2278 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
2280 + * SPDX-License-Identifier: GPL-2.0+
2283 +#include <common.h>
2284 +#include <asm/arch/soc.h>
2285 +#include <asm/lantiq/io.h>
2287 +#define LTQ_DCDC_CLK_SET0_CLK_SEL_P (1 << 6)
2288 +#define LTQ_DCDC_CLK_SET1_SEL_DIV25 (1 << 5)
2289 +#define LTQ_DCDC_CONF_TEST_DIG_PID_FREEZE (1 << 5)
2291 +struct ltq_dcdc_regs {
2292 + u8 b0_coeh; /* Coefficient b0 */
2293 + u8 b0_coel; /* Coefficient b0 */
2294 + u8 b1_coeh; /* Coefficient b1 */
2295 + u8 b1_coel; /* Coefficient b1 */
2296 + u8 b2_coeh; /* Coefficient b2 */
2297 + u8 b2_coel; /* Coefficient b2 */
2298 + u8 clk_set0; /* Clock setup */
2299 + u8 clk_set1; /* Clock setup */
2300 + u8 pwm_confh; /* Configure PWM */
2301 + u8 pwm_confl; /* Configure PWM */
2302 + u8 bias_vreg0; /* Bias and regulator setup */
2303 + u8 bias_vreg1; /* Bias and regulator setup */
2304 + u8 adc_gen0; /* ADC and general control */
2305 + u8 adc_gen1; /* ADC and general control */
2306 + u8 adc_con0; /* ADC and general config */
2307 + u8 adc_con1; /* ADC and general config */
2308 + u8 conf_test_ana; /* not documented */
2309 + u8 conf_test_dig; /* not documented */
2310 + u8 dcdc_status; /* not documented */
2311 + u8 pid_status; /* not documented */
2312 + u8 duty_cycle; /* not documented */
2313 + u8 non_ov_delay; /* not documented */
2314 + u8 analog_gain; /* not documented */
2315 + u8 duty_cycle_max_sat; /* not documented */
2316 + u8 duty_cycle_min_sat; /* not documented */
2317 + u8 duty_cycle_max; /* not documented */
2318 + u8 duty_cycle_min; /* not documented */
2319 + u8 error_max; /* not documented */
2320 + u8 error_read; /* not documented */
2321 + u8 delay_deglitch; /* not documented */
2322 + u8 latch_control; /* not documented */
2324 + u8 osc_conf; /* OSC general config */
2325 + u8 osc_stat; /* OSC general status */
2328 +static struct ltq_dcdc_regs *ltq_dcdc_regs =
2329 + (struct ltq_dcdc_regs *) CKSEG1ADDR(LTQ_DCDC_BASE);
2331 +void ltq_dcdc_init(unsigned int dig_ref)
2333 + u8 dig_ref_cur, val;
2335 + /* Set duty cycle max sat. to 70/90, enable PID freeze */
2336 + ltq_writeb(<q_dcdc_regs->duty_cycle_max_sat, 0x5A);
2337 + ltq_writeb(<q_dcdc_regs->duty_cycle_min_sat, 0x46);
2338 + val = ltq_readb(<q_dcdc_regs->conf_test_dig);
2339 + val |= LTQ_DCDC_CONF_TEST_DIG_PID_FREEZE;
2340 + ltq_writeb(<q_dcdc_regs->conf_test_dig, val);
2342 + /* Program new coefficients */
2343 + ltq_writeb(<q_dcdc_regs->b0_coeh, 0x00);
2344 + ltq_writeb(<q_dcdc_regs->b0_coel, 0x00);
2345 + ltq_writeb(<q_dcdc_regs->b1_coeh, 0xFF);
2346 + ltq_writeb(<q_dcdc_regs->b1_coel, 0xE6);
2347 + ltq_writeb(<q_dcdc_regs->b2_coeh, 0x00);
2348 + ltq_writeb(<q_dcdc_regs->b2_coel, 0x1B);
2349 + ltq_writeb(<q_dcdc_regs->non_ov_delay, 0x8B);
2351 + /* Set duty cycle max sat. to 60/108, disable PID freeze */
2352 + ltq_writeb(<q_dcdc_regs->duty_cycle_max_sat, 0x6C);
2353 + ltq_writeb(<q_dcdc_regs->duty_cycle_min_sat, 0x3C);
2354 + val = ltq_readb(<q_dcdc_regs->conf_test_dig);
2355 + val &= ~LTQ_DCDC_CONF_TEST_DIG_PID_FREEZE;
2356 + ltq_writeb(<q_dcdc_regs->conf_test_dig, val);
2358 + /* Init clock and DLL settings */
2359 + val = ltq_readb(<q_dcdc_regs->clk_set0);
2360 + val |= LTQ_DCDC_CLK_SET0_CLK_SEL_P;
2361 + ltq_writeb(<q_dcdc_regs->clk_set0, val);
2362 + val = ltq_readb(<q_dcdc_regs->clk_set1);
2363 + val |= LTQ_DCDC_CLK_SET1_SEL_DIV25;
2364 + ltq_writeb(<q_dcdc_regs->clk_set1, val);
2365 + ltq_writeb(<q_dcdc_regs->pwm_confh, 0xF9);
2369 + /* Adapt value of digital reference of DCDC converter */
2370 + dig_ref_cur = ltq_readb(<q_dcdc_regs->bias_vreg1);
2372 + while (dig_ref_cur != dig_ref) {
2373 + if (dig_ref >= dig_ref_cur)
2375 + else if (dig_ref < dig_ref_cur)
2378 + ltq_writeb(<q_dcdc_regs->bias_vreg1, dig_ref_cur);
2383 +++ b/arch/mips/cpu/mips32/vrx200/ebu.c
2386 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
2388 + * SPDX-License-Identifier: GPL-2.0+
2391 +#include <common.h>
2392 +#include <asm/arch/soc.h>
2393 +#include <asm/lantiq/io.h>
2395 +#define EBU_ADDRSEL_MASK(mask) ((mask & 0xf) << 4)
2396 +#define EBU_ADDRSEL_REGEN (1 << 0)
2398 +#define EBU_CON_WRDIS (1 << 31)
2399 +#define EBU_CON_AGEN_DEMUX (0x0 << 24)
2400 +#define EBU_CON_AGEN_MUX (0x2 << 24)
2401 +#define EBU_CON_SETUP (1 << 22)
2402 +#define EBU_CON_WAIT_DIS (0x0 << 20)
2403 +#define EBU_CON_WAIT_ASYNC (0x1 << 20)
2404 +#define EBU_CON_WAIT_SYNC (0x2 << 20)
2405 +#define EBU_CON_WINV (1 << 19)
2406 +#define EBU_CON_PW_8BIT (0x0 << 16)
2407 +#define EBU_CON_PW_16BIT (0x1 << 16)
2408 +#define EBU_CON_ALEC(cycles) ((cycles & 0x3) << 14)
2409 +#define EBU_CON_BCGEN_CS (0x0 << 12)
2410 +#define EBU_CON_BCGEN_INTEL (0x1 << 12)
2411 +#define EBU_CON_BCGEN_MOTOROLA (0x2 << 12)
2412 +#define EBU_CON_WAITWRC(cycles) ((cycles & 0x7) << 8)
2413 +#define EBU_CON_WAITRDC(cycles) ((cycles & 0x3) << 6)
2414 +#define EBU_CON_HOLDC(cycles) ((cycles & 0x3) << 4)
2415 +#define EBU_CON_RECOVC(cycles) ((cycles & 0x3) << 2)
2416 +#define EBU_CON_CMULT_1 0x0
2417 +#define EBU_CON_CMULT_4 0x1
2418 +#define EBU_CON_CMULT_8 0x2
2419 +#define EBU_CON_CMULT_16 0x3
2421 +#if defined(CONFIG_LTQ_SUPPORT_NOR_FLASH)
2422 +#define ebu_region0_enable 1
2424 +#define ebu_region0_enable 0
2427 +#if defined(CONFIG_LTQ_SUPPORT_NAND_FLASH)
2428 +#define ebu_region1_enable 1
2430 +#define ebu_region1_enable 0
2433 +struct ltq_ebu_regs {
2451 +static struct ltq_ebu_regs *ltq_ebu_regs =
2452 + (struct ltq_ebu_regs *) CKSEG1ADDR(LTQ_EBU_BASE);
2454 +void ltq_ebu_init(void)
2456 + if (ebu_region0_enable) {
2458 + * Map EBU region 0 to range 0x10000000-0x13ffffff and enable
2459 + * region control. This supports up to 32 MiB NOR flash in
2462 + ltq_writel(<q_ebu_regs->addr_sel_0, LTQ_EBU_REGION0_BASE |
2463 + EBU_ADDRSEL_MASK(1) | EBU_ADDRSEL_REGEN);
2465 + ltq_writel(<q_ebu_regs->con_0, EBU_CON_AGEN_DEMUX |
2466 + EBU_CON_WAIT_DIS | EBU_CON_PW_16BIT |
2467 + EBU_CON_ALEC(3) | EBU_CON_BCGEN_INTEL |
2468 + EBU_CON_WAITWRC(7) | EBU_CON_WAITRDC(3) |
2469 + EBU_CON_HOLDC(3) | EBU_CON_RECOVC(3) |
2470 + EBU_CON_CMULT_16);
2472 + ltq_clrbits(<q_ebu_regs->addr_sel_0, EBU_ADDRSEL_REGEN);
2474 + if (ebu_region1_enable) {
2476 + * Map EBU region 1 to range 0x14000000-0x13ffffff and enable
2477 + * region control. This supports NAND flash in bank 1.
2479 + ltq_writel(<q_ebu_regs->addr_sel_1, LTQ_EBU_REGION1_BASE |
2480 + EBU_ADDRSEL_MASK(3) | EBU_ADDRSEL_REGEN);
2482 + ltq_writel(<q_ebu_regs->con_1, EBU_CON_AGEN_DEMUX |
2483 + EBU_CON_SETUP | EBU_CON_WAIT_DIS | EBU_CON_PW_8BIT |
2484 + EBU_CON_ALEC(3) | EBU_CON_BCGEN_INTEL |
2485 + EBU_CON_WAITWRC(2) | EBU_CON_WAITRDC(2) |
2486 + EBU_CON_HOLDC(1) | EBU_CON_RECOVC(1) |
2489 + ltq_clrbits(<q_ebu_regs->addr_sel_1, EBU_ADDRSEL_REGEN);
2492 +void *flash_swap_addr(unsigned long addr)
2494 + return (void *)(addr ^ 2);
2497 +++ b/arch/mips/cpu/mips32/vrx200/gphy.c
2500 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
2502 + * SPDX-License-Identifier: GPL-2.0+
2505 +#include <common.h>
2506 +#include <asm/lantiq/io.h>
2507 +#include <asm/arch/soc.h>
2508 +#include <asm/arch/gphy.h>
2510 +static inline void ltq_gphy_copy(const void *fw_start, const void *fw_end,
2513 + const ulong fw_len = (ulong) fw_end - (ulong) fw_start;
2514 + const ulong addr = CKSEG1ADDR(dst_addr);
2516 + debug("ltq_gphy_copy: addr %08lx, fw_start %p, fw_end %p\n",
2517 + addr, fw_start, fw_end);
2519 + memcpy((void *) addr, fw_start, fw_len);
2522 +void ltq_gphy_phy11g_a1x_load(ulong addr)
2524 + extern ulong __ltq_fw_phy11g_a1x_start;
2525 + extern ulong __ltq_fw_phy11g_a1x_end;
2527 + ltq_gphy_copy(&__ltq_fw_phy11g_a1x_start, &__ltq_fw_phy11g_a1x_end,
2531 +void ltq_gphy_phy11g_a2x_load(ulong addr)
2533 + extern ulong __ltq_fw_phy11g_a2x_start;
2534 + extern ulong __ltq_fw_phy11g_a2x_end;
2536 + ltq_gphy_copy(&__ltq_fw_phy11g_a2x_start, &__ltq_fw_phy11g_a2x_end,
2540 +void ltq_gphy_phy22f_a1x_load(ulong addr)
2542 + extern ulong __ltq_fw_phy22f_a1x_start;
2543 + extern ulong __ltq_fw_phy22f_a1x_end;
2545 + ltq_gphy_copy(&__ltq_fw_phy22f_a1x_start, &__ltq_fw_phy22f_a1x_end,
2549 +void ltq_gphy_phy22f_a2x_load(ulong addr)
2551 + extern ulong __ltq_fw_phy22f_a2x_start;
2552 + extern ulong __ltq_fw_phy22f_a2x_end;
2554 + ltq_gphy_copy(&__ltq_fw_phy22f_a2x_start, &__ltq_fw_phy22f_a2x_end,
2558 +++ b/arch/mips/cpu/mips32/vrx200/gphy_fw.S
2561 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
2563 + * SPDX-License-Identifier: GPL-2.0+
2566 +#include <asm/asm.h>
2568 + .section .rodata.__ltq_fw_phy11g_a1x
2569 +EXPORT(__ltq_fw_phy11g_a1x_start)
2570 + .incbin "fw_phy11g_a1x.blob"
2571 +EXPORT(__ltq_fw_phy11g_a1x_end)
2573 + .section .rodata.__ltq_fw_phy11g_a2x
2574 +EXPORT(__ltq_fw_phy11g_a2x_start)
2575 + .incbin "fw_phy11g_a2x.blob"
2576 +EXPORT(__ltq_fw_phy11g_a2x_end)
2578 + .section .rodata.__ltq_fw_phy22f_a1x
2579 +EXPORT(__ltq_fw_phy22f_a1x_start)
2580 + .incbin "fw_phy22f_a1x.blob"
2581 +EXPORT(__ltq_fw_phy22f_a1x_end)
2583 + .section .rodata.__ltq_fw_phy22f_a2x
2584 +EXPORT(__ltq_fw_phy22f_a2x_start)
2585 + .incbin "fw_phy22f_a2x.blob"
2586 +EXPORT(__ltq_fw_phy22f_a2x_end)
2588 +++ b/arch/mips/cpu/mips32/vrx200/mem.c
2591 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
2593 + * SPDX-License-Identifier: GPL-2.0+
2596 +#include <common.h>
2597 +#include <asm/arch/soc.h>
2598 +#include <asm/lantiq/io.h>
2600 +#define LTQ_CCR03_EIGHT_BANK_MODE (1 << 0)
2601 +#define LTQ_CCR08_CS_MAP_SHIFT 24
2602 +#define LTQ_CCR08_CS_MAP_MASK (0x3 << LTQ_CCR08_CS_MAP_SHIFT)
2603 +#define LTQ_CCR11_COLUMN_SIZE_SHIFT 24
2604 +#define LTQ_CCR11_COLUMN_SIZE_MASK (0x7 << LTQ_CCR11_COLUMN_SIZE_SHIFT)
2605 +#define LTQ_CCR11_ADDR_PINS_MASK 0x7
2606 +#define LTQ_CCR15_MAX_COL_REG_SHIFT 24
2607 +#define LTQ_CCR15_MAX_COL_REG_MASK (0xF << LTQ_CCR15_MAX_COL_REG_SHIFT)
2608 +#define LTQ_CCR16_MAX_ROW_REG_MASK 0xF
2610 +static void *ltq_mc_ddr_base = (void *) CKSEG1ADDR(LTQ_MC_DDR_BASE);
2612 +static inline u32 ltq_mc_ccr_read(u32 index)
2614 + return ltq_readl(ltq_mc_ddr_base + LTQ_MC_DDR_CCR_OFFSET(index));
2617 +phys_size_t initdram(int board_type)
2619 + u32 max_col_reg, max_row_reg, column_size, addr_pins;
2620 + u32 banks, cs_map;
2623 + banks = (ltq_mc_ccr_read(3) & LTQ_CCR03_EIGHT_BANK_MODE) ? 8 : 4;
2625 + cs_map = (ltq_mc_ccr_read(8) & LTQ_CCR08_CS_MAP_MASK) >>
2626 + LTQ_CCR08_CS_MAP_SHIFT;
2628 + column_size = (ltq_mc_ccr_read(11) & LTQ_CCR11_COLUMN_SIZE_MASK) >>
2629 + LTQ_CCR11_COLUMN_SIZE_SHIFT;
2631 + addr_pins = ltq_mc_ccr_read(11) & LTQ_CCR11_ADDR_PINS_MASK;
2633 + max_col_reg = (ltq_mc_ccr_read(15) & LTQ_CCR15_MAX_COL_REG_MASK) >>
2634 + LTQ_CCR15_MAX_COL_REG_SHIFT;
2636 + max_row_reg = ltq_mc_ccr_read(16) & LTQ_CCR16_MAX_ROW_REG_MASK;
2639 + * size (bytes) = 2 ^ rowsize * 2 ^ colsize * banks * chipselects
2640 + * * datawidth (bytes)
2642 + size = (2 << (max_col_reg - column_size - 1)) *
2643 + (2 << (max_row_reg - addr_pins - 1)) * banks * cs_map * 2;
2648 +++ b/arch/mips/cpu/mips32/vrx200/mem_init.S
2651 + * Copyright (C) 2010 Lantiq Deutschland GmbH
2652 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
2654 + * SPDX-License-Identifier: GPL-2.0+
2657 +#include <config.h>
2658 +#include <asm/asm.h>
2659 +#include <asm/regdef.h>
2660 +#include <asm/addrspace.h>
2661 +#include <asm/arch/soc.h>
2663 +/* Must be configured in BOARDDIR */
2664 +#include <ddr_settings.h>
2666 +#define LTQ_MC_DDR_START (1 << 8)
2667 +#define LTQ_MC_DDR_DLL_LOCK_IND 1
2669 +#define CCS_ALWAYS_LAST 0x0430
2670 +#define CCS_AHBM_CR_BURST_EN (1 << 2)
2671 +#define CCS_FPIM_CR_BURST_EN (1 << 1)
2673 +#define CCR03_EIGHT_BANK_MODE (1 << 0)
2675 + /* Store given value in MC DDR CCRx register */
2676 + .macro ccr_sw num, val
2678 + sw t1, LTQ_MC_DDR_CCR_OFFSET(\num)(t0)
2682 + /* Load MC DDR module base */
2683 + li t0, (LTQ_MC_DDR_BASE | KSEG1)
2685 + /* Put memory controller in inactive mode */
2686 + sw zero, LTQ_MC_DDR_CCR_OFFSET(7)(t0)
2688 + /* Init MC DDR CCR registers with values from ddr_settings.h */
2689 + ccr_sw 0, MC_CCR00_VALUE
2690 + ccr_sw 1, MC_CCR01_VALUE
2691 + ccr_sw 2, MC_CCR02_VALUE
2692 + ccr_sw 3, MC_CCR03_VALUE
2693 + ccr_sw 4, MC_CCR04_VALUE
2694 + ccr_sw 5, MC_CCR05_VALUE
2695 + ccr_sw 6, MC_CCR06_VALUE
2696 + ccr_sw 7, MC_CCR07_VALUE
2697 + ccr_sw 8, MC_CCR08_VALUE
2698 + ccr_sw 9, MC_CCR09_VALUE
2700 + ccr_sw 10, MC_CCR10_VALUE
2701 + ccr_sw 11, MC_CCR11_VALUE
2702 + ccr_sw 12, MC_CCR12_VALUE
2703 + ccr_sw 13, MC_CCR13_VALUE
2704 + ccr_sw 14, MC_CCR14_VALUE
2705 + ccr_sw 15, MC_CCR15_VALUE
2706 + ccr_sw 16, MC_CCR16_VALUE
2707 + ccr_sw 17, MC_CCR17_VALUE
2708 + ccr_sw 18, MC_CCR18_VALUE
2709 + ccr_sw 19, MC_CCR19_VALUE
2711 + ccr_sw 20, MC_CCR20_VALUE
2712 + ccr_sw 21, MC_CCR21_VALUE
2713 + ccr_sw 22, MC_CCR22_VALUE
2714 + ccr_sw 23, MC_CCR23_VALUE
2715 + ccr_sw 24, MC_CCR24_VALUE
2716 + ccr_sw 25, MC_CCR25_VALUE
2717 + ccr_sw 26, MC_CCR26_VALUE
2718 + ccr_sw 27, MC_CCR27_VALUE
2719 + ccr_sw 28, MC_CCR28_VALUE
2720 + ccr_sw 29, MC_CCR29_VALUE
2722 + ccr_sw 30, MC_CCR30_VALUE
2723 + ccr_sw 31, MC_CCR31_VALUE
2724 + ccr_sw 32, MC_CCR32_VALUE
2725 + ccr_sw 33, MC_CCR33_VALUE
2726 + ccr_sw 34, MC_CCR34_VALUE
2727 + ccr_sw 35, MC_CCR35_VALUE
2728 + ccr_sw 36, MC_CCR36_VALUE
2729 + ccr_sw 37, MC_CCR37_VALUE
2730 + ccr_sw 38, MC_CCR38_VALUE
2731 + ccr_sw 39, MC_CCR39_VALUE
2733 + ccr_sw 40, MC_CCR40_VALUE
2734 + ccr_sw 41, MC_CCR41_VALUE
2735 + ccr_sw 42, MC_CCR42_VALUE
2736 + ccr_sw 43, MC_CCR43_VALUE
2737 + ccr_sw 44, MC_CCR44_VALUE
2738 + ccr_sw 45, MC_CCR45_VALUE
2739 + ccr_sw 46, MC_CCR46_VALUE
2741 + ccr_sw 52, MC_CCR52_VALUE
2742 + ccr_sw 53, MC_CCR53_VALUE
2743 + ccr_sw 54, MC_CCR54_VALUE
2744 + ccr_sw 55, MC_CCR55_VALUE
2745 + ccr_sw 56, MC_CCR56_VALUE
2746 + ccr_sw 57, MC_CCR57_VALUE
2747 + ccr_sw 58, MC_CCR58_VALUE
2748 + ccr_sw 59, MC_CCR59_VALUE
2750 + ccr_sw 60, MC_CCR60_VALUE
2751 + ccr_sw 61, MC_CCR61_VALUE
2753 + /* Disable bursts between FPI Master bus and XBAR bus */
2754 + li t4, (LTQ_MC_GLOBAL_BASE | KSEG1)
2755 + li t5, CCS_AHBM_CR_BURST_EN
2756 + sw t5, CCS_ALWAYS_LAST(t4)
2758 + /* Init abort condition for DRAM probe */
2762 + * Put memory controller in active mode and start initialitation
2763 + * sequence for connected DDR-SDRAM device
2766 + lw t1, LTQ_MC_DDR_CCR_OFFSET(7)(t0)
2767 + li t2, LTQ_MC_DDR_START
2769 + sw t1, LTQ_MC_DDR_CCR_OFFSET(7)(t0)
2772 + * Wait until DLL has locked and core is ready for data transfers.
2773 + * DLL lock indication is in register CCR47 and CCR48
2776 + li t1, LTQ_MC_DDR_DLL_LOCK_IND
2777 + lw t2, LTQ_MC_DDR_CCR_OFFSET(47)(t0)
2779 + bne t1, t2, wait_ready
2781 + lw t2, LTQ_MC_DDR_CCR_OFFSET(48)(t0)
2783 + bne t1, t2, wait_ready
2785 +#ifdef CONFIG_SYS_DRAM_PROBE
2787 + /* Initialization is finished after the second MC start */
2788 + bnez t4, mc_finished
2791 + * Preload register values for CCR03 and CCR11. Initial settings
2792 + * are 8-bank mode enabled, 14 use address row bits, 10 used
2793 + * column address bits.
2795 + li t1, CONFIG_SYS_SDRAM_BASE_UC
2796 + li t5, MC_CCR03_VALUE
2797 + li t6, MC_CCR11_VALUE
2801 + * Store test values to DRAM at offsets 0 and 2^13 (bit 2 in bank select
2802 + * address BA[3]) and read back the value at offset 0. If the resulting
2803 + * value is equal to 1 we can skip to the next test. Otherwise
2804 + * the 8-bank mode does not work with the current DRAM device,
2805 + * thus we need to clear the according bit in register CCR03.
2813 + bnez t3, row_col_test
2815 + /* Clear CCR03.EIGHT_BANK_MODE */
2816 + li t3, ~CCR03_EIGHT_BANK_MODE
2821 + * Store test values to DRAM at offsets 0, 2^27 (bit 13 of row address
2822 + * RA[14]) and 2^26 (bit 12 of RA[14]). The chosen test values
2823 + * represent the difference between max. row address bits (14) and used
2824 + * row address bits. Then the read back value at offset 0 indicates
2825 + * the useable row address bits with the current DRAM device. This
2826 + * value must be set in the CCR11 register.
2840 + /* Update CCR11.ADDR_PINS */
2845 + * Store test values to DRAM at offsets 0, 2^10 (bit 9 of column address
2846 + * CA[10]) and 2^9 (bit 8 of CA[10]). The chosen test values represent
2847 + * the difference between max. column address bits (12) and used
2848 + * column address bits. Then the read back value at offset 0 indicates
2849 + * the useable column address bits with the current DRAM device. This
2850 + * value must be set in the CCR11 register.
2864 + /* Update CCR11.COLUMN_SIZE */
2869 + /* Put memory controller in inactive mode */
2870 + sw zero, LTQ_MC_DDR_CCR_OFFSET(7)(t0)
2872 + /* Update CCR03 and CCR11 and restart memory controller initialiation */
2873 + sw t5, LTQ_MC_DDR_CCR_OFFSET(3)(t0)
2874 + sw t6, LTQ_MC_DDR_CCR_OFFSET(11)(t0)
2878 +#endif /* CONFIG_SYS_DRAM_PROBE */
2884 +++ b/arch/mips/cpu/mips32/vrx200/pmu.c
2887 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
2889 + * SPDX-License-Identifier: GPL-2.0+
2892 +#include <common.h>
2893 +#include <asm/lantiq/io.h>
2894 +#include <asm/lantiq/pm.h>
2895 +#include <asm/arch/soc.h>
2897 +#define LTQ_PMU_PWDCR_RESERVED ((1 << 13) | (1 << 4))
2899 +#define LTQ_PMU_PWDCR_PCIELOC_EN (1 << 31)
2900 +#define LTQ_PMU_PWDCR_GPHY (1 << 30)
2901 +#define LTQ_PMU_PWDCR_PPE_TOP (1 << 29)
2902 +#define LTQ_PMU_PWDCR_SWITCH (1 << 28)
2903 +#define LTQ_PMU_PWDCR_USB1 (1 << 27)
2904 +#define LTQ_PMU_PWDCR_USB1_PHY (1 << 26)
2905 +#define LTQ_PMU_PWDCR_TDM (1 << 25)
2906 +#define LTQ_PMU_PWDCR_PPE_DPLUS (1 << 24)
2907 +#define LTQ_PMU_PWDCR_PPE_DPLUM (1 << 23)
2908 +#define LTQ_PMU_PWDCR_PPE_EMA (1 << 22)
2909 +#define LTQ_PMU_PWDCR_PPE_TC (1 << 21)
2910 +#define LTQ_PMU_PWDCR_DEU (1 << 20)
2911 +#define LTQ_PMU_PWDCR_PPE_SLL01 (1 << 19)
2912 +#define LTQ_PMU_PWDCR_PPE_QSB (1 << 18)
2913 +#define LTQ_PMU_PWDCR_UART1 (1 << 17)
2914 +#define LTQ_PMU_PWDCR_SDIO (1 << 16)
2915 +#define LTQ_PMU_PWDCR_AHBM (1 << 15)
2916 +#define LTQ_PMU_PWDCR_FPIM (1 << 14)
2917 +#define LTQ_PMU_PWDCR_GPTC (1 << 12)
2918 +#define LTQ_PMU_PWDCR_LEDC (1 << 11)
2919 +#define LTQ_PMU_PWDCR_EBU (1 << 10)
2920 +#define LTQ_PMU_PWDCR_DSL (1 << 9)
2921 +#define LTQ_PMU_PWDCR_SPI (1 << 8)
2922 +#define LTQ_PMU_PWDCR_USIF (1 << 7)
2923 +#define LTQ_PMU_PWDCR_USB0 (1 << 6)
2924 +#define LTQ_PMU_PWDCR_DMA (1 << 5)
2925 +#define LTQ_PMU_PWDCR_DFEV1 (1 << 3)
2926 +#define LTQ_PMU_PWDCR_DFEV0 (1 << 2)
2927 +#define LTQ_PMU_PWDCR_FPIS (1 << 1)
2928 +#define LTQ_PMU_PWDCR_USB0_PHY (1 << 0)
2930 +struct ltq_pmu_regs {
2932 + u32 pwdcr; /* Power down control */
2933 + u32 sr; /* Power down status */
2934 + u32 pwdcr1; /* Power down control 1 */
2935 + u32 sr1; /* Power down status 1 */
2938 +static struct ltq_pmu_regs *ltq_pmu_regs =
2939 + (struct ltq_pmu_regs *) CKSEG1ADDR(LTQ_PMU_BASE);
2941 +u32 ltq_pm_map(enum ltq_pm_modules module)
2947 + val = LTQ_PMU_PWDCR_UART1 | LTQ_PMU_PWDCR_FPIM |
2948 + LTQ_PMU_PWDCR_LEDC | LTQ_PMU_PWDCR_EBU;
2951 + val = LTQ_PMU_PWDCR_DMA;
2954 + val = LTQ_PMU_PWDCR_GPHY | LTQ_PMU_PWDCR_PPE_TOP |
2955 + LTQ_PMU_PWDCR_SWITCH | LTQ_PMU_PWDCR_PPE_DPLUS |
2956 + LTQ_PMU_PWDCR_PPE_DPLUM | LTQ_PMU_PWDCR_PPE_EMA |
2957 + LTQ_PMU_PWDCR_PPE_TC | LTQ_PMU_PWDCR_PPE_SLL01 |
2958 + LTQ_PMU_PWDCR_PPE_QSB;
2961 + val = LTQ_PMU_PWDCR_SPI;
2971 +int ltq_pm_enable(enum ltq_pm_modules module)
2973 + const unsigned long timeout = 1000;
2974 + unsigned long timebase;
2977 + val = ltq_pm_map(module);
2978 + if (unlikely(!val))
2981 + ltq_clrbits(<q_pmu_regs->pwdcr, val);
2983 + timebase = get_timer(0);
2986 + sr = ltq_readl(<q_pmu_regs->sr);
2989 + } while (get_timer(timebase) < timeout);
2994 +int ltq_pm_disable(enum ltq_pm_modules module)
2998 + val = ltq_pm_map(module);
2999 + if (unlikely(!val))
3002 + ltq_setbits(<q_pmu_regs->pwdcr, val);
3007 +void ltq_pmu_init(void)
3011 + clr = ltq_pm_map(LTQ_PM_CORE);
3012 + set = ~(LTQ_PMU_PWDCR_RESERVED | clr);
3014 + ltq_clrsetbits(<q_pmu_regs->pwdcr, clr, set);
3017 +++ b/arch/mips/cpu/mips32/vrx200/rcu.c
3020 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
3022 + * SPDX-License-Identifier: GPL-2.0+
3025 +#include <common.h>
3026 +#include <asm/lantiq/io.h>
3027 +#include <asm/lantiq/reset.h>
3028 +#include <asm/lantiq/cpu.h>
3029 +#include <asm/arch/soc.h>
3031 +#define LTQ_RCU_RD_GPHY0 (1 << 31) /* GPHY0 */
3032 +#define LTQ_RCU_RD_SRST (1 << 30) /* Global SW Reset */
3033 +#define LTQ_RCU_RD_GPHY1 (1 << 29) /* GPHY1 */
3034 +#define LTQ_RCU_RD_ENMIP2 (1 << 28) /* Enable NMI of PLL2 */
3035 +#define LTQ_RCU_RD_REG25_PD (1 << 26) /* Power down 2.5V regulator */
3036 +#define LTQ_RCU_RD_ENDINIT (1 << 25) /* FPI slave bus access */
3037 +#define LTQ_RCU_RD_PPE_ATM_TC (1 << 23) /* PPE ATM TC */
3038 +#define LTQ_RCU_RD_PCIE (1 << 22) /* PCI-E core */
3039 +#define LTQ_RCU_RD_ETHSW (1 << 21) /* Ethernet switch */
3040 +#define LTQ_RCU_RD_DSP_DEN (1 << 20) /* Enable DSP JTAG */
3041 +#define LTQ_RCU_RD_TDM (1 << 19) /* TDM module interface */
3042 +#define LTQ_RCU_RD_ENMIP1 (1 << 18) /* Enable NMI of PLL1 */
3043 +#define LTQ_RCU_RD_SWBCK (1 << 17) /* Switch backward compat */
3044 +#define LTQ_RCU_RD_HSNAND (1 << 16) /* HSNAND controller */
3045 +#define LTQ_RCU_RD_ENMIP0 (1 << 15) /* Enable NMI of PLL0 */
3046 +#define LTQ_RCU_RD_MC (1 << 14) /* Memory Controller */
3047 +#define LTQ_RCU_RD_PCI (1 << 13) /* PCI core */
3048 +#define LTQ_RCU_RD_PCIE_PHY (1 << 12) /* PCI-E Phy */
3049 +#define LTQ_RCU_RD_DFE_CORE (1 << 11) /* DFE core */
3050 +#define LTQ_RCU_RD_SDIO (1 << 10) /* SDIO core */
3051 +#define LTQ_RCU_RD_DMA (1 << 9) /* DMA core */
3052 +#define LTQ_RCU_RD_PPE (1 << 8) /* PPE core */
3053 +#define LTQ_RCU_RD_DFE (1 << 7) /* DFE core */
3054 +#define LTQ_RCU_RD_AHB (1 << 6) /* AHB bus */
3055 +#define LTQ_RCU_RD_HRST_CFG (1 << 5) /* HW reset configuration */
3056 +#define LTQ_RCU_RD_USB (1 << 4) /* USB and Phy core */
3057 +#define LTQ_RCU_RD_PPE_DSP (1 << 3) /* PPE DSP interface */
3058 +#define LTQ_RCU_RD_FPI (1 << 2) /* FPI bus */
3059 +#define LTQ_RCU_RD_CPU (1 << 1) /* CPU subsystem */
3060 +#define LTQ_RCU_RD_HRST (1 << 0) /* HW reset via HRST pin */
3062 +#define LTQ_RCU_STAT_BOOT_SHIFT 17
3063 +#define LTQ_RCU_STAT_BOOT_MASK (0xF << LTQ_RCU_STAT_BOOT_SHIFT)
3064 +#define LTQ_RCU_STAT_BOOT_H (1 << 12)
3066 +#define LTQ_RCU_GP_STRAP_CLOCKSOURCE (1 << 15)
3068 +struct ltq_rcu_regs {
3070 + u32 req; /* Reset request */
3071 + u32 stat; /* Reset status */
3072 + u32 usb0_cfg; /* USB0 configure */
3073 + u32 gp_strap; /* GPIO strapping */
3074 + u32 gfs_add0; /* GPHY0 firmware base addr */
3075 + u32 stat2; /* SLIC and USB reset status */
3076 + u32 pci_rdy; /* PCI boot ready */
3077 + u32 ppe_conf; /* PPE ethernet config */
3078 + u32 pcie_phy_con; /* PCIE PHY config/status */
3079 + u32 usb1_cfg; /* USB1 configure */
3080 + u32 usb_ana_cfg1a; /* USB analog config 1a */
3081 + u32 usb_ana_cfg1b; /* USB analog config 1b */
3083 + u32 gf_mdio_add; /* GPHY0/1 MDIO address */
3084 + u32 req2; /* SLIC and USB reset request */
3085 + u32 ahb_endian; /* AHB bus endianess */
3087 + u32 gcc; /* General CPU config */
3089 + u32 gfs_add1; /* GPHY1 firmware base addr */
3092 +static struct ltq_rcu_regs *ltq_rcu_regs =
3093 + (struct ltq_rcu_regs *) CKSEG1ADDR(LTQ_RCU_BASE);
3095 +u32 ltq_reset_map(enum ltq_reset_modules module)
3100 + case LTQ_RESET_CORE:
3101 + case LTQ_RESET_SOFT:
3102 + val = LTQ_RCU_RD_SRST | LTQ_RCU_RD_CPU | LTQ_RCU_RD_ENMIP2 |
3103 + LTQ_RCU_RD_GPHY1 | LTQ_RCU_RD_GPHY0;
3105 + case LTQ_RESET_DMA:
3106 + val = LTQ_RCU_RD_DMA;
3108 + case LTQ_RESET_ETH:
3109 + val = LTQ_RCU_RD_PPE | LTQ_RCU_RD_ETHSW;
3111 + case LTQ_RESET_PHY:
3112 + val = LTQ_RCU_RD_GPHY1 | LTQ_RCU_RD_GPHY0;
3114 + case LTQ_RESET_HARD:
3115 + val = LTQ_RCU_RD_HRST;
3125 +int ltq_reset_activate(enum ltq_reset_modules module)
3129 + val = ltq_reset_map(module);
3130 + if (unlikely(!val))
3133 + ltq_setbits(<q_rcu_regs->req, val);
3138 +int ltq_reset_deactivate(enum ltq_reset_modules module)
3142 + val = ltq_reset_map(module);
3143 + if (unlikely(!val))
3146 + ltq_clrbits(<q_rcu_regs->req, val);
3151 +enum ltq_boot_select ltq_boot_select(void)
3154 + unsigned int bootstrap;
3157 + * Boot select value is built from bits 20-17 and bit 12.
3158 + * The bit sequence is read as 4-2-1-0-3.
3160 + stat = ltq_readl(<q_rcu_regs->stat);
3161 + bootstrap = ((stat & LTQ_RCU_STAT_BOOT_H) << 4) |
3162 + ((stat & LTQ_RCU_STAT_BOOT_MASK) >> LTQ_RCU_STAT_BOOT_SHIFT);
3164 + switch (bootstrap) {
3166 + return BOOT_NOR_NO_BOOTROM;
3168 + return BOOT_RGMII1;
3172 + return BOOT_UART_NO_EEPROM;
3182 + return BOOT_UNKNOWN;
3186 +void ltq_rcu_gphy_boot(unsigned int id, ulong addr)
3193 + module = LTQ_RCU_RD_GPHY0;
3194 + gfs_add = <q_rcu_regs->gfs_add0;
3197 + module = LTQ_RCU_RD_GPHY1;
3198 + gfs_add = <q_rcu_regs->gfs_add1;
3204 + /* Stop and reset GPHY */
3205 + ltq_setbits(<q_rcu_regs->req, module);
3207 + /* Configure firmware and boot address */
3208 + ltq_writel(gfs_add, CPHYSADDR(addr & 0xFFFFC000));
3210 + /* Start GPHY by releasing reset */
3211 + ltq_clrbits(<q_rcu_regs->req, module);
3214 +++ b/arch/mips/include/asm/arch-danube/config.h
3217 + * Copyright (C) 2007-2010 Lantiq Deutschland GmbH
3218 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
3220 + * SPDX-License-Identifier: GPL-2.0+
3222 + * Common board configuration for Lantiq XWAY Danube family
3224 + * Use following defines in your board config to enable specific features
3225 + * and drivers for this SoC:
3227 + * CONFIG_LTQ_SUPPORT_UART
3228 + * - support the Danube ASC/UART interface and console
3230 + * CONFIG_LTQ_SUPPORT_NOR_FLASH
3231 + * - support a parallel NOR flash via the CFI interface in flash bank 0
3233 + * CONFIG_LTQ_SUPPORT_ETHERNET
3234 + * - support the Danube ETOP and MAC interface
3236 + * CONFIG_LTQ_SUPPORT_SPI_FLASH
3237 + * - support the Danube SPI interface and serial flash drivers
3238 + * - specific SPI flash drivers must be configured separately
3241 +#ifndef __DANUBE_CONFIG_H__
3242 +#define __DANUBE_CONFIG_H__
3244 +/* CPU and SoC type */
3245 +#define CONFIG_SOC_LANTIQ
3246 +#define CONFIG_SOC_XWAY_DANUBE
3248 +/* Cache configuration */
3249 +#define CONFIG_SYS_MIPS_CACHE_MODE CONF_CM_CACHABLE_NONCOHERENT
3250 +#define CONFIG_SYS_DCACHE_SIZE (16 * 1024)
3251 +#define CONFIG_SYS_ICACHE_SIZE (16 * 1024)
3252 +#define CONFIG_SYS_CACHELINE_SIZE 32
3253 +#define CONFIG_SYS_MIPS_CACHE_EXT_INIT
3256 + * Supported clock modes
3257 + * PLL0 clock output is 333 MHz
3258 + * PLL1 clock output is 262.144 MHz
3260 +#define LTQ_CLK_CPU_333_DDR_167 0 /* Base PLL0, OCP 2 */
3261 +#define LTQ_CLK_CPU_111_DDR_111 1 /* Base PLL0, OCP 1 */
3264 +#define CONFIG_SYS_CLOCK_MODE LTQ_CLK_CPU_333_DDR_167
3265 +#define CONFIG_SYS_MIPS_TIMER_FREQ 166666667
3266 +#define CONFIG_SYS_HZ 1000
3269 +#define CONFIG_NR_DRAM_BANKS 1
3270 +#define CONFIG_SYS_SDRAM_BASE 0x80000000
3271 +#define CONFIG_SYS_MEMTEST_START 0x81000000
3272 +#define CONFIG_SYS_MEMTEST_END 0x82000000
3273 +#define CONFIG_SYS_LOAD_ADDR 0x81000000
3274 +#define CONFIG_SYS_INIT_SP_OFFSET 0x4000
3277 +#define CONFIG_SYS_SRAM_BASE 0xBE1A0000
3278 +#define CONFIG_SYS_SRAM_SIZE 0x10000
3280 +/* ASC/UART driver and console */
3281 +#define CONFIG_LANTIQ_SERIAL
3282 +#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
3285 +#define CONFIG_LANTIQ_GPIO
3286 +#define CONFIG_LTQ_GPIO_MAX_BANKS 2
3289 +#if defined(CONFIG_LTQ_SUPPORT_NOR_FLASH)
3290 +#define CONFIG_SYS_MAX_FLASH_BANKS 1
3291 +#define CONFIG_SYS_MAX_FLASH_SECT 256
3292 +#define CONFIG_SYS_FLASH_BASE 0xB0000000
3293 +#define CONFIG_FLASH_16BIT
3294 +#define CONFIG_SYS_FLASH_CFI
3295 +#define CONFIG_FLASH_CFI_DRIVER
3296 +#define CONFIG_SYS_FLASH_CFI_WIDTH FLASH_CFI_16BIT
3297 +#define CONFIG_SYS_FLASH_USE_BUFFER_WRITE
3298 +#define CONFIG_FLASH_SHOW_PROGRESS 50
3299 +#define CONFIG_SYS_FLASH_PROTECTION
3300 +#define CONFIG_CFI_FLASH_USE_WEAK_ADDR_SWAP
3302 +#define CONFIG_CMD_FLASH
3304 +#define CONFIG_SYS_NO_FLASH
3305 +#endif /* CONFIG_NOR_FLASH */
3307 +#if defined(CONFIG_LTQ_SUPPORT_SPI_FLASH)
3308 +#define CONFIG_LANTIQ_SPI
3309 +#define CONFIG_SPI_FLASH
3311 +#define CONFIG_CMD_SF
3312 +#define CONFIG_CMD_SPI
3315 +#if defined(CONFIG_LTQ_SUPPORT_NAND_FLASH)
3316 +#define CONFIG_NAND_LANTIQ
3317 +#define CONFIG_SYS_MAX_NAND_DEVICE 1
3318 +#define CONFIG_SYS_NAND_BASE 0xB4000000
3320 +#define CONFIG_CMD_NAND
3323 +#if defined(CONFIG_LTQ_SUPPORT_ETHERNET)
3324 +#define CONFIG_LANTIQ_DMA
3325 +#define CONFIG_LANTIQ_DANUBE_ETOP
3327 +#define CONFIG_PHYLIB
3330 +#define CONFIG_CMD_MII
3331 +#define CONFIG_CMD_NET
3334 +#define CONFIG_SPL_MAX_SIZE (32 * 1024)
3335 +#define CONFIG_SPL_BSS_MAX_SIZE (8 * 1024)
3336 +#define CONFIG_SPL_STACK_MAX_SIZE (8 * 1024)
3337 +#define CONFIG_SPL_MALLOC_MAX_SIZE (32 * 1024)
3338 +/*#define CONFIG_SPL_STACK_BSS_IN_SRAM*/
3340 +#if defined(CONFIG_SPL_STACK_BSS_IN_SRAM)
3341 +#define CONFIG_SPL_STACK_BASE (CONFIG_SYS_SRAM_BASE + \
3342 + CONFIG_SPL_MAX_SIZE + \
3343 + CONFIG_SPL_STACK_MAX_SIZE - 1)
3344 +#define CONFIG_SPL_BSS_BASE (CONFIG_SPL_STACK_BASE + 1)
3345 +#define CONFIG_SPL_MALLOC_BASE (CONFIG_SYS_SDRAM_BASE + \
3346 + CONFIG_SYS_INIT_SP_OFFSET)
3348 +#define CONFIG_SPL_STACK_BASE (CONFIG_SYS_SDRAM_BASE + \
3349 + CONFIG_SYS_INIT_SP_OFFSET + \
3350 + CONFIG_SPL_STACK_MAX_SIZE - 1)
3351 +#define CONFIG_SPL_BSS_BASE (CONFIG_SPL_STACK_BASE + 1)
3352 +#define CONFIG_SPL_MALLOC_BASE (CONFIG_SPL_BSS_BASE + \
3353 + CONFIG_SPL_BSS_MAX_SIZE)
3356 +#if defined(CONFIG_SYS_BOOT_RAM)
3357 +#define CONFIG_SYS_TEXT_BASE 0xa0100000
3358 +#define CONFIG_SKIP_LOWLEVEL_INIT
3359 +#define CONFIG_SYS_DISABLE_CACHE
3362 +#if defined(CONFIG_SYS_BOOT_NOR)
3363 +#define CONFIG_SYS_TEXT_BASE 0xB0000000
3366 +#if defined(CONFIG_SYS_BOOT_NORSPL)
3367 +#define CONFIG_SYS_TEXT_BASE 0x80100000
3368 +#define CONFIG_SPL_TEXT_BASE 0xB0000000
3371 +#if defined(CONFIG_SYS_BOOT_NOR) || defined(CONFIG_SYS_BOOT_NORSPL)
3372 +#define CONFIG_SYS_XWAY_EBU_BOOTCFG 0x688C688C
3373 +#define CONFIG_XWAY_SWAP_BYTES
3376 +#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE
3378 +#endif /* __DANUBE_CONFIG_H__ */
3380 +++ b/arch/mips/include/asm/arch-danube/gpio.h
3383 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
3385 + * SPDX-License-Identifier: GPL-2.0+
3388 +#ifndef __DANUBE_GPIO_H__
3389 +#define __DANUBE_GPIO_H__
3391 +#include <asm/lantiq/gpio.h>
3393 +#endif /* __DANUBE_GPIO_H__ */
3395 +++ b/arch/mips/include/asm/arch-danube/nand.h
3398 + * Copyright (C) 2012-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
3400 + * SPDX-License-Identifier: GPL-2.0+
3403 +#ifndef __DANUBE_NAND_H__
3404 +#define __DANUBE_NAND_H__
3407 +int ltq_nand_init(struct nand_chip *nand);
3409 +#endif /* __DANUBE_NAND_H__ */
3411 +++ b/arch/mips/include/asm/arch-danube/soc.h
3414 + * Copyright (C) 2007-2010 Lantiq Deutschland GmbH
3415 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
3417 + * SPDX-License-Identifier: GPL-2.0+
3420 +#ifndef __DANUBE_SOC_H__
3421 +#define __DANUBE_SOC_H__
3423 +#define LTQ_ASC0_BASE 0x1E100400
3424 +#define LTQ_SPI_BASE 0x1E100800
3425 +#define LTQ_GPIO_BASE 0x1E100B00
3426 +#define LTQ_SSIO_BASE 0x1E100BB0
3427 +#define LTQ_ASC1_BASE 0x1E100C00
3428 +#define LTQ_DMA_BASE 0x1E104100
3430 +#define LTQ_EBU_BASE 0x1E105300
3431 +#define LTQ_EBU_REGION0_BASE 0x10000000
3432 +#define LTQ_EBU_REGION1_BASE 0x14000000
3433 +#define LTQ_EBU_NAND_BASE (LTQ_EBU_BASE + 0xB0)
3435 +#define LTQ_PPE_BASE 0x1E180000
3436 +#define LTQ_PPE_ETOP_BASE (LTQ_PPE_BASE + 0x11800)
3437 +#define LTQ_PPE_ENET0_BASE (LTQ_PPE_BASE + 0x11840)
3439 +#define LTQ_PMU_BASE 0x1F102000
3440 +#define LTQ_CGU_BASE 0x1F103000
3441 +#define LTQ_MPS_BASE 0x1F107000
3442 +#define LTQ_CHIPID_BASE (LTQ_MPS_BASE + 0x340)
3443 +#define LTQ_RCU_BASE 0x1F203000
3445 +#define LTQ_MC_GEN_BASE 0x1F800000
3446 +#define LTQ_MC_SDR_BASE 0x1F800200
3447 +#define LTQ_MC_DDR_BASE 0x1F801000
3448 +#define LTQ_MC_DDR_DC_OFFSET(x) (x * 0x10)
3450 +#endif /* __DANUBE_SOC_H__ */
3452 +++ b/arch/mips/include/asm/arch-vrx200/config.h
3455 + * Copyright (C) 2010 Lantiq Deutschland GmbH
3456 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
3458 + * SPDX-License-Identifier: GPL-2.0+
3460 + * Common board configuration for Lantiq XWAY VRX200 family
3462 + * Use following defines in your board config to enable specific features
3463 + * and drivers for this SoC:
3465 + * CONFIG_LTQ_SUPPORT_UART
3466 + * - support the VRX200 ASC/UART interface and console
3468 + * CONFIG_LTQ_SUPPORT_NOR_FLASH
3469 + * - support a parallel NOR flash via the CFI interface in flash bank 0
3471 + * CONFIG_LTQ_SUPPORT_ETHERNET
3472 + * - support the VRX200 internal switch
3474 + * CONFIG_LTQ_SUPPORT_SPI_FLASH
3475 + * - support the VRX200 SPI interface and serial flash drivers
3476 + * - specific SPI flash drivers must be configured separately
3478 + * CONFIG_LTQ_SUPPORT_SPL_SPI_FLASH
3479 + * - build a preloader that runs in the internal SRAM and loads
3480 + * the U-Boot from SPI flash into RAM
3483 +#ifndef __VRX200_CONFIG_H__
3484 +#define __VRX200_CONFIG_H__
3486 +/* CPU and SoC type */
3487 +#define CONFIG_SOC_LANTIQ
3488 +#define CONFIG_SOC_XWAY_VRX200
3490 +/* Cache configuration */
3491 +#define CONFIG_SYS_MIPS_CACHE_MODE CONF_CM_CACHABLE_NONCOHERENT
3492 +#define CONFIG_SYS_DCACHE_SIZE (32 * 1024)
3493 +#define CONFIG_SYS_ICACHE_SIZE (32 * 1024)
3494 +#define CONFIG_SYS_CACHELINE_SIZE 32
3495 +#define CONFIG_SYS_MIPS_CACHE_EXT_INIT
3498 + * Supported clock modes
3499 + * PLL0 clock output is 1000 MHz
3500 + * PLL1 clock output is 393.219 MHz
3502 +#define LTQ_CLK_CPU_600_DDR_300 0 /* Base PLL0, OCP 2 */
3503 +#define LTQ_CLK_CPU_600_DDR_200 1 /* Base PLL0, OCP 3 */
3504 +#define LTQ_CLK_CPU_500_DDR_250 2 /* Base PLL0, OCP 2 */
3505 +#define LTQ_CLK_CPU_500_DDR_200 3 /* Base PLL0, OCP 2.5 */
3506 +#define LTQ_CLK_CPU_333_DDR_167 4 /* Base PLL0, OCP 2 */
3507 +#define LTQ_CLK_CPU_167_DDR_167 5 /* Base PLL0, OCP 1 */
3508 +#define LTQ_CLK_CPU_125_DDR_125 6 /* Base PLL0, OCP 1 */
3509 +#define LTQ_CLK_CPU_393_DDR_197 7 /* Base PLL1, OCP 2 */
3510 +#define LTQ_CLK_CPU_197_DDR_197 8 /* Base PLL1, OCP 1 */
3513 +#define CONFIG_SYS_CLOCK_MODE LTQ_CLK_CPU_500_DDR_250
3514 +#define CONFIG_SYS_MIPS_TIMER_FREQ 250000000
3515 +#define CONFIG_SYS_HZ 1000
3518 +#define CONFIG_NR_DRAM_BANKS 1
3519 +#define CONFIG_SYS_SDRAM_BASE 0x80000000
3520 +#define CONFIG_SYS_SDRAM_BASE_UC 0xa0000000
3521 +#define CONFIG_SYS_MEMTEST_START 0x81000000
3522 +#define CONFIG_SYS_MEMTEST_END 0x82000000
3523 +#define CONFIG_SYS_LOAD_ADDR 0x81000000
3524 +#define CONFIG_SYS_INIT_SP_OFFSET (32 * 1024)
3527 +#define CONFIG_SYS_SRAM_BASE 0xBE220000
3528 +#define CONFIG_SYS_SRAM_SIZE 0x10000
3530 +/* ASC/UART driver and console */
3531 +#define CONFIG_LANTIQ_SERIAL
3532 +#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
3535 +#define CONFIG_LANTIQ_GPIO
3536 +#define CONFIG_LTQ_GPIO_MAX_BANKS 3
3537 +#define CONFIG_LTQ_HAS_GPIO_BANK3
3540 +#if defined(CONFIG_LTQ_SUPPORT_NOR_FLASH)
3541 +#define CONFIG_SYS_MAX_FLASH_BANKS 1
3542 +#define CONFIG_SYS_MAX_FLASH_SECT 256
3543 +#define CONFIG_SYS_FLASH_BASE 0xB0000000
3544 +#define CONFIG_FLASH_16BIT
3545 +#define CONFIG_SYS_FLASH_CFI
3546 +#define CONFIG_FLASH_CFI_DRIVER
3547 +#define CONFIG_SYS_FLASH_CFI_WIDTH FLASH_CFI_16BIT
3548 +#define CONFIG_SYS_FLASH_USE_BUFFER_WRITE
3549 +#define CONFIG_FLASH_SHOW_PROGRESS 50
3550 +#define CONFIG_SYS_FLASH_PROTECTION
3551 +#define CONFIG_CFI_FLASH_USE_WEAK_ADDR_SWAP
3553 +#define CONFIG_CMD_FLASH
3555 +#define CONFIG_SYS_NO_FLASH
3556 +#endif /* CONFIG_NOR_FLASH */
3558 +#if defined(CONFIG_LTQ_SUPPORT_SPI_FLASH)
3559 +#define CONFIG_LANTIQ_SPI
3560 +#define CONFIG_SPI_FLASH
3562 +#define CONFIG_CMD_SF
3563 +#define CONFIG_CMD_SPI
3566 +#if defined(CONFIG_LTQ_SUPPORT_NAND_FLASH)
3567 +#define CONFIG_NAND_LANTIQ
3568 +#define CONFIG_SYS_MAX_NAND_DEVICE 1
3569 +#define CONFIG_SYS_NAND_BASE 0xB4000000
3571 +#define CONFIG_CMD_NAND
3574 +#if defined(CONFIG_LTQ_SUPPORT_ETHERNET)
3575 +#define CONFIG_LANTIQ_DMA
3576 +#define CONFIG_LANTIQ_VRX200_SWITCH
3577 +#define CONFIG_PHY_LANTIQ
3579 +#define CONFIG_SYS_RX_ETH_BUFFER 8
3580 +#define CONFIG_PHYLIB
3582 +#define CONFIG_UDP_CHECKSUM
3584 +#define CONFIG_CMD_MII
3585 +#define CONFIG_CMD_NET
3588 +#define CONFIG_SPL_MAX_SIZE (32 * 1024)
3589 +#define CONFIG_SPL_BSS_MAX_SIZE (8 * 1024)
3590 +#define CONFIG_SPL_STACK_MAX_SIZE (8 * 1024)
3591 +#define CONFIG_SPL_MALLOC_MAX_SIZE (32 * 1024)
3592 +#define CONFIG_SPL_STACK_BSS_IN_SRAM
3594 +#if defined(CONFIG_SPL_STACK_BSS_IN_SRAM)
3595 +#define CONFIG_SPL_STACK_BASE (CONFIG_SYS_SRAM_BASE + \
3596 + CONFIG_SPL_MAX_SIZE + \
3597 + CONFIG_SPL_STACK_MAX_SIZE - 1)
3598 +#define CONFIG_SPL_BSS_BASE (CONFIG_SPL_STACK_BASE + 1)
3599 +#define CONFIG_SPL_MALLOC_BASE (CONFIG_SYS_SDRAM_BASE + \
3600 + CONFIG_SYS_INIT_SP_OFFSET)
3602 +#define CONFIG_SPL_STACK_BASE (CONFIG_SYS_SDRAM_BASE + \
3603 + CONFIG_SYS_INIT_SP_OFFSET + \
3604 + CONFIG_SPL_STACK_MAX_SIZE - 1)
3605 +#define CONFIG_SPL_BSS_BASE (CONFIG_SPL_STACK_BASE + 1)
3606 +#define CONFIG_SPL_MALLOC_BASE (CONFIG_SPL_BSS_BASE + \
3607 + CONFIG_SPL_BSS_MAX_SIZE)
3610 +#if defined(CONFIG_SYS_BOOT_RAM)
3611 +#define CONFIG_SYS_TEXT_BASE 0xA0100000
3612 +#define CONFIG_SKIP_LOWLEVEL_INIT
3613 +#define CONFIG_SYS_DISABLE_CACHE
3616 +#if defined(CONFIG_SYS_BOOT_NOR)
3617 +#define CONFIG_SYS_TEXT_BASE 0xB0000000
3620 +#if defined(CONFIG_SYS_BOOT_SFSPL)
3621 +#define CONFIG_SYS_TEXT_BASE 0x80100000
3622 +#define CONFIG_SPL_TEXT_BASE 0xBE220000
3625 +#if defined(CONFIG_SYS_BOOT_NORSPL)
3626 +#define CONFIG_SYS_TEXT_BASE 0x80100000
3627 +#define CONFIG_SPL_TEXT_BASE 0xB0000000
3630 +#if defined(CONFIG_SYS_BOOT_NOR) || defined(CONFIG_SYS_BOOT_NORSPL)
3631 +#define CONFIG_SYS_XWAY_EBU_BOOTCFG 0x688C688C
3632 +#define CONFIG_XWAY_SWAP_BYTES
3635 +#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE
3637 +#endif /* __VRX200_CONFIG_H__ */
3639 +++ b/arch/mips/include/asm/arch-vrx200/gphy.h
3642 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
3644 + * SPDX-License-Identifier: GPL-2.0+
3647 +#ifndef __VRX200_GPHY_H__
3648 +#define __VRX200_GPHY_H__
3650 +enum ltq_gphy_clk {
3651 + /* XTAL 36 MHz input */
3652 + LTQ_GPHY_CLK_36MHZ_XTAL = 1,
3653 + /* 25 MHz from PLL0 with divider */
3654 + LTQ_GPHY_CLK_25MHZ_PLL0 = 2,
3655 + /* derived from PLL2 output (XTAL is 36 MHz) */
3656 + LTQ_GPHY_CLK_24MHZ_PLL2 = 3,
3657 + /* 25 MHz Clock from Pin GPIO3 */
3658 + LTQ_GPHY_CLK_25MHZ_GPIO3 = 4,
3662 + * Load PHY11G firmware for VRX200 v1.1 to given RAM address
3664 + * Address must be 16k aligned!
3666 +extern void ltq_gphy_phy11g_a1x_load(ulong addr);
3669 + * Load PHY11G firmware for VRX200 v1.2 to given RAM address
3671 + * Address must be 16k aligned!
3673 +extern void ltq_gphy_phy11g_a2x_load(ulong addr);
3676 + * Load PHY22F firmware for VRX200 v1.1 to given RAM address
3678 + * Address must be 16k aligned!
3680 +extern void ltq_gphy_phy22f_a1x_load(ulong addr);
3683 + * Load PHY22F firmware for VRX200 v1.2 to given RAM address
3685 + * Address must be 16k aligned!
3687 +extern void ltq_gphy_phy22f_a2x_load(ulong addr);
3690 + * Set clock source of internal GPHYs
3692 + * According registers resides in CGU address space. Thus this function
3693 + * is implemented by the CGU driver.
3695 +extern void ltq_cgu_gphy_clk_src(enum ltq_gphy_clk clk);
3698 + * Boot internal GPHY with id from given RAM address
3700 + * According registers resides in RCU address space. Thus this function
3701 + * is implemented by the RCU driver.
3703 +extern void ltq_rcu_gphy_boot(unsigned int id, ulong addr);
3705 +#endif /* __VRX200_GPHY_H__ */
3707 +++ b/arch/mips/include/asm/arch-vrx200/gpio.h
3710 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
3712 + * SPDX-License-Identifier: GPL-2.0+
3715 +#ifndef __VRX200_GPIO_H__
3716 +#define __VRX200_GPIO_H__
3718 +#include <asm/lantiq/gpio.h>
3720 +#endif /* __VRX200_GPIO_H__ */
3722 +++ b/arch/mips/include/asm/arch-vrx200/nand.h
3725 + * Copyright (C) 2012-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
3727 + * SPDX-License-Identifier: GPL-2.0+
3730 +#ifndef __VRX200_NAND_H__
3731 +#define __VRX200_NAND_H__
3734 +int ltq_nand_init(struct nand_chip *nand);
3736 +#endif /* __VRX200_NAND_H__ */
3738 +++ b/arch/mips/include/asm/arch-vrx200/soc.h
3741 + * Copyright (C) 2010 Lantiq Deutschland GmbH
3742 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
3744 + * SPDX-License-Identifier: GPL-2.0+
3747 +#ifndef __VRX200_SOC_H__
3748 +#define __VRX200_SOC_H__
3750 +#define LTQ_ASC0_BASE 0x1E100400
3751 +#define LTQ_SPI_BASE 0x1E100800
3752 +#define LTQ_GPIO_BASE 0x1E100B00
3753 +#define LTQ_SSIO_BASE 0x1E100BB0
3754 +#define LTQ_ASC1_BASE 0x1E100C00
3755 +#define LTQ_DMA_BASE 0x1E104100
3757 +#define LTQ_EBU_BASE 0x1E105300
3758 +#define LTQ_EBU_REGION0_BASE 0x10000000
3759 +#define LTQ_EBU_REGION1_BASE 0x14000000
3760 +#define LTQ_EBU_NAND_BASE (LTQ_EBU_BASE + 0xB0)
3762 +#define LTQ_SWITCH_BASE 0x1E108000
3763 +#define LTQ_SWITCH_CORE_BASE LTQ_SWITCH_BASE
3764 +#define LTQ_SWITCH_TOP_PDI_BASE LTQ_SWITCH_CORE_BASE
3765 +#define LTQ_SWITCH_BM_PDI_BASE (LTQ_SWITCH_CORE_BASE + 4 * 0x40)
3766 +#define LTQ_SWITCH_MAC_PDI_0_BASE (LTQ_SWITCH_CORE_BASE + 4 * 0x900)
3767 +#define LTQ_SWITCH_MAC_PDI_X_BASE(x) (LTQ_SWITCH_MAC_PDI_0_BASE + x * 0x30)
3768 +#define LTQ_SWITCH_TOPLEVEL_BASE (LTQ_SWITCH_BASE + 4 * 0xC40)
3769 +#define LTQ_SWITCH_MDIO_PDI_BASE (LTQ_SWITCH_TOPLEVEL_BASE)
3770 +#define LTQ_SWITCH_MII_PDI_BASE (LTQ_SWITCH_TOPLEVEL_BASE + 4 * 0x36)
3771 +#define LTQ_SWITCH_PMAC_PDI_BASE (LTQ_SWITCH_TOPLEVEL_BASE + 4 * 0x82)
3773 +#define LTQ_PMU_BASE 0x1F102000
3774 +#define LTQ_CGU_BASE 0x1F103000
3775 +#define LTQ_DCDC_BASE 0x1F106A00
3776 +#define LTQ_MPS_BASE 0x1F107000
3777 +#define LTQ_CHIPID_BASE (LTQ_MPS_BASE + 0x340)
3778 +#define LTQ_RCU_BASE 0x1F203000
3780 +#define LTQ_MC_GLOBAL_BASE 0x1F400000
3781 +#define LTQ_MC_DDR_BASE 0x1F401000
3782 +#define LTQ_MC_DDR_CCR_OFFSET(x) (x * 0x10)
3784 +#endif /* __VRX200_SOC_H__ */
3786 +++ b/arch/mips/include/asm/arch-vrx200/switch.h
3789 + * Copyright (C) 2012-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
3791 + * SPDX-License-Identifier: GPL-2.0+
3794 +#ifndef __VRX200_SWITCH_H__
3795 +#define __VRX200_SWITCH_H__
3797 +/* Switch core registers */
3798 +struct vr9_switch_core_regs {
3800 + /* TODO: implement registers */
3801 + __be32 rsvd0[0x3f];
3804 +/* Switch buffer management registers */
3805 +struct vr9_switch_bm_regs {
3807 + __be32 ram_val3; /* RAM value 3 */
3808 + __be32 ram_val2; /* RAM value 2 */
3809 + __be32 ram_val1; /* RAM value 1 */
3810 + __be32 ram_val0; /* RAM value 0 */
3811 + __be32 ram_addr; /* RAM address */
3812 + __be32 ram_ctrl; /* RAM access control */
3813 + __be32 fsqm_gctrl; /* Free segment queue global control */
3814 + __be32 cons_sel; /* Number of consumed segments */
3815 + __be32 cons_pkt; /* Number of consumed packet pointers */
3816 + __be32 gctrl; /* Global control */
3817 + __be32 queue_gctrl; /* Queue manager global control */
3818 + /* TODO: implement registers */
3819 + __be32 rsvd0[0x35];
3823 + __be32 pcfg; /* Port config */
3824 + __be32 rmon_ctrl; /* RMON control */
3827 + __be32 rsvd0[0x66];
3831 + __be32 pqm_rs; /* Packet queue manager rate shape assignment */
3834 + struct bm_shaper {
3835 + __be32 ctrl; /* Rate shaper control */
3836 + __be32 cbs; /* Rate shaper committed burst size */
3837 + __be32 ibs; /* Rate shaper instantaneous burst size */
3838 + __be32 cir_ext; /* Rate shaper rate exponent */
3839 + __be32 cir_mant; /* Rate shaper rate mantissa */
3842 + __be32 rsvd1[0x2a8];
3845 +/* Switch parser and classification engine registers */
3846 +struct vr9_switch_pce_regs {
3848 + __be32 tbl_key[16]; /* Table key data */
3849 + __be32 tbl_mask; /* Table mask */
3850 + __be32 tbl_val[5]; /* Table value */
3851 + __be32 tbl_addr; /* Table entry address */
3852 + __be32 tbl_ctrl; /* Table access control */
3853 + __be32 tbl_stat; /* Table general status */
3854 + __be32 age_0; /* Aging counter config 0 */
3855 + __be32 age_1; /* Aging counter config 1 */
3856 + __be32 pmap_1; /* Port map (monitoring) */
3857 + __be32 pmap_2; /* Port map (multicast) */
3858 + __be32 pmap_3; /* Port map (unknown unicast) */
3859 + __be32 gctrl_0; /* Global control 0 */
3860 + __be32 gctrl_1; /* Global control 1 */
3861 + __be32 tcm_gctrl; /* Three-color marker global control */
3862 + __be32 igmp_ctrl; /* IGMP control */
3863 + __be32 igmp_drpm; /* IGMP default router port map */
3864 + __be32 igmp_age_0; /* IGMP aging 0 */
3865 + __be32 igmp_age_1; /* IGMP aging 1 */
3866 + __be32 igmp_stat; /* IGMP status */
3867 + __be32 wol_gctrl; /* Wake-on-LAN control */
3868 + __be32 wol_da_0; /* Wake-on-LAN destination address 0 */
3869 + __be32 wol_da_1; /* Wake-on-LAN destination address 1 */
3870 + __be32 wol_da_2; /* Wake-on-LAN destination address 2 */
3871 + __be32 wol_pw_0; /* Wake-on-LAN password 0 */
3872 + __be32 wol_pw_1; /* Wake-on-LAN password 1 */
3873 + __be32 wol_pw_2; /* Wake-on-LAN password 2 */
3874 + __be32 ier_0; /* PCE global interrupt enable 0 */
3875 + __be32 ier_1; /* PCE global interrupt enable 1 */
3876 + __be32 isr_0; /* PCE global interrupt status 0 */
3877 + __be32 isr_1; /* PCE global interrupt status 1 */
3878 + __be32 parser_stat; /* Parser status */
3879 + __be32 rsvd0[0x6];
3882 + __be32 rsvd0[0x10];
3885 + __be32 pctrl_0; /* Port control 0 */
3886 + __be32 pctrl_1; /* Port control 1 */
3887 + __be32 pctrl_2; /* Port control 2 */
3888 + __be32 pctrl_3; /* Port control 3 */
3889 + __be32 wol_ctrl; /* Wake-on-LAN control */
3890 + __be32 vlan_ctrl; /* VLAN control */
3891 + __be32 def_pvid; /* Default port VID */
3892 + __be32 pstat; /* Port status */
3893 + __be32 pier; /* Interrupt enable */
3894 + __be32 pisr; /* Interrupt status */
3897 + __be32 rsvd1[0x7e];
3899 + struct pce_meter {
3900 + /* TODO: implement registers */
3901 + __be32 rsvd0[0x7];
3904 + __be32 rsvd2[0x308];
3907 +static inline unsigned int to_pce_tbl_key_id(unsigned int id)
3914 +static inline unsigned int to_pce_tbl_value_id(unsigned int id)
3921 +/* Switch ethernet MAC registers */
3922 +struct vr9_switch_mac_regs {
3924 + __be32 test; /* MAC test */
3925 + __be32 pfad_cfg; /* Pause frame source address config */
3926 + __be32 pfsa_0; /* Pause frame source address 0 */
3927 + __be32 pfsa_1; /* Pause frame source address 1 */
3928 + __be32 pfsa_2; /* Pause frame source address 2 */
3929 + __be32 flen; /* Frame length */
3930 + __be32 vlan_etype_0; /* VLAN ethertype 0 */
3931 + __be32 vlan_etype_1; /* VLAN ethertype 1 */
3932 + __be32 ier; /* Interrupt enable */
3933 + __be32 isr; /* Interrupt status */
3934 + __be32 rsvd0[0x36];
3938 + __be32 pstat; /* Port status */
3939 + __be32 pisr; /* Interrupt status */
3940 + __be32 pier; /* Interrupt enable */
3941 + __be32 ctrl_0; /* Control 0 */
3942 + __be32 ctrl_1; /* Control 1 */
3943 + __be32 ctrl_2; /* Control 2 */
3944 + __be32 ctrl_3; /* Control 3 */
3945 + __be32 ctrl_4; /* Control 4 */
3946 + __be32 ctrl_5; /* Control 5 */
3947 + __be32 rsvd0[0x2];
3948 + __be32 testen; /* Test enable */
3951 + __be32 rsvd0[0xa4];
3954 +/* Switch Fetch DMA registers */
3955 +struct vr9_switch_fdma_regs {
3956 + struct fdma_core {
3957 + __be32 ctrl; /* FDMA control */
3958 + __be32 stetype; /* Special tag ethertype control */
3959 + __be32 vtetype; /* VLAN tag ethertype control */
3960 + __be32 stat; /* FDMA status */
3961 + __be32 ier; /* FDMA interrupt enable */
3962 + __be32 isr; /* FDMA interrupt status */
3965 + __be32 rsvd0[0x3a];
3967 + struct fdma_port {
3968 + __be32 pctrl; /* Port control */
3969 + __be32 prio; /* Port priority */
3970 + __be32 pstat_0; /* Port status 0 */
3971 + __be32 pstat_1; /* Port status 1 */
3972 + __be32 tstamp_0; /* Egress time stamp 0 */
3973 + __be32 tstamp_1; /* Egress time stamp 1 */
3976 + __be32 rsvd1[0x72];
3979 +/* Switch Store DMA registers */
3980 +struct vr9_switch_sdma_regs {
3981 + struct sdma_core {
3982 + __be32 ctrl; /* SDMA Control */
3983 + __be32 fcthr_1; /* Flow control threshold 1 */
3985 + __be32 fcthr_3; /* Flow control threshold 3 */
3986 + __be32 fcthr_4; /* Flow control threshold 4 */
3987 + __be32 fcthr_5; /* Flow control threshold 5 */
3988 + __be32 fcthr_6; /* Flow control threshold 6 */
3989 + __be32 fcthr_7; /* Flow control threshold 7 */
3990 + __be32 stat_0; /* SDMA status 0 */
3991 + __be32 stat_1; /* SDMA status 1 */
3992 + __be32 stat_2; /* SDMA status 2 */
3993 + __be32 ier; /* SDMA interrupt enable */
3994 + __be32 isr; /* SDMA interrupt status */
3997 + __be32 rsvd0[0x73];
3999 + struct sdma_port {
4000 + __be32 pctrl; /* Port control */
4001 + __be32 prio; /* Port priority */
4002 + __be32 pstat_0; /* Port status 0 */
4003 + __be32 pstat_1; /* Port status 1 */
4004 + __be32 tstamp_0; /* Ingress time stamp 0 */
4005 + __be32 tstamp_1; /* Ingress time stamp 1 */
4008 + __be32 rsvd1[0x32];
4011 +/* Switch MDIO control and status registers */
4012 +struct vr9_switch_mdio_regs {
4013 + __be32 glob_ctrl; /* Global control 0 */
4015 + __be32 mdio_ctrl; /* MDIO control */
4016 + __be32 mdio_read; /* MDIO read data */
4017 + __be32 mdio_write; /* MDIO write data */
4018 + __be32 mdc_cfg_0; /* MDC clock configuration 0 */
4019 + __be32 mdc_cfg_1; /* MDC clock configuration 1 */
4020 + __be32 rsvd1[0x3];
4021 + __be32 phy_addr[6]; /* PHY address port 5..0 */
4022 + __be32 mdio_stat[6]; /* MDIO PHY polling status port 0..5 */
4023 + __be32 aneg_eee[6]; /* EEE auto-neg overrides port 0..5 */
4024 + __be32 rsvd2[0x14];
4027 +static inline unsigned int to_mdio_phyaddr_id(unsigned int id)
4034 +/* Switch xMII control registers */
4035 +struct vr9_switch_mii_regs {
4036 + __be32 mii_cfg0; /* xMII port 0 configuration */
4037 + __be32 pcdu0; /* Port 0 clock delay configuration */
4038 + __be32 mii_cfg1; /* xMII port 1 configuration */
4039 + __be32 pcdu1; /* Port 1 clock delay configuration */
4040 + __be32 rsvd0[0x6];
4041 + __be32 mii_cfg5; /* xMII port 5 configuration */
4042 + __be32 pcdu5; /* Port 5 clock delay configuration */
4043 + __be32 rsvd1[0x14];
4044 + __be32 rxb_ctl_0; /* Port 0 receive buffer control */
4045 + __be32 rxb_ctl_1; /* Port 1 receive buffer control */
4046 + __be32 rxb_ctl_5; /* Port 5 receive buffer control */
4047 + __be32 rsvd2[0x28];
4048 + __be32 dbg_ctl; /* Debug control */
4051 +/* Switch Pseudo-MAC registers */
4052 +struct vr9_switch_pmac_regs {
4053 + __be32 hd_ctl; /* PMAC header control */
4054 + __be32 tl; /* PMAC type/length */
4055 + __be32 sa1; /* PMAC source address 1 */
4056 + __be32 sa2; /* PMAC source address 2 */
4057 + __be32 sa3; /* PMAC source address 3 */
4058 + __be32 da1; /* PMAC destination address 1 */
4059 + __be32 da2; /* PMAC destination address 2 */
4060 + __be32 da3; /* PMAC destination address 3 */
4061 + __be32 vlan; /* PMAC VLAN */
4062 + __be32 rx_ipg; /* PMAC interpacket gap in RX direction */
4063 + __be32 st_etype; /* PMAC special tag ethertype */
4064 + __be32 ewan; /* PMAC ethernet WAN group */
4065 + __be32 ctl; /* PMAC control */
4066 + __be32 rsvd0[0x2];
4069 +struct vr9_switch_regs {
4070 + struct vr9_switch_core_regs core;
4071 + struct vr9_switch_bm_regs bm;
4072 + struct vr9_switch_pce_regs pce;
4073 + struct vr9_switch_mac_regs mac;
4074 + struct vr9_switch_fdma_regs fdma;
4075 + struct vr9_switch_sdma_regs sdma;
4076 + struct vr9_switch_mdio_regs mdio;
4077 + struct vr9_switch_mii_regs mii;
4078 + struct vr9_switch_pmac_regs pmac;
4081 +static inline void *to_pce_tbl_key(struct vr9_switch_regs *regs,
4084 + return ®s->pce.core.tbl_key[to_pce_tbl_key_id(id)];
4087 +static inline void *to_pce_tbl_value(struct vr9_switch_regs *regs,
4090 + return ®s->pce.core.tbl_val[to_pce_tbl_value_id(id)];
4093 +static inline void *to_mac_ctrl(struct vr9_switch_regs *regs,
4094 + unsigned int id, unsigned int ctrl)
4096 + struct mac_port *mac = ®s->mac.port[id];
4100 + return &mac->ctrl_0;
4102 + return &mac->ctrl_1;
4104 + return &mac->ctrl_2;
4106 + return &mac->ctrl_3;
4108 + return &mac->ctrl_4;
4110 + return &mac->ctrl_5;
4116 +static inline void *to_mdio_phyaddr(struct vr9_switch_regs *regs,
4119 + return ®s->mdio.phy_addr[to_mdio_phyaddr_id(id)];
4122 +static inline void *to_mii_miicfg(struct vr9_switch_regs *regs,
4127 + return ®s->mii.mii_cfg0;
4129 + return ®s->mii.mii_cfg1;
4131 + return ®s->mii.mii_cfg5;
4137 +static inline void *to_mii_pcdu(struct vr9_switch_regs *regs,
4142 + return ®s->mii.pcdu0;
4144 + return ®s->mii.pcdu1;
4146 + return ®s->mii.pcdu5;
4152 +#define VR9_SWITCH_REG_OFFSET(reg) (4 * (reg))
4154 +#define BUILD_CHECK_VR9_REG(name, offset) \
4155 + BUILD_BUG_ON(offsetof(struct vr9_switch_regs, name) != (4 * offset))
4157 +static inline void build_check_vr9_registers(void)
4159 + BUILD_CHECK_VR9_REG(core, 0x0);
4160 + BUILD_CHECK_VR9_REG(bm.core, 0x40);
4161 + BUILD_CHECK_VR9_REG(bm.core.queue_gctrl, 0x4a);
4162 + BUILD_CHECK_VR9_REG(bm.port[0], 0x80);
4163 + BUILD_CHECK_VR9_REG(bm.queue, 0x100);
4164 + BUILD_CHECK_VR9_REG(bm.shaper, 0x140);
4165 + BUILD_CHECK_VR9_REG(pce.core, 0x438);
4166 + BUILD_CHECK_VR9_REG(pce.core.tbl_ctrl, 0x44f);
4167 + BUILD_CHECK_VR9_REG(pce.core.parser_stat, 0x469);
4168 + BUILD_CHECK_VR9_REG(pce.port[0], 0x480);
4169 + BUILD_CHECK_VR9_REG(pce.meter[0], 0x580);
4170 + BUILD_CHECK_VR9_REG(mac.core, 0x8c0);
4171 + BUILD_CHECK_VR9_REG(mac.port[0].pstat, 0x900);
4172 + BUILD_CHECK_VR9_REG(mac.port[0].ctrl_0, 0x903);
4173 + BUILD_CHECK_VR9_REG(mac.port[1].pstat, 0x90c);
4174 + BUILD_CHECK_VR9_REG(mac.port[1].ctrl_0, 0x90f);
4175 + BUILD_CHECK_VR9_REG(mac.port[2].pstat, 0x918);
4176 + BUILD_CHECK_VR9_REG(mac.port[2].ctrl_0, 0x91b);
4177 + BUILD_CHECK_VR9_REG(fdma.core, 0xa40);
4178 + BUILD_CHECK_VR9_REG(fdma.port[0], 0xa80);
4179 + BUILD_CHECK_VR9_REG(sdma.core, 0xb40);
4180 + BUILD_CHECK_VR9_REG(sdma.port[0], 0xbc0);
4181 + BUILD_CHECK_VR9_REG(mdio, 0xc40);
4182 + BUILD_CHECK_VR9_REG(mii, (0xc40 + 0x36));
4183 + BUILD_CHECK_VR9_REG(pmac, (0xc40 + 0x82));
4186 +#define BM_GCTRL_F_SRES 1
4188 +#define MAC_CTRL0_BM (1 << 12)
4189 +#define MAC_CTRL0_APADEN (1 << 11)
4190 +#define MAC_CTRL0_VPAD2EN (1 << 10)
4191 +#define MAC_CTRL0_VPADEN (1 << 9)
4192 +#define MAC_CTRL0_PADEN (1 << 8)
4193 +#define MAC_CTRL0_FCS (1 << 7)
4194 +#define MAC_CTRL0_FCON_SHIFT 4
4195 +#define MAC_CTRL0_FCON_AUTO (0x0 << MAC_CTRL0_FCON_SHIFT)
4196 +#define MAC_CTRL0_FCON_RX (0x1 << MAC_CTRL0_FCON_SHIFT)
4197 +#define MAC_CTRL0_FCON_TX (0x2 << MAC_CTRL0_FCON_SHIFT)
4198 +#define MAC_CTRL0_FCON_RXTX (0x3 << MAC_CTRL0_FCON_SHIFT)
4199 +#define MAC_CTRL0_FCON_NONE (0x4 << MAC_CTRL0_FCON_SHIFT)
4200 +#define MAC_CTRL0_FDUP_SHIFT 2
4201 +#define MAC_CTRL0_FDUP_AUTO (0x0 << MAC_CTRL0_FDUP_SHIFT)
4202 +#define MAC_CTRL0_FDUP_EN (0x1 << MAC_CTRL0_FDUP_SHIFT)
4203 +#define MAC_CTRL0_FDUP_DIS (0x3 << MAC_CTRL0_FDUP_SHIFT)
4204 +#define MAC_CTRL0_GMII_AUTO 0x0
4205 +#define MAC_CTRL0_GMII_MII 0x1
4206 +#define MAC_CTRL0_GMII_GMII 0x2
4207 +#define MAC_CTRL0_GMII_GMII_2G 0x3
4209 +#define MAC_CTRL1_DEFERMODE (1 << 15)
4210 +#define MAC_CTRL1_SHORTPRE (1 << 8)
4212 +#define MAC_CTRL2_MLEN (1 << 3)
4213 +#define MAC_CTRL2_LCHKL (1 << 2)
4214 +#define MAC_CTRL2_LCHKS_DIS 0x0
4215 +#define MAC_CTRL2_LCHKS_UNTAG 0x1
4216 +#define MAC_CTRL2_LCHKS_TAG 0x2
4218 +#define PHY_ADDR_LNKST_SHIFT 13
4219 +#define PHY_ADDR_LNKST_AUTO (0x0 << PHY_ADDR_LNKST_SHIFT)
4220 +#define PHY_ADDR_LNKST_UP (0x1 << PHY_ADDR_LNKST_SHIFT)
4221 +#define PHY_ADDR_LNKST_DOWN (0x2 << PHY_ADDR_LNKST_SHIFT)
4222 +#define PHY_ADDR_SPEED_SHIFT 11
4223 +#define PHY_ADDR_SPEED_M10 (0x0 << PHY_ADDR_SPEED_SHIFT)
4224 +#define PHY_ADDR_SPEED_M100 (0x1 << PHY_ADDR_SPEED_SHIFT)
4225 +#define PHY_ADDR_SPEED_G1 (0x2 << PHY_ADDR_SPEED_SHIFT)
4226 +#define PHY_ADDR_SPEED_AUTO (0x3 << PHY_ADDR_SPEED_SHIFT)
4227 +#define PHY_ADDR_FDUP_SHIFT 9
4228 +#define PHY_ADDR_FDUP_AUTO (0x0 << PHY_ADDR_FDUP_SHIFT)
4229 +#define PHY_ADDR_FDUP_EN (0x1 << PHY_ADDR_FDUP_SHIFT)
4230 +#define PHY_ADDR_FDUP_DIS (0x3 << PHY_ADDR_FDUP_SHIFT)
4231 +#define PHY_ADDR_FCONTX_SHIFT 7
4232 +#define PHY_ADDR_FCONTX_AUTO (0x0 << PHY_ADDR_FCONTX_SHIFT)
4233 +#define PHY_ADDR_FCONTX_EN (0x1 << PHY_ADDR_FCONTX_SHIFT)
4234 +#define PHY_ADDR_FCONTX_DIS (0x3 << PHY_ADDR_FCONTX_SHIFT)
4235 +#define PHY_ADDR_FCONRX_SHIFT 5
4236 +#define PHY_ADDR_FCONRX_AUTO (0x0 << PHY_ADDR_FCONRX_SHIFT)
4237 +#define PHY_ADDR_FCONRX_EN (0x1 << PHY_ADDR_FCONRX_SHIFT)
4238 +#define PHY_ADDR_FCONRX_DIS (0x3 << PHY_ADDR_FCONRX_SHIFT)
4240 +#define MII_CFG_RES (1 << 15)
4241 +#define MII_CFG_EN (1 << 14)
4242 +#define MII_CFG_LDCLKDIS (1 << 12)
4243 +#define MII_CFG_MIIRATE_SHIFT 4
4244 +#define MII_CFG_MIIRATE_MASK (0x7 << MII_CFG_MIIRATE_SHIFT)
4245 +#define MII_CFG_MIIRATE_M2P5 (0x0 << MII_CFG_MIIRATE_SHIFT)
4246 +#define MII_CFG_MIIRATE_M25 (0x1 << MII_CFG_MIIRATE_SHIFT)
4247 +#define MII_CFG_MIIRATE_M125 (0x2 << MII_CFG_MIIRATE_SHIFT)
4248 +#define MII_CFG_MIIRATE_M50 (0x3 << MII_CFG_MIIRATE_SHIFT)
4249 +#define MII_CFG_MIIRATE_AUTO (0x4 << MII_CFG_MIIRATE_SHIFT)
4250 +#define MII_CFG_MIIMODE_MASK 0xf
4251 +#define MII_CFG_MIIMODE_MIIP 0x0
4252 +#define MII_CFG_MIIMODE_MIIM 0x1
4253 +#define MII_CFG_MIIMODE_RMIIP 0x2
4254 +#define MII_CFG_MIIMODE_RMIIM 0x3
4255 +#define MII_CFG_MIIMODE_RGMII 0x4
4257 +#define PCDU_RXDLY_SHIFT 7
4258 +#define PCDU_RXDLY_MASK (0x7 << PCDU_RXDLY_SHIFT)
4259 +#define PCDU_TXDLY_MASK 0x7
4261 +#define PMAC_HD_CTL_FC (1 << 10)
4262 +#define PMAC_HD_CTL_CCRC (1 << 9)
4263 +#define PMAC_HD_CTL_RST (1 << 8)
4264 +#define PMAC_HD_CTL_AST (1 << 7)
4265 +#define PMAC_HD_CTL_RXSH (1 << 6)
4266 +#define PMAC_HD_CTL_RC (1 << 4)
4267 +#define PMAC_HD_CTL_AS (1 << 3)
4268 +#define PMAC_HD_CTL_AC (1 << 2)
4270 +#define PCE_PCTRL_0_IGSTEN (1 << 11)
4272 +#define FDMA_PCTRL_STEN (1 << 1)
4273 +#define FDMA_PCTRL_EN (1 << 0)
4275 +#define SDMA_PCTRL_EN (1 << 0)
4277 +#define MDIO_GLOB_CTRL_SE (1 << 15)
4279 +#define MDIO_MDC_CFG1_RES (1 << 15)
4280 +#define MDIO_MDC_CFG1_MCEN (1 << 8)
4282 +#define MDIO_CTRL_MBUSY (1 << 12)
4283 +#define MDIO_CTRL_OP_READ (1 << 11)
4284 +#define MDIO_CTRL_OP_WRITE (1 << 10)
4285 +#define MDIO_CTRL_PHYAD_SHIFT 5
4286 +#define MDIO_CTRL_PHYAD_MASK (0x1f << MDIO_CTRL_PHYAD_SHIFT)
4287 +#define MDIO_CTRL_REGAD_MASK 0x1f
4289 +#endif /* __VRX200_SWITCH_H__ */
4290 --- a/arch/mips/include/asm/asm.h
4291 +++ b/arch/mips/include/asm/asm.h
4294 .type symbol, @function; \
4296 + .section .text.symbol,"x"; \
4297 symbol: .frame sp, 0, ra
4300 @@ -62,7 +63,8 @@ symbol: .frame sp, 0, ra
4303 .type symbol, @function; \
4306 + .section .text.symbol,"x"; \
4307 symbol: .frame sp, framesize, rpc
4311 +++ b/arch/mips/include/asm/gpio.h
4314 + * SPDX-License-Identifier: GPL-2.0+
4317 +#include <asm/arch/gpio.h>
4318 +#include <asm-generic/gpio.h>
4320 +++ b/arch/mips/include/asm/lantiq/chipid.h
4323 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
4325 + * SPDX-License-Identifier: GPL-2.0+
4328 +#ifndef __LANTIQ_CHIPID_H__
4329 +#define __LANTIQ_CHIPID_H__
4331 +enum ltq_chip_partnum {
4332 + LTQ_SOC_UNKNOWN = 0,
4333 + LTQ_SOC_VRX288_2 = 0x000B, /* VRX288 v1.2 */
4334 + LTQ_SOC_VRX268_2 = 0x000C, /* VRX268 v1.2 */
4335 + LTQ_SOC_GRX288_2 = 0x000D, /* GRX288 v1.2 */
4336 + LTQ_SOC_DANUBE = 0x0129,
4337 + LTQ_SOC_DANUBE_S = 0x012B,
4338 + LTQ_SOC_TWINPASS = 0x012D,
4339 + LTQ_SOC_VRX288 = 0x01C0, /* VRX288 v1.1 */
4340 + LTQ_SOC_VRX268 = 0x01C2, /* VRX268 v1.1 */
4341 + LTQ_SOC_GRX288 = 0x01C9, /* GRX288 v1.1 */
4344 +extern unsigned int ltq_chip_version_get(void);
4345 +extern unsigned int ltq_chip_partnum_get(void);
4346 +extern const char *ltq_chip_partnum_str(void);
4348 +extern void ltq_chip_print_info(void);
4350 +#ifdef CONFIG_SOC_XWAY_DANUBE
4351 +static inline int ltq_soc_is_danube(void)
4356 +static inline int ltq_soc_is_danube(void)
4362 +#ifdef CONFIG_SOC_XWAY_VRX200
4363 +static inline int ltq_soc_is_vrx200(void)
4368 +static inline int ltq_soc_is_vrx200_v1(void)
4370 + return ltq_chip_version_get() == 1;
4373 +static inline int ltq_soc_is_vrx200_v2(void)
4375 + return ltq_chip_version_get() == 2;
4378 +static inline int ltq_soc_is_vrx200(void)
4383 +static inline int ltq_soc_is_vrx200_v1(void)
4388 +static inline int ltq_soc_is_vrx200_v2(void)
4394 +#endif /* __LANTIQ_CHIPID_H__ */
4396 +++ b/arch/mips/include/asm/lantiq/clk.h
4399 + * Copyright (C) 2007-2010 Lantiq Deutschland GmbH
4400 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
4402 + * SPDX-License-Identifier: GPL-2.0+
4405 +#ifndef __LANTIQ_CLK_H__
4406 +#define __LANTIQ_CLK_H__
4408 +/* Symbolic clock speeds */
4410 + CLOCK_83_MHZ = 83333333,
4411 + CLOCK_111_MHZ = 111111111,
4412 + CLOCK_125_MHZ = 125000000,
4413 + CLOCK_133_MHZ = 133333333,
4414 + CLOCK_166_MHZ = 166666667,
4415 + CLOCK_197_MHZ = 197000000,
4416 + CLOCK_333_MHZ = 333333333,
4417 + CLOCK_393_MHZ = 393219000,
4418 + CLOCK_500_MHZ = 500000000,
4419 + CLOCK_600_MHZ = 600000000,
4420 + CLOCK_1000_MHZ = 1000000000,
4423 +extern unsigned long ltq_get_cpu_clock(void);
4424 +extern unsigned long ltq_get_bus_clock(void);
4425 +extern unsigned long ltq_get_io_region_clock(void);
4427 +#endif /* __LANTIQ_CLK_H__ */
4429 +++ b/arch/mips/include/asm/lantiq/config.h
4432 + * Copyright (C) 2007-2010 Lantiq Deutschland GmbH
4433 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
4435 + * SPDX-License-Identifier: GPL-2.0+
4438 +#ifndef __LANTIQ_CONFIG_H__
4439 +#define __LANTIQ_CONFIG_H__
4442 +#define CONFIG_SYS_MAXARGS 24
4443 +#define CONFIG_SYS_MALLOC_LEN 1024*1024
4444 +#define CONFIG_SYS_BOOTPARAMS_LEN 128*1024
4447 +#define CONFIG_SYS_PROMPT CONFIG_MACH_TYPE " # "
4448 +#define CONFIG_SYS_CBSIZE 512
4449 +#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + \
4450 + sizeof(CONFIG_SYS_PROMPT)+16)
4452 +#define CONFIG_SYS_HUSH_PARSER
4453 +#define CONFIG_SYS_PROMPT_HUSH_PS2 "> "
4456 + * Enable advanced console features on demand to reduce
4457 + * flash and RAM footprint
4459 +#if defined(CONFIG_LTQ_ADVANCED_CONSOLE)
4460 +#define CONFIG_SYS_LONGHELP
4461 +#define CONFIG_AUTO_COMPLETE
4462 +#define CONFIG_CMDLINE_EDITING
4465 +/* SPI flash SPL */
4466 +#if defined(CONFIG_LTQ_SUPPORT_SPL_SPI_FLASH) && defined(CONFIG_SYS_BOOT_SFSPL)
4468 +#define CONFIG_SPL_SPI_SUPPORT
4469 +#define CONFIG_SPL_SPI_FLASH_SUPPORT
4470 +#define CONFIG_SPI_SPL_SIMPLE
4473 +#if defined(CONFIG_LTQ_SUPPORT_SPL_NOR_FLASH) && defined(CONFIG_SYS_BOOT_NORSPL)
4478 +#if defined(CONFIG_SPL)
4479 +#define CONFIG_SKIP_LOWLEVEL_INIT
4480 +#define CONFIG_SPL_LIBGENERIC_SUPPORT
4481 +#define CONFIG_SPL_GPIO_SUPPORT
4482 +#define CONFIG_SPL_START_S_PATH \
4483 + "arch/mips/cpu/mips32/lantiq-common"
4484 +#define CONFIG_SPL_LDSCRIPT \
4485 + "arch/mips/cpu/mips32/lantiq-common/u-boot-spl.lds"
4488 +#if defined(CONFIG_LTQ_SPL_CONSOLE)
4489 +#define CONFIG_SPL_SERIAL_SUPPORT
4490 +#define CONFIG_SPL_LIBCOMMON_SUPPORT
4493 +#if defined(CONFIG_LTQ_SPL_COMP_LZMA)
4494 +#define CONFIG_LZMA
4495 +#define CONFIG_SPL_LZMA_SUPPORT
4498 +#if defined(CONFIG_LTQ_SPL_COMP_LZO)
4500 +#define CONFIG_SPL_LZO_SUPPORT
4503 +/* Basic commands */
4504 +#define CONFIG_CMD_BDI
4505 +#define CONFIG_CMD_EDITENV
4506 +#define CONFIG_CMD_IMI
4507 +#define CONFIG_CMD_MEMORY
4508 +#define CONFIG_CMD_RUN
4509 +#define CONFIG_CMD_SAVEENV
4510 +#define CONFIG_CMD_LOADB
4512 +/* Other U-Boot settings */
4513 +#define CONFIG_TIMESTAMP
4515 +/* Default environment */
4516 +#define CONFIG_ENV_CONSOLEDEV \
4517 + "consoledev=" CONFIG_CONSOLE_DEV "\0"
4519 +#define CONFIG_ENV_ADDCONSOLE \
4520 + "addconsole=setenv bootargs $bootargs" \
4521 + " console=$consoledev,$baudrate\0"
4523 +#if defined(CONFIG_NET_DEV)
4524 +#define CONFIG_ENV_NETDEV \
4525 + "netdev=" CONFIG_NET_DEV "\0"
4527 +#define CONFIG_ENV_NETDEV \
4531 +#define CONFIG_ENV_ADDIP \
4532 + "addip=setenv bootargs $bootargs" \
4533 + " ip=$ipaddr:$serverip::::$netdev:off\0"
4535 +#define CONFIG_ENV_ADDETH \
4536 + "addeth=setenv bootargs $bootargs" \
4537 + " ethaddr=$ethaddr\0"
4539 +#define CONFIG_ENV_ADDMACHTYPE \
4540 + "addmachtype=setenv bootargs $bootargs" \
4541 + " machtype=" CONFIG_MACH_TYPE "\0"
4543 +#if defined(CONFIG_LTQ_SUPPORT_NOR_FLASH)
4544 +#define CONFIG_ENV_WRITE_UBOOT_NOR \
4545 + "write-uboot-nor=" \
4546 + "protect off " __stringify(CONFIG_SYS_FLASH_BASE) " +$filesize && " \
4547 + "erase " __stringify(CONFIG_SYS_FLASH_BASE) " +$filesize && " \
4548 + "cp.b $fileaddr " __stringify(CONFIG_SYS_FLASH_BASE) " $filesize\0"
4550 +#define CONFIG_ENV_LOAD_UBOOT_NOR \
4551 + "load-uboot-nor=tftpboot u-boot.bin\0" \
4552 + "load-uboot-norspl=tftpboot u-boot.ltq.norspl\0" \
4553 + "load-uboot-norspl-lzo=tftpboot u-boot.ltq.lzo.norspl\0" \
4554 + "load-uboot-norspl-lzma=tftpboot u-boot.ltq.lzma.norspl\0"
4556 +#define CONFIG_ENV_WRITE_UBOOT_NOR
4557 +#define CONFIG_ENV_LOAD_UBOOT_NOR
4560 +#if defined(CONFIG_LTQ_SUPPORT_SPI_FLASH)
4561 +#define CONFIG_ENV_SF_PROBE \
4562 + "sf-probe=sf probe " __stringify(CONFIG_ENV_SPI_CS) " " \
4563 + __stringify(CONFIG_ENV_SPI_MAX_HZ) " " \
4564 + __stringify(CONFIG_ENV_SPI_MODE) " \0"
4566 +#define CONFIG_ENV_WRITE_UBOOT_SF \
4567 + "write-uboot-sf=" \
4568 + "run sf-probe && sf erase 0 +$filesize && " \
4569 + "sf write $fileaddr 0 $filesize\0"
4571 +#define CONFIG_ENV_LOAD_UBOOT_SF \
4572 + "load-uboot-sfspl=tftpboot u-boot.ltq.sfspl\0" \
4573 + "load-uboot-sfspl-lzo=tftpboot u-boot.ltq.lzo.sfspl\0" \
4574 + "load-uboot-sfspl-lzma=tftpboot u-boot.ltq.lzma.sfspl\0"
4576 +#define CONFIG_ENV_SF_PROBE
4577 +#define CONFIG_ENV_WRITE_UBOOT_SF
4578 +#define CONFIG_ENV_LOAD_UBOOT_SF
4581 +#define CONFIG_ENV_LANTIQ_DEFAULTS \
4582 + CONFIG_ENV_CONSOLEDEV \
4583 + CONFIG_ENV_ADDCONSOLE \
4584 + CONFIG_ENV_NETDEV \
4585 + CONFIG_ENV_ADDIP \
4586 + CONFIG_ENV_ADDETH \
4587 + CONFIG_ENV_ADDMACHTYPE \
4588 + CONFIG_ENV_WRITE_UBOOT_NOR \
4589 + CONFIG_ENV_LOAD_UBOOT_NOR \
4590 + CONFIG_ENV_SF_PROBE \
4591 + CONFIG_ENV_WRITE_UBOOT_SF \
4592 + CONFIG_ENV_LOAD_UBOOT_SF
4594 +#endif /* __LANTIQ_CONFIG_H__ */
4596 +++ b/arch/mips/include/asm/lantiq/cpu.h
4599 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
4601 + * SPDX-License-Identifier: GPL-2.0+
4604 +#ifndef __LANTIQ_CPU_H__
4605 +#define __LANTIQ_CPU_H__
4607 +enum ltq_boot_select {
4609 + BOOT_NOR_NO_BOOTROM,
4611 + BOOT_UART_NO_EEPROM,
4621 +enum ltq_boot_select ltq_boot_select(void);
4622 +const char *ltq_boot_select_str(void);
4624 +void ltq_pmu_init(void);
4625 +void ltq_ebu_init(void);
4626 +void ltq_gpio_init(void);
4628 +void ltq_pll_init(void);
4629 +void ltq_dcdc_init(unsigned int dig_ref);
4631 +#endif /* __LANTIQ_CPU_H__ */
4633 +++ b/arch/mips/include/asm/lantiq/dma.h
4636 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
4638 + * SPDX-License-Identifier: GPL-2.0+
4641 +#ifndef __LANTIQ_DMA_H__
4642 +#define __LANTIQ_DMA_H__
4644 +enum ltq_dma_endianess {
4645 + LTQ_DMA_ENDIANESS_B0_B1_B2_B3, /* No byte swapping */
4646 + LTQ_DMA_ENDIANESS_B1_B0_B3_B2, /* B0B1B2B3 => B1B0B3B2 */
4647 + LTQ_DMA_ENDIANESS_B2_B3_B0_B1, /* B0B1B2B3 => B2B3B0B1 */
4648 + LTQ_DMA_ENDIANESS_B3_B2_B1_B0, /* B0B1B2B3 => B3B2B1B0 */
4651 +enum ltq_dma_burst_len {
4652 + LTQ_DMA_BURST_2WORDS = 1,
4653 + LTQ_DMA_BURST_4WORDS = 2,
4654 + LTQ_DMA_BURST_8WORDS = 3,
4657 +struct ltq_dma_desc {
4662 +struct ltq_dma_channel {
4663 + struct ltq_dma_device *dev;
4667 + struct ltq_dma_desc *desc_base;
4672 +struct ltq_dma_device {
4673 + enum ltq_dma_endianess rx_endian_swap;
4674 + enum ltq_dma_endianess tx_endian_swap;
4675 + enum ltq_dma_burst_len rx_burst_len;
4676 + enum ltq_dma_burst_len tx_burst_len;
4677 + struct ltq_dma_channel rx_chan;
4678 + struct ltq_dma_channel tx_chan;
4683 + * Initialize DMA hardware and driver
4685 +void ltq_dma_init(void);
4688 + * Register given DMA client context
4690 + * @returns 0 on success, negative value otherwise
4692 +int ltq_dma_register(struct ltq_dma_device *dev);
4695 + * Reset and halt all channels related to given DMA client
4697 +void ltq_dma_reset(struct ltq_dma_device *dev);
4698 +void ltq_dma_enable(struct ltq_dma_device *dev);
4699 +void ltq_dma_disable(struct ltq_dma_device *dev);
4702 + * Map RX DMA descriptor to memory region
4704 + * @returns 0 on success, negative value otherwise
4706 +int ltq_dma_rx_map(struct ltq_dma_device *dev, int index, void *data, int len);
4709 + * Check if new data is available.
4711 + * @returns length of received data, 0 otherwise
4713 +int ltq_dma_rx_poll(struct ltq_dma_device *dev, int index);
4715 +int ltq_dma_rx_length(struct ltq_dma_device *dev, int index);
4718 + * Map TX DMA descriptor to memory region
4720 + * @returns 0 on success, negative value otherwise
4722 +int ltq_dma_tx_map(struct ltq_dma_device *dev, int index, void *data, int len,
4723 + unsigned long timeout);
4725 +int ltq_dma_tx_wait(struct ltq_dma_device *dev, int index,
4726 + unsigned long timeout);
4728 +#endif /* __LANTIQ_DMA_H__ */
4730 +++ b/arch/mips/include/asm/lantiq/eth.h
4733 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
4735 + * SPDX-License-Identifier: GPL-2.0+
4738 +#ifndef __LANTIQ_ETH_H__
4739 +#define __LANTIQ_ETH_H__
4743 +enum LTQ_ETH_PORT_FLAGS {
4744 + LTQ_ETH_PORT_NONE = 0,
4745 + LTQ_ETH_PORT_PHY = 1,
4746 + LTQ_ETH_PORT_SWITCH = (1 << 1),
4747 + LTQ_ETH_PORT_MAC = (1 << 2),
4750 +struct ltq_eth_port_config {
4754 + phy_interface_t phy_if;
4755 + u8 rgmii_rx_delay;
4756 + u8 rgmii_tx_delay;
4759 +struct ltq_eth_board_config {
4760 + const struct ltq_eth_port_config *ports;
4764 +extern int ltq_eth_initialize(const struct ltq_eth_board_config *board_config);
4766 +#endif /* __LANTIQ_ETH_H__ */
4768 +++ b/arch/mips/include/asm/lantiq/gpio.h
4771 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
4773 + * SPDX-License-Identifier: GPL-2.0+
4776 +#ifndef __LANTIQ_GPIO_H__
4777 +#define __LANTIQ_GPIO_H__
4779 +enum ltq_gpio_dir {
4785 + GPIO_OD_ACTIVE = 0,
4789 +enum ltq_gpio_altsel {
4790 + GPIO_ALTSEL_CLR = 0,
4794 +extern int gpio_set_altfunc(unsigned gpio, int altsel0, int altsel1, int dir);
4795 +extern int gpio_set_opendrain(unsigned gpio, int od);
4797 +static inline int gpio_to_port(unsigned gpio)
4802 +static inline int gpio_to_pin(unsigned gpio)
4804 + return gpio & 0xF;
4807 +static inline int gpio_to_bit(unsigned gpio)
4809 + return 1 << gpio_to_pin(gpio);
4812 +static inline int gpio_to_gpio(unsigned port, unsigned pin)
4814 + return (port << 4) | (pin & 0xF);
4817 +#include <asm-generic/gpio.h>
4819 +#endif /* __LANTIQ_GPIO_H__ */
4821 +++ b/arch/mips/include/asm/lantiq/io.h
4824 + * Copyright (C) 2010 John Crispin <blogic@openwrt.org>
4825 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
4827 + * SPDX-License-Identifier: GPL-2.0+
4830 +#ifndef __LANTIQ_IO_H__
4831 +#define __LANTIQ_IO_H__
4833 +#include <asm/io.h>
4835 +#define ltq_readb(a) __raw_readb(a)
4836 +#define ltq_writeb(a, v) __raw_writeb(v, a)
4838 +#define ltq_readl(a) __raw_readl(a)
4839 +#define ltq_writel(a, v) __raw_writel(v, a)
4841 +#define ltq_clrbits(a, clear) \
4842 + ltq_writel(a, ltq_readl(a) & ~(clear))
4844 +#define ltq_setbits(a, set) \
4845 + ltq_writel(a, ltq_readl(a) | (set))
4847 +#define ltq_clrsetbits(a, clear, set) \
4848 + ltq_writel(a, (ltq_readl(a) & ~(clear)) | (set))
4850 +static inline void ltq_reg_dump(const void *addr, const char *desc)
4854 + data = ltq_readl(addr);
4855 + printf("ltq_reg_dump: %s 0x%p = 0x%08x\n",
4856 + desc, addr, data);
4859 +#endif /* __LANTIQ_IO_H__ */
4861 +++ b/arch/mips/include/asm/lantiq/pm.h
4864 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
4866 + * SPDX-License-Identifier: GPL-2.0+
4869 +#ifndef __LANTIQ_PM_H__
4870 +#define __LANTIQ_PM_H__
4872 +enum ltq_pm_modules {
4879 +u32 ltq_pm_map(enum ltq_pm_modules module);
4880 +int ltq_pm_enable(enum ltq_pm_modules module);
4881 +int ltq_pm_disable(enum ltq_pm_modules module);
4883 +#endif /* __LANTIQ_PM_H__ */
4885 +++ b/arch/mips/include/asm/lantiq/reset.h
4888 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
4890 + * SPDX-License-Identifier: GPL-2.0+
4893 +#ifndef __LANTIQ_RESET_H__
4894 +#define __LANTIQ_RESET_H__
4896 +enum ltq_reset_modules {
4905 +extern u32 ltq_reset_map(enum ltq_reset_modules module);
4906 +extern int ltq_reset_activate(enum ltq_reset_modules module);
4907 +extern int ltq_reset_deactivate(enum ltq_reset_modules module);
4909 +static inline int ltq_reset_once(enum ltq_reset_modules module, ulong usec)
4913 + ret = ltq_reset_activate(module);
4918 + ret = ltq_reset_deactivate(module);
4923 +#endif /* __LANTIQ_RESET_H__ */
4924 --- a/arch/mips/include/asm/mipsregs.h
4925 +++ b/arch/mips/include/asm/mipsregs.h
4927 #define CP0_ENTRYLO1 $3
4929 #define CP0_CONTEXT $4
4930 +#define CP0_CONTEXTCONFIG $4,1
4931 +#define CP0_USERLOCAL $4,1
4932 #define CP0_PAGEMASK $5
4933 +#define CP0_PAGEGRAIN $5,1
4934 #define CP0_WIRED $6
4936 #define CP0_BADVADDR $8
4938 #define CP0_ENTRYHI $10
4939 #define CP0_COMPARE $11
4940 #define CP0_STATUS $12
4941 +#define CP0_INTCTL $12,1
4942 +#define CP0_SRSCTL $12,2
4943 +#define CP0_SRSMAP $12,3
4944 +#define CP0_SRSHIGH $12,4
4945 #define CP0_CAUSE $13
4947 #define CP0_PRID $15
4948 +#define CP0_EBASE $15,1
4949 #define CP0_CONFIG $16
4950 +#define CP0_CONFIG1 $16,1
4951 +#define CP0_CONFIG2 $16,2
4952 +#define CP0_CONFIG3 $16,3
4953 +#define CP0_CONFIG7 $16,7
4954 #define CP0_LLADDR $17
4955 #define CP0_WATCHLO $18
4956 #define CP0_WATCHHI $19
4959 #define CP0_CACHEERR $27
4960 #define CP0_TAGLO $28
4961 +#define CP0_ITAGLO $28
4962 +#define CP0_IDATALO $28,1
4963 +#define CP0_DTAGLO $28,2
4964 +#define CP0_DDATALO $28,3
4965 +#define CP0_L23TAGLO $28,4
4966 +#define CP0_L23DATALO $28,5
4967 #define CP0_TAGHI $29
4968 +#define CP0_IDATAHI $29,1
4969 +#define CP0_DTAGHI $29,2
4970 +#define CP0_L23TAGHI $29,4
4971 +#define CP0_L23DATAHI $29,5
4972 #define CP0_ERROREPC $30
4973 #define CP0_DESAVE $31
4975 @@ -395,6 +417,12 @@
4976 #define CAUSEF_BD (_ULCAST_(1) << 31)
4979 + * Bits in the coprocessor 0 EBase register.
4981 +#define EBASEB_CPUNUM 0
4982 +#define EBASEF_CPUNUM (_ULCAST_(1023))
4985 * Bits in the coprocessor 0 config register.
4988 --- a/arch/mips/include/asm/u-boot-mips.h
4989 +++ b/arch/mips/include/asm/u-boot-mips.h
4990 @@ -23,3 +23,4 @@ static inline unsigned long image_copy_e
4993 extern int incaip_set_cpuclk(void);
4994 +extern int arch_cpu_init(void);
4995 --- a/arch/mips/lib/board.c
4996 +++ b/arch/mips/lib/board.c
4997 @@ -33,6 +33,16 @@ static char *failed = "*** failed ***\n"
4999 const unsigned long mips_io_port_base = -1;
5001 +int __arch_cpu_init(void)
5004 + * Nothing to do in this dummy implementation
5008 +int arch_cpu_init(void)
5009 + __attribute__((weak, alias("__arch_cpu_init")));
5011 int __board_early_init_f(void)
5014 @@ -106,6 +116,7 @@ static int init_baudrate(void)
5015 typedef int (init_fnc_t)(void);
5017 init_fnc_t *init_sequence[] = {
5021 env_init, /* initialize environment */
5022 --- a/drivers/dma/Makefile
5023 +++ b/drivers/dma/Makefile
5024 @@ -12,6 +12,7 @@ LIB := $(obj)libdma.o
5025 COBJS-$(CONFIG_FSLDMAFEC) += MCD_tasksInit.o MCD_dmaApi.o MCD_tasks.o
5026 COBJS-$(CONFIG_APBH_DMA) += apbh_dma.o
5027 COBJS-$(CONFIG_FSL_DMA) += fsl_dma.o
5028 +COBJS-$(CONFIG_LANTIQ_DMA) += lantiq_dma.o
5029 COBJS-$(CONFIG_OMAP3_DMA) += omap3_dma.o
5033 +++ b/drivers/dma/lantiq_dma.c
5036 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
5038 + * SPDX-License-Identifier: GPL-2.0+
5041 +#include <common.h>
5042 +#include <malloc.h>
5043 +#include <watchdog.h>
5044 +#include <linux/compiler.h>
5045 +#include <asm/lantiq/io.h>
5046 +#include <asm/lantiq/dma.h>
5047 +#include <asm/lantiq/pm.h>
5048 +#include <asm/lantiq/reset.h>
5049 +#include <asm/arch/soc.h>
5050 +#include <asm/processor.h>
5052 +#define DMA_CTRL_PKTARB (1 << 31)
5053 +#define DMA_CTRL_MBRSTARB (1 << 30)
5054 +#define DMA_CTRL_MBRSTCNT_SHIFT 16
5055 +#define DMA_CTRL_MBRSTCNT_MASK (0x3ff << DMA_CTRL_MBRSTCNT_SHIFT)
5056 +#define DMA_CTRL_DRB (1 << 8)
5057 +#define DMA_CTRL_RESET (1 << 0)
5059 +#define DMA_CPOLL_EN (1 << 31)
5060 +#define DMA_CPOLL_CNT_SHIFT 4
5061 +#define DMA_CPOLL_CNT_MASK (0xFFF << DMA_CPOLL_CNT_SHIFT)
5063 +#define DMA_CCTRL_TXWGT_SHIFT 16
5064 +#define DMA_CCTRL_TXWGT_MASK (0x3 << DMA_CCTRL_TXWGT_SHIFT)
5065 +#define DMA_CCTRL_CLASS_SHIFT 9
5066 +#define DMA_CCTRL_CLASS_MASK (0x3 << DMA_CCTRL_CLASS_SHIFT)
5067 +#define DMA_CCTRL_RST (1 << 1)
5068 +#define DMA_CCTRL_ONOFF (1 << 0)
5070 +#define DMA_PCTRL_TXBL_SHIFT 4
5071 +#define DMA_PCTRL_TXBL_2WORDS (1 << DMA_PCTRL_TXBL_SHIFT)
5072 +#define DMA_PCTRL_TXBL_4WORDS (2 << DMA_PCTRL_TXBL_SHIFT)
5073 +#define DMA_PCTRL_TXBL_8WORDS (3 << DMA_PCTRL_TXBL_SHIFT)
5074 +#define DMA_PCTRL_RXBL_SHIFT 2
5075 +#define DMA_PCTRL_RXBL_2WORDS (1 << DMA_PCTRL_RXBL_SHIFT)
5076 +#define DMA_PCTRL_RXBL_4WORDS (2 << DMA_PCTRL_RXBL_SHIFT)
5077 +#define DMA_PCTRL_RXBL_8WORDS (3 << DMA_PCTRL_RXBL_SHIFT)
5078 +#define DMA_PCTRL_TXENDI_SHIFT 10
5079 +#define DMA_PCTRL_TXENDI_MASK (0x3 << DMA_PCTRL_TXENDI_SHIFT)
5080 +#define DMA_PCTRL_RXENDI_SHIFT 8
5081 +#define DMA_PCTRL_RXENDI_MASK (0x3 << DMA_PCTRL_RXENDI_SHIFT)
5083 +#define DMA_DESC_OWN (1 << 31)
5084 +#define DMA_DESC_C (1 << 30)
5085 +#define DMA_DESC_SOP (1 << 29)
5086 +#define DMA_DESC_EOP (1 << 28)
5087 +#define DMA_DESC_TX_OFFSET(x) ((x & 0x1f) << 23)
5088 +#define DMA_DESC_RX_OFFSET(x) ((x & 0x3) << 23)
5089 +#define DMA_DESC_LENGTH(x) (x & 0xffff)
5091 +#define PTR_ALIGN(p, a) ((typeof(p))ALIGN((unsigned long)(p), (a)))
5093 +struct ltq_dma_regs {
5094 + u32 clc; /* Clock control */
5096 + u32 id; /* Identification */
5098 + u32 ctrl; /* Control */
5099 + u32 cpoll; /* Channel polling */
5100 + u32 cs; /* Channel select */
5101 + u32 cctrl; /* Channel control */
5102 + u32 cdba; /* Channel descriptor base address */
5103 + u32 cdlen; /* Channel descriptor length */
5104 + u32 cis; /* Channel interrupt status */
5105 + u32 cie; /* Channel interrupt enable */
5106 + u32 cgbl; /* Channel global buffer length */
5107 + u32 cdptnrd; /* Current descriptor pointer */
5109 + u32 ps; /* Port select */
5110 + u32 pctrl; /* Port control */
5112 + u32 irnen; /* Interrupt node enable */
5113 + u32 irncr; /* Interrupt node control */
5114 + u32 irnicr; /* Interrupt capture */
5117 +static struct ltq_dma_regs *ltq_dma_regs =
5118 + (struct ltq_dma_regs *) CKSEG1ADDR(LTQ_DMA_BASE);
5120 +static inline unsigned long ltq_dma_addr_to_virt(u32 dma_addr)
5122 + return KSEG0ADDR(dma_addr);
5125 +static inline u32 ltq_virt_to_dma_addr(void *addr)
5127 + return CPHYSADDR(addr);
5130 +static inline int ltq_dma_burst_align(enum ltq_dma_burst_len burst_len)
5132 + switch (burst_len) {
5133 + case LTQ_DMA_BURST_2WORDS:
5135 + case LTQ_DMA_BURST_4WORDS:
5137 + case LTQ_DMA_BURST_8WORDS:
5144 +static inline void ltq_dma_sync(void)
5146 + __asm__ __volatile__("sync");
5149 +static inline void ltq_dma_dcache_wb_inv(const void *ptr, size_t size)
5151 + unsigned long addr = (unsigned long) ptr;
5153 + flush_dcache_range(addr, addr + size);
5157 +static inline void ltq_dma_dcache_inv(const void *ptr, size_t size)
5159 + unsigned long addr = (unsigned long) ptr;
5161 + invalidate_dcache_range(addr, addr + size);
5164 +void ltq_dma_init(void)
5166 + /* Power up DMA */
5167 + ltq_pm_enable(LTQ_PM_DMA);
5170 + ltq_setbits(<q_dma_regs->ctrl, DMA_CTRL_RESET);
5172 + /* Disable and clear all interrupts */
5173 + ltq_writel(<q_dma_regs->irnen, 0);
5174 + ltq_writel(<q_dma_regs->irncr, 0xFFFFF);
5177 + /* Enable packet arbitration */
5178 + ltq_setbits(<q_dma_regs->ctrl, DMA_CTRL_PKTARB);
5182 + /* Enable descriptor read back */
5183 + ltq_setbits(<q_dma_regs->ctrl, DMA_CTRL_DRB);
5186 + /* Enable polling for descriptor fetching for all channels */
5187 + ltq_writel(<q_dma_regs->cpoll, DMA_CPOLL_EN |
5188 + (4 << DMA_CPOLL_CNT_SHIFT));
5191 +static void ltq_dma_channel_reset(struct ltq_dma_channel *chan)
5193 + ltq_writel(<q_dma_regs->cs, chan->chan_no);
5194 + ltq_setbits(<q_dma_regs->cctrl, DMA_CCTRL_RST);
5197 +static void ltq_dma_channel_enable(struct ltq_dma_channel *chan)
5199 + ltq_writel(<q_dma_regs->cs, chan->chan_no);
5200 + ltq_setbits(<q_dma_regs->cctrl, DMA_CCTRL_ONOFF);
5203 +static void ltq_dma_channel_disable(struct ltq_dma_channel *chan)
5205 + ltq_writel(<q_dma_regs->cs, chan->chan_no);
5206 + ltq_clrbits(<q_dma_regs->cctrl, DMA_CCTRL_ONOFF);
5209 +static void ltq_dma_port_init(struct ltq_dma_device *dev)
5213 + pctrl = dev->tx_endian_swap << DMA_PCTRL_TXENDI_SHIFT;
5214 + pctrl |= dev->rx_endian_swap << DMA_PCTRL_RXENDI_SHIFT;
5215 + pctrl |= dev->tx_burst_len << DMA_PCTRL_TXBL_SHIFT;
5216 + pctrl |= dev->rx_burst_len << DMA_PCTRL_RXBL_SHIFT;
5218 + ltq_writel(<q_dma_regs->ps, dev->port);
5219 + ltq_writel(<q_dma_regs->pctrl, pctrl);
5222 +static int ltq_dma_alloc_descriptors(struct ltq_dma_device *dev,
5223 + struct ltq_dma_channel *chan)
5228 + size = ALIGN(sizeof(struct ltq_dma_desc) * chan->num_desc +
5229 + ARCH_DMA_MINALIGN, ARCH_DMA_MINALIGN);
5231 + chan->mem_base = malloc(size);
5232 + if (!chan->mem_base)
5235 + memset(chan->mem_base, 0, size);
5236 + ltq_dma_dcache_wb_inv(chan->mem_base, size);
5238 + desc_base = PTR_ALIGN(chan->mem_base, ARCH_DMA_MINALIGN);
5240 + debug("DMA: mem %p, desc %p\n", chan->mem_base, desc_base);
5242 + /* Align descriptor base to 8 bytes */
5243 + chan->desc_base = (void *) CKSEG1ADDR(desc_base);
5244 + chan->dma_addr = CPHYSADDR(desc_base);
5247 + debug("DMA: desc_base %p, size %u\n", chan->desc_base, size);
5249 + /* Configure hardware with location of descriptor list */
5250 + ltq_writel(<q_dma_regs->cs, chan->chan_no);
5251 + ltq_writel(<q_dma_regs->cdba, chan->dma_addr);
5252 + ltq_writel(<q_dma_regs->cdlen, chan->num_desc);
5253 + ltq_writel(<q_dma_regs->cctrl, (3 << DMA_CCTRL_TXWGT_SHIFT) |
5254 + (chan->class << DMA_CCTRL_CLASS_SHIFT));
5255 + ltq_writel(<q_dma_regs->cctrl, DMA_CCTRL_RST);
5260 +static void ltq_dma_free_descriptors(struct ltq_dma_channel *chan)
5262 + ltq_writel(<q_dma_regs->cs, chan->chan_no);
5263 + ltq_writel(<q_dma_regs->cdba, 0);
5264 + ltq_writel(<q_dma_regs->cdlen, 0);
5266 + ltq_dma_channel_reset(chan);
5268 + free(chan->mem_base);
5271 +int ltq_dma_register(struct ltq_dma_device *dev)
5275 + ltq_dma_port_init(dev);
5277 + ret = ltq_dma_alloc_descriptors(dev, &dev->rx_chan);
5281 + ret = ltq_dma_alloc_descriptors(dev, &dev->tx_chan);
5283 + ltq_dma_free_descriptors(&dev->rx_chan);
5290 +void ltq_dma_reset(struct ltq_dma_device *dev)
5292 + ltq_dma_channel_reset(&dev->rx_chan);
5293 + ltq_dma_channel_reset(&dev->tx_chan);
5296 +void ltq_dma_enable(struct ltq_dma_device *dev)
5298 + ltq_dma_channel_enable(&dev->rx_chan);
5299 + ltq_dma_channel_enable(&dev->tx_chan);
5302 +void ltq_dma_disable(struct ltq_dma_device *dev)
5304 + ltq_dma_channel_disable(&dev->rx_chan);
5305 + ltq_dma_channel_disable(&dev->tx_chan);
5308 +int ltq_dma_rx_map(struct ltq_dma_device *dev, int index, void *data, int len)
5310 + struct ltq_dma_channel *chan = &dev->rx_chan;
5311 + struct ltq_dma_desc *desc = &chan->desc_base[index];
5312 + u32 dma_addr = ltq_virt_to_dma_addr(data);
5313 + unsigned int offset;
5315 + offset = dma_addr % ltq_dma_burst_align(dev->rx_burst_len);
5317 + ltq_dma_dcache_inv(data, len);
5320 + printf("%s: index %d, data %p, dma_addr %08x, offset %u, len %d\n",
5321 + __func__, index, data, dma_addr, offset, len);
5325 + desc->addr = dma_addr - offset;
5326 + desc->ctl = DMA_DESC_OWN | DMA_DESC_RX_OFFSET(offset) |
5327 + DMA_DESC_LENGTH(len);
5330 + printf("%s: index %d, desc %p, desc->ctl %08x\n",
5331 + __func__, index, desc, desc->ctl);
5337 +int ltq_dma_rx_poll(struct ltq_dma_device *dev, int index)
5339 + struct ltq_dma_channel *chan = &dev->rx_chan;
5340 + struct ltq_dma_desc *desc = &chan->desc_base[index];
5343 + printf("%s: index %d, desc %p, desc->ctl %08x\n",
5344 + __func__, index, desc, desc->ctl);
5347 + if (desc->ctl & DMA_DESC_OWN)
5350 + if (desc->ctl & DMA_DESC_C)
5356 +int ltq_dma_rx_length(struct ltq_dma_device *dev, int index)
5358 + struct ltq_dma_channel *chan = &dev->rx_chan;
5359 + struct ltq_dma_desc *desc = &chan->desc_base[index];
5361 + return DMA_DESC_LENGTH(desc->ctl);
5364 +int ltq_dma_tx_map(struct ltq_dma_device *dev, int index, void *data, int len,
5365 + unsigned long timeout)
5367 + struct ltq_dma_channel *chan = &dev->tx_chan;
5368 + struct ltq_dma_desc *desc = &chan->desc_base[index];
5369 + unsigned int offset;
5370 + unsigned long timebase = get_timer(0);
5371 + u32 dma_addr = ltq_virt_to_dma_addr(data);
5373 + while (desc->ctl & DMA_DESC_OWN) {
5376 + if (get_timer(timebase) >= timeout) {
5378 + printf("%s: timeout: index %d, desc %p, desc->ctl %08x\n",
5379 + __func__, index, desc, desc->ctl);
5385 + offset = dma_addr % ltq_dma_burst_align(dev->rx_burst_len);
5388 + printf("%s: index %d, desc %p, data %p, dma_addr %08x, offset %u, len %d\n",
5389 + __func__, index, desc, data, dma_addr, offset, len);
5392 + ltq_dma_dcache_wb_inv(data, len);
5394 + desc->addr = dma_addr - offset;
5395 + desc->ctl = DMA_DESC_OWN | DMA_DESC_SOP | DMA_DESC_EOP |
5396 + DMA_DESC_TX_OFFSET(offset) | DMA_DESC_LENGTH(len);
5399 + printf("%s: index %d, desc %p, desc->ctl %08x\n",
5400 + __func__, index, desc, desc->ctl);
5406 +int ltq_dma_tx_wait(struct ltq_dma_device *dev, int index,
5407 + unsigned long timeout)
5409 + struct ltq_dma_channel *chan = &dev->tx_chan;
5410 + struct ltq_dma_desc *desc = &chan->desc_base[index];
5411 + unsigned long timebase = get_timer(0);
5413 + while ((desc->ctl & (DMA_DESC_OWN | DMA_DESC_C)) != DMA_DESC_C) {
5416 + if (get_timer(timebase) >= timeout)
5422 --- a/drivers/gpio/Makefile
5423 +++ b/drivers/gpio/Makefile
5424 @@ -12,6 +12,7 @@ LIB := $(obj)libgpio.o
5425 COBJS-$(CONFIG_AT91_GPIO) += at91_gpio.o
5426 COBJS-$(CONFIG_INTEL_ICH6_GPIO) += intel_ich6_gpio.o
5427 COBJS-$(CONFIG_KIRKWOOD_GPIO) += kw_gpio.o
5428 +COBJS-$(CONFIG_LANTIQ_GPIO) += lantiq_gpio.o
5429 COBJS-$(CONFIG_MARVELL_GPIO) += mvgpio.o
5430 COBJS-$(CONFIG_MARVELL_MFP) += mvmfp.o
5431 COBJS-$(CONFIG_MXC_GPIO) += mxc_gpio.o
5433 +++ b/drivers/gpio/lantiq_gpio.c
5436 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
5438 + * SPDX-License-Identifier: GPL-2.0+
5441 +#include <common.h>
5442 +#include <asm/arch/soc.h>
5443 +#include <asm/arch/gpio.h>
5444 +#include <asm/lantiq/io.h>
5446 +#define SSIO_GPIO_BASE 64
5448 +#define SSIO_CON0_SWU (1 << 31)
5449 +#define SSIO_CON0_RZFL (1 << 26)
5450 +#define SSIO_CON0_GPHY1_SHIFT 27
5451 +#define SSIO_CON0_GPHY1_CONFIG ((CONFIG_LTQ_SSIO_GPHY1_MODE & 0x7) << 27)
5453 +#define SSIO_CON1_US_FPI (2 << 30)
5454 +#define SSIO_CON1_FPID_2HZ (0 << 23)
5455 +#define SSIO_CON1_FPID_4HZ (1 << 23)
5456 +#define SSIO_CON1_FPID_8HZ (2 << 23)
5457 +#define SSIO_CON1_FPID_10HZ (3 << 23)
5458 +#define SSIO_CON1_FPIS_1_2 (1 << 20)
5459 +#define SSIO_CON1_FPIS_1_32 (2 << 20)
5460 +#define SSIO_CON1_FPIS_1_64 (3 << 20)
5462 +#define SSIO_CON1_GPHY2_SHIFT 15
5463 +#define SSIO_CON1_GPHY2_CONFIG ((CONFIG_LTQ_SSIO_GPHY2_MODE & 0x7) << 15)
5465 +#define SSIO_CON1_GROUP2 (1 << 2)
5466 +#define SSIO_CON1_GROUP1 (1 << 1)
5467 +#define SSIO_CON1_GROUP0 (1 << 0)
5468 +#define SSIO_CON1_GROUP_CONFIG (0x3)
5470 +#ifdef CONFIG_LTQ_SSIO_SHIFT_REGS
5471 +#define enable_ssio 1
5473 +#define enable_ssio 0
5475 +#define CONFIG_LTQ_SSIO_GPHY1_MODE 0
5476 +#define CONFIG_LTQ_SSIO_GPHY2_MODE 0
5477 +#define CONFIG_LTQ_SSIO_INIT_VALUE 0
5480 +#ifdef CONFIG_LTQ_SSIO_EDGE_FALLING
5481 +#define SSIO_RZFL_CONFIG SSIO_CON0_RZFL
5483 +#define SSIO_RZFL_CONFIG 0
5486 +struct ltq_gpio_port_regs {
5499 +struct ltq_gpio_regs {
5501 + struct ltq_gpio_port_regs ports[CONFIG_LTQ_GPIO_MAX_BANKS];
5504 +struct ltq_gpio3_regs {
5518 +struct ltq_ssio_regs {
5526 +static struct ltq_gpio_regs *ltq_gpio_regs =
5527 + (struct ltq_gpio_regs *) CKSEG1ADDR(LTQ_GPIO_BASE);
5529 +static struct ltq_gpio3_regs *ltq_gpio3_regs =
5530 + (struct ltq_gpio3_regs *) CKSEG1ADDR(LTQ_GPIO_BASE);
5532 +static struct ltq_ssio_regs *ltq_ssio_regs =
5533 + (struct ltq_ssio_regs *) CKSEG1ADDR(LTQ_SSIO_BASE);
5535 +static int is_gpio_bank3(unsigned int port)
5537 +#ifdef CONFIG_LTQ_HAS_GPIO_BANK3
5544 +static int is_gpio_ssio(unsigned int gpio)
5546 +#ifdef CONFIG_LTQ_SSIO_SHIFT_REGS
5547 + return gpio >= SSIO_GPIO_BASE;
5553 +static inline int ssio_gpio_to_bit(unsigned gpio)
5555 + return 1 << (gpio - SSIO_GPIO_BASE);
5558 +int ltq_gpio_init(void)
5560 + ltq_writel(<q_ssio_regs->ar, 0);
5561 + ltq_writel(<q_ssio_regs->cpu0, CONFIG_LTQ_SSIO_INIT_VALUE);
5562 + ltq_writel(<q_ssio_regs->cpu1, 0);
5563 + ltq_writel(<q_ssio_regs->con0, SSIO_CON0_SWU);
5565 + if (enable_ssio) {
5566 + ltq_writel(<q_ssio_regs->con0, SSIO_CON0_GPHY1_CONFIG |
5567 + SSIO_RZFL_CONFIG);
5568 + ltq_writel(<q_ssio_regs->con1, SSIO_CON1_US_FPI |
5569 + SSIO_CON1_FPID_8HZ | SSIO_CON1_GPHY2_CONFIG |
5570 + SSIO_CON1_GROUP_CONFIG);
5576 +int gpio_request(unsigned gpio, const char *label)
5581 +int gpio_free(unsigned gpio)
5586 +int gpio_direction_input(unsigned gpio)
5588 + unsigned port = gpio_to_port(gpio);
5589 + const void *gpio_od = <q_gpio_regs->ports[port].od;
5590 + const void *gpio_altsel0 = <q_gpio_regs->ports[port].altsel0;
5591 + const void *gpio_altsel1 = <q_gpio_regs->ports[port].altsel1;
5592 + const void *gpio_dir = <q_gpio_regs->ports[port].dir;
5594 + if (is_gpio_ssio(gpio))
5597 + if (is_gpio_bank3(port)) {
5598 + gpio_od = <q_gpio3_regs->od;
5599 + gpio_altsel0 = <q_gpio3_regs->altsel0;
5600 + gpio_altsel1 = <q_gpio3_regs->altsel1;
5601 + gpio_dir = <q_gpio3_regs->dir;
5605 + * Reset open drain and altsel configs to workaround improper
5606 + * reset values or unwanted modifications by BootROM
5608 + ltq_clrbits(gpio_od, gpio_to_bit(gpio));
5609 + ltq_clrbits(gpio_altsel0, gpio_to_bit(gpio));
5610 + ltq_clrbits(gpio_altsel1, gpio_to_bit(gpio));
5612 + /* Switch to input */
5613 + ltq_clrbits(gpio_dir, gpio_to_bit(gpio));
5618 +int gpio_direction_output(unsigned gpio, int value)
5620 + unsigned port = gpio_to_port(gpio);
5621 + const void *gpio_od = <q_gpio_regs->ports[port].od;
5622 + const void *gpio_altsel0 = <q_gpio_regs->ports[port].altsel0;
5623 + const void *gpio_altsel1 = <q_gpio_regs->ports[port].altsel1;
5624 + const void *gpio_dir = <q_gpio_regs->ports[port].dir;
5625 + const void *gpio_out = <q_gpio_regs->ports[port].out;
5626 + u32 data = gpio_to_bit(gpio);
5628 + if (is_gpio_ssio(gpio)) {
5629 + data = ssio_gpio_to_bit(gpio);
5631 + ltq_setbits(<q_ssio_regs->cpu0, data);
5633 + ltq_clrbits(<q_ssio_regs->cpu0, data);
5638 + if (is_gpio_bank3(port)) {
5639 + gpio_od = <q_gpio3_regs->od;
5640 + gpio_altsel0 = <q_gpio3_regs->altsel0;
5641 + gpio_altsel1 = <q_gpio3_regs->altsel1;
5642 + gpio_dir = <q_gpio3_regs->dir;
5643 + gpio_out = <q_gpio3_regs->out;
5647 + * Reset open drain and altsel configs to workaround improper
5648 + * reset values or unwanted modifications by BootROM
5650 + ltq_setbits(gpio_od, data);
5651 + ltq_clrbits(gpio_altsel0, data);
5652 + ltq_clrbits(gpio_altsel1, data);
5655 + ltq_setbits(gpio_out, data);
5657 + ltq_clrbits(gpio_out, data);
5659 + /* Switch to output */
5660 + ltq_setbits(gpio_dir, data);
5665 +int gpio_get_value(unsigned gpio)
5667 + unsigned port = gpio_to_port(gpio);
5668 + const void *gpio_in = <q_gpio_regs->ports[port].in;
5669 + u32 data = gpio_to_bit(gpio);
5672 + if (is_gpio_ssio(gpio)) {
5673 + gpio_in = <q_ssio_regs->cpu0;
5674 + data = ssio_gpio_to_bit(gpio);
5677 + if (is_gpio_bank3(port))
5678 + gpio_in = <q_gpio3_regs->in;
5680 + val = ltq_readl(gpio_in);
5682 + return !!(val & data);
5685 +int gpio_set_value(unsigned gpio, int value)
5687 + unsigned port = gpio_to_port(gpio);
5688 + const void *gpio_out = <q_gpio_regs->ports[port].out;
5689 + u32 data = gpio_to_bit(gpio);
5691 + if (is_gpio_ssio(gpio)) {
5692 + gpio_out = <q_ssio_regs->cpu0;
5693 + data = ssio_gpio_to_bit(gpio);
5696 + if (is_gpio_bank3(port))
5697 + gpio_out = <q_gpio3_regs->out;
5700 + ltq_setbits(gpio_out, data);
5702 + ltq_clrbits(gpio_out, data);
5707 +int gpio_set_altfunc(unsigned gpio, int altsel0, int altsel1, int dir)
5709 + unsigned port = gpio_to_port(gpio);
5710 + const void *gpio_od = <q_gpio_regs->ports[port].od;
5711 + const void *gpio_altsel0 = <q_gpio_regs->ports[port].altsel0;
5712 + const void *gpio_altsel1 = <q_gpio_regs->ports[port].altsel1;
5713 + const void *gpio_dir = <q_gpio_regs->ports[port].dir;
5715 + if (is_gpio_ssio(gpio))
5718 + if (is_gpio_bank3(port)) {
5719 + gpio_od = <q_gpio3_regs->od;
5720 + gpio_altsel0 = <q_gpio3_regs->altsel0;
5721 + gpio_altsel1 = <q_gpio3_regs->altsel1;
5722 + gpio_dir = <q_gpio3_regs->dir;
5726 + ltq_setbits(gpio_altsel0, gpio_to_bit(gpio));
5728 + ltq_clrbits(gpio_altsel0, gpio_to_bit(gpio));
5731 + ltq_setbits(gpio_altsel1, gpio_to_bit(gpio));
5733 + ltq_clrbits(gpio_altsel1, gpio_to_bit(gpio));
5736 + ltq_setbits(gpio_od, gpio_to_bit(gpio));
5737 + ltq_setbits(gpio_dir, gpio_to_bit(gpio));
5739 + ltq_clrbits(gpio_od, gpio_to_bit(gpio));
5740 + ltq_clrbits(gpio_dir, gpio_to_bit(gpio));
5746 +int gpio_set_opendrain(unsigned gpio, int od)
5748 + unsigned port = gpio_to_port(gpio);
5749 + const void *gpio_od = <q_gpio_regs->ports[port].od;
5751 + if (is_gpio_ssio(gpio))
5754 + if (is_gpio_bank3(port))
5755 + gpio_od = <q_gpio3_regs->od;
5758 + ltq_setbits(gpio_od, gpio_to_bit(gpio));
5760 + ltq_clrbits(gpio_od, gpio_to_bit(gpio));
5764 --- a/drivers/mtd/cfi_flash.c
5765 +++ b/drivers/mtd/cfi_flash.c
5766 @@ -161,6 +161,18 @@ u64 flash_read64(void *addr)__attribute_
5767 #define flash_read64 __flash_read64
5770 +static inline void *__flash_swap_addr(unsigned long addr)
5772 + return (void *) addr;
5775 +#ifdef CONFIG_CFI_FLASH_USE_WEAK_ADDR_SWAP
5776 +void *flash_swap_addr(unsigned long addr)
5777 + __attribute__((weak, alias("__flash_swap_addr")));
5779 +#define flash_swap_addr __flash_swap_addr
5782 /*-----------------------------------------------------------------------
5784 #if defined(CONFIG_ENV_IS_IN_FLASH) || defined(CONFIG_ENV_ADDR_REDUND) || (CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE)
5785 @@ -196,7 +208,7 @@ flash_map (flash_info_t * info, flash_se
5787 unsigned int byte_offset = offset * info->portwidth;
5789 - return (void *)(info->start[sect] + byte_offset);
5790 + return flash_swap_addr(info->start[sect] + byte_offset);
5793 static inline void flash_unmap(flash_info_t *info, flash_sect_t sect,
5794 --- a/drivers/mtd/nand/Makefile
5795 +++ b/drivers/mtd/nand/Makefile
5796 @@ -53,6 +53,7 @@ COBJS-$(CONFIG_NAND_JZ4740) += jz4740_na
5797 COBJS-$(CONFIG_NAND_KB9202) += kb9202_nand.o
5798 COBJS-$(CONFIG_NAND_KIRKWOOD) += kirkwood_nand.o
5799 COBJS-$(CONFIG_NAND_KMETER1) += kmeter1_nand.o
5800 +COBJS-$(CONFIG_NAND_LANTIQ) += lantiq_nand.o
5801 COBJS-$(CONFIG_NAND_MPC5121_NFC) += mpc5121_nfc.o
5802 COBJS-$(CONFIG_NAND_MXC) += mxc_nand.o
5803 COBJS-$(CONFIG_NAND_MXS) += mxs_nand.o
5805 +++ b/drivers/mtd/nand/lantiq_nand.c
5808 + * Copyright (C) 2012-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
5810 + * SPDX-License-Identifier: GPL-2.0+
5813 +#include <common.h>
5814 +#include <linux/mtd/nand.h>
5815 +#include <linux/compiler.h>
5816 +#include <asm/arch/soc.h>
5817 +#include <asm/arch/nand.h>
5818 +#include <asm/lantiq/io.h>
5820 +#define NAND_CON_ECC_ON (1 << 31)
5821 +#define NAND_CON_LATCH_PRE (1 << 23)
5822 +#define NAND_CON_LATCH_WP (1 << 22)
5823 +#define NAND_CON_LATCH_SE (1 << 21)
5824 +#define NAND_CON_LATCH_CS (1 << 20)
5825 +#define NAND_CON_LATCH_CLE (1 << 19)
5826 +#define NAND_CON_LATCH_ALE (1 << 18)
5827 +#define NAND_CON_OUT_CS1 (1 << 10)
5828 +#define NAND_CON_IN_CS1 (1 << 8)
5829 +#define NAND_CON_PRE_P (1 << 7)
5830 +#define NAND_CON_WP_P (1 << 6)
5831 +#define NAND_CON_SE_P (1 << 5)
5832 +#define NAND_CON_CS_P (1 << 4)
5833 +#define NAND_CON_CLE_P (1 << 3)
5834 +#define NAND_CON_ALE_P (1 << 2)
5835 +#define NAND_CON_CSMUX (1 << 1)
5836 +#define NAND_CON_NANDM (1 << 0)
5838 +#define NAND_WAIT_WR_C (1 << 3)
5839 +#define NAND_WAIT_RDBY (1 << 0)
5841 +#define NAND_CMD_ALE (1 << 2)
5842 +#define NAND_CMD_CLE (1 << 3)
5843 +#define NAND_CMD_CS (1 << 4)
5844 +#define NAND_CMD_SE (1 << 5)
5845 +#define NAND_CMD_WP (1 << 6)
5846 +#define NAND_CMD_PRE (1 << 7)
5848 +struct ltq_nand_regs {
5849 + __be32 con; /* NAND controller control */
5850 + __be32 wait; /* NAND Flash Device RD/BY State */
5851 + __be32 ecc0; /* NAND Flash ECC Register 0 */
5852 + __be32 ecc_ac; /* NAND Flash ECC Register address counter */
5853 + __be32 ecc_cr; /* NAND Flash ECC Comparison */
5856 +static struct ltq_nand_regs *ltq_nand_regs =
5857 + (struct ltq_nand_regs *) CKSEG1ADDR(LTQ_EBU_NAND_BASE);
5859 +static void ltq_nand_wait_ready(void)
5861 + while ((ltq_readl(<q_nand_regs->wait) & NAND_WAIT_WR_C) == 0)
5865 +static int ltq_nand_dev_ready(struct mtd_info *mtd)
5867 + u32 data = ltq_readl(<q_nand_regs->wait);
5868 + return data & NAND_WAIT_RDBY;
5871 +static void ltq_nand_select_chip(struct mtd_info *mtd, int chip)
5874 + ltq_setbits(<q_nand_regs->con, NAND_CON_NANDM);
5875 + ltq_setbits(<q_nand_regs->con, NAND_CON_LATCH_CS);
5877 + ltq_clrbits(<q_nand_regs->con, NAND_CON_LATCH_CS);
5878 + ltq_clrbits(<q_nand_regs->con, NAND_CON_NANDM);
5882 +static void ltq_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
5884 + struct nand_chip *chip = mtd->priv;
5885 + unsigned long addr = (unsigned long) chip->IO_ADDR_W;
5887 + if (ctrl & NAND_CTRL_CHANGE) {
5888 + if (ctrl & NAND_ALE)
5889 + addr |= NAND_CMD_ALE;
5891 + addr &= ~NAND_CMD_ALE;
5893 + if (ctrl & NAND_CLE)
5894 + addr |= NAND_CMD_CLE;
5896 + addr &= ~NAND_CMD_CLE;
5898 + chip->IO_ADDR_W = (void __iomem *) addr;
5901 + if (cmd != NAND_CMD_NONE) {
5902 + writeb(cmd, chip->IO_ADDR_W);
5903 + ltq_nand_wait_ready();
5907 +int ltq_nand_init(struct nand_chip *nand)
5909 + /* Enable NAND, set NAND CS to EBU CS1, enable EBU CS mux */
5910 + ltq_writel(<q_nand_regs->con, NAND_CON_OUT_CS1 | NAND_CON_IN_CS1 |
5911 + NAND_CON_PRE_P | NAND_CON_WP_P | NAND_CON_SE_P |
5912 + NAND_CON_CS_P | NAND_CON_CSMUX);
5914 + nand->dev_ready = ltq_nand_dev_ready;
5915 + nand->select_chip = ltq_nand_select_chip;
5916 + nand->cmd_ctrl = ltq_nand_cmd_ctrl;
5918 + nand->chip_delay = 30;
5919 + nand->options = 0;
5920 + nand->ecc.mode = NAND_ECC_SOFT;
5922 + /* Enable CS bit in address offset */
5923 + nand->IO_ADDR_R = nand->IO_ADDR_R + NAND_CMD_CS;
5924 + nand->IO_ADDR_W = nand->IO_ADDR_W + NAND_CMD_CS;
5929 +__weak int board_nand_init(struct nand_chip *chip)
5931 + return ltq_nand_init(chip);
5933 --- a/drivers/net/Makefile
5934 +++ b/drivers/net/Makefile
5935 @@ -37,6 +37,8 @@ COBJS-$(CONFIG_INCA_IP_SWITCH) += inca-i
5936 COBJS-$(CONFIG_DRIVER_KS8695ETH) += ks8695eth.o
5937 COBJS-$(CONFIG_KS8851_MLL) += ks8851_mll.o
5938 COBJS-$(CONFIG_LAN91C96) += lan91c96.o
5939 +COBJS-$(CONFIG_LANTIQ_DANUBE_ETOP) += lantiq_danube_etop.o
5940 +COBJS-$(CONFIG_LANTIQ_VRX200_SWITCH) += lantiq_vrx200_switch.o
5941 COBJS-$(CONFIG_MACB) += macb.o
5942 COBJS-$(CONFIG_MCFFEC) += mcffec.o mcfmii.o
5943 COBJS-$(CONFIG_MPC5xxx_FEC) += mpc5xxx_fec.o
5945 +++ b/drivers/net/lantiq_danube_etop.c
5948 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
5950 + * SPDX-License-Identifier: GPL-2.0+
5953 +#include <common.h>
5954 +#include <malloc.h>
5955 +#include <netdev.h>
5956 +#include <miiphy.h>
5957 +#include <switch.h>
5958 +#include <asm/lantiq/io.h>
5959 +#include <asm/lantiq/eth.h>
5960 +#include <asm/lantiq/pm.h>
5961 +#include <asm/lantiq/reset.h>
5962 +#include <asm/lantiq/dma.h>
5963 +#include <asm/arch/soc.h>
5965 +#define LTQ_PPE_ETOP_MDIO_ACC_RA (1 << 31)
5966 +#define LTQ_PPE_ETOP_MDIO_CFG_UMM1 (1 << 2)
5967 +#define LTQ_PPE_ETOP_MDIO_CFG_UMM0 (1 << 1)
5969 +#define LTQ_PPE_ETOP_CFG_TCKINV1 (1 << 11)
5970 +#define LTQ_PPE_ETOP_CFG_TCKINV0 (1 << 10)
5971 +#define LTQ_PPE_ETOP_CFG_FEN1 (1 << 9)
5972 +#define LTQ_PPE_ETOP_CFG_FEN0 (1 << 8)
5973 +#define LTQ_PPE_ETOP_CFG_SEN1 (1 << 7)
5974 +#define LTQ_PPE_ETOP_CFG_SEN0 (1 << 6)
5975 +#define LTQ_PPE_ETOP_CFG_TURBO1 (1 << 5)
5976 +#define LTQ_PPE_ETOP_CFG_REMII1 (1 << 4)
5977 +#define LTQ_PPE_ETOP_CFG_OFF1 (1 << 3)
5978 +#define LTQ_PPE_ETOP_CFG_TURBO0 (1 << 2)
5979 +#define LTQ_PPE_ETOP_CFG_REMII0 (1 << 1)
5980 +#define LTQ_PPE_ETOP_CFG_OFF0 (1 << 0)
5982 +#define LTQ_PPE_ENET0_MAC_CFG_CGEN (1 << 11)
5983 +#define LTQ_PPE_ENET0_MAC_CFG_DUPLEX (1 << 2)
5984 +#define LTQ_PPE_ENET0_MAC_CFG_SPEED (1 << 1)
5985 +#define LTQ_PPE_ENET0_MAC_CFG_LINK (1 << 0)
5987 +#define LTQ_PPE_ENETS0_CFG_FTUC (1 << 28)
5989 +#define LTQ_ETH_RX_BUFFER_CNT PKTBUFSRX
5990 +#define LTQ_ETH_TX_BUFFER_CNT 8
5991 +#define LTQ_ETH_RX_DATA_SIZE PKTSIZE_ALIGN
5992 +#define LTQ_ETH_IP_ALIGN 2
5994 +#define LTQ_MDIO_DRV_NAME "ltq-mdio"
5995 +#define LTQ_ETH_DRV_NAME "ltq-eth"
5997 +struct ltq_ppe_etop_regs {
5998 + u32 mdio_cfg; /* MDIO configuration */
5999 + u32 mdio_acc; /* MDIO access */
6000 + u32 cfg; /* ETOP configuration */
6001 + u32 ig_vlan_cos; /* IG VLAN priority CoS mapping */
6002 + u32 ig_dscp_cos3; /* IG DSCP CoS mapping 3 */
6003 + u32 ig_dscp_cos2; /* IG DSCP CoS mapping 2 */
6004 + u32 ig_dscp_cos1; /* IG DSCP CoS mapping 1 */
6005 + u32 ig_dscp_cos0; /* IG DSCP CoS mapping 0 */
6006 + u32 ig_plen_ctrl; /* IG frame length control */
6008 + u32 vpid; /* VLAN protocol ID */
6011 +struct ltq_ppe_enet_regs {
6012 + u32 mac_cfg; /* MAC configuration */
6014 + u32 ig_cfg; /* Ingress configuration */
6015 + u32 ig_pgcnt; /* Ingress buffer used page count */
6017 + u32 ig_buf_ctrl; /* Ingress buffer backpressure ctrl */
6018 + u32 cos_cfg; /* Classification configuration */
6019 + u32 ig_drop; /* Total ingress drop frames */
6020 + u32 ig_err; /* Total ingress error frames */
6021 + u32 mac_da0; /* Ingress MAC address 0 */
6022 + u32 mac_da1; /* Ingress MAC address 1 */
6024 + u32 pgcnt; /* Page counter */
6026 + u32 hf_ctrl; /* Half duplex control */
6027 + u32 tx_ctrl; /* Transmit control */
6029 + u32 vlcos0; /* VLAN insertion config CoS 0 */
6030 + u32 vlcos1; /* VLAN insertion config CoS 1 */
6031 + u32 vlcos2; /* VLAN insertion config CoS 2 */
6032 + u32 vlcos3; /* VLAN insertion config CoS 3 */
6033 + u32 eg_col; /* Total egress collision frames */
6034 + u32 eg_drop; /* Total egress drop frames */
6037 +struct ltq_eth_priv {
6038 + struct ltq_dma_device dma_dev;
6039 + struct mii_dev *bus;
6040 + struct eth_device *dev;
6045 +struct ltq_mdio_access {
6059 +static struct ltq_ppe_etop_regs *ltq_ppe_etop_regs =
6060 + (struct ltq_ppe_etop_regs *) CKSEG1ADDR(LTQ_PPE_ETOP_BASE);
6062 +static struct ltq_ppe_enet_regs *ltq_ppe_enet0_regs =
6063 + (struct ltq_ppe_enet_regs *) CKSEG1ADDR(LTQ_PPE_ENET0_BASE);
6065 +static inline int ltq_mdio_poll(void)
6067 + struct ltq_mdio_access acc;
6068 + unsigned cnt = 10000;
6070 + while (likely(cnt--)) {
6071 + acc.val = ltq_readl(<q_ppe_etop_regs->mdio_acc);
6079 +static int ltq_mdio_read(struct mii_dev *bus, int addr, int dev_addr,
6082 + struct ltq_mdio_access acc;
6088 + acc.reg.phya = addr;
6089 + acc.reg.rega = regnum;
6091 + ret = ltq_mdio_poll();
6095 + ltq_writel(<q_ppe_etop_regs->mdio_acc, acc.val);
6097 + ret = ltq_mdio_poll();
6101 + acc.val = ltq_readl(<q_ppe_etop_regs->mdio_acc);
6103 + return acc.reg.phyd;
6106 +static int ltq_mdio_write(struct mii_dev *bus, int addr, int dev_addr,
6107 + int regnum, u16 val)
6109 + struct ltq_mdio_access acc;
6115 + acc.reg.phya = addr;
6116 + acc.reg.rega = regnum;
6117 + acc.reg.phyd = val;
6119 + ret = ltq_mdio_poll();
6123 + ltq_writel(<q_ppe_etop_regs->mdio_acc, acc.val);
6128 +static inline void ltq_eth_write_hwaddr(const struct eth_device *dev)
6132 + da0 = (dev->enetaddr[0] << 24) + (dev->enetaddr[1] << 16) +
6133 + (dev->enetaddr[2] << 8) + dev->enetaddr[3];
6134 + da1 = (dev->enetaddr[4] << 24) + (dev->enetaddr[5] << 16);
6136 + ltq_writel(<q_ppe_enet0_regs->mac_da0, da0);
6137 + ltq_writel(<q_ppe_enet0_regs->mac_da1, da1);
6140 +static inline u8 *ltq_eth_rx_packet_align(int rx_num)
6142 + u8 *packet = (u8 *) NetRxPackets[rx_num];
6147 + return packet + LTQ_ETH_IP_ALIGN;
6150 +static int ltq_eth_init(struct eth_device *dev, bd_t *bis)
6152 + struct ltq_eth_priv *priv = dev->priv;
6153 + struct ltq_dma_device *dma_dev = &priv->dma_dev;
6156 + ltq_eth_write_hwaddr(dev);
6158 + for (i = 0; i < LTQ_ETH_RX_BUFFER_CNT; i++)
6159 + ltq_dma_rx_map(dma_dev, i, ltq_eth_rx_packet_align(i),
6160 + LTQ_ETH_RX_DATA_SIZE);
6162 + ltq_dma_enable(dma_dev);
6170 +static void ltq_eth_halt(struct eth_device *dev)
6172 + struct ltq_eth_priv *priv = dev->priv;
6173 + struct ltq_dma_device *dma_dev = &priv->dma_dev;
6175 + ltq_dma_reset(dma_dev);
6178 +static int ltq_eth_send(struct eth_device *dev, void *packet, int length)
6180 + struct ltq_eth_priv *priv = dev->priv;
6181 + struct ltq_dma_device *dma_dev = &priv->dma_dev;
6184 + /* Minimum payload length w/ CRC is 60 bytes */
6188 + err = ltq_dma_tx_map(dma_dev, priv->tx_num, packet, length, 10);
6190 + puts("NET: timeout on waiting for TX descriptor\n");
6194 + priv->tx_num = (priv->tx_num + 1) % LTQ_ETH_TX_BUFFER_CNT;
6199 +static int ltq_eth_recv(struct eth_device *dev)
6201 + struct ltq_eth_priv *priv = dev->priv;
6202 + struct ltq_dma_device *dma_dev = &priv->dma_dev;
6206 + if (!ltq_dma_rx_poll(dma_dev, priv->rx_num))
6210 + printf("%s: rx_num %d\n", __func__, priv->rx_num);
6213 + len = ltq_dma_rx_length(dma_dev, priv->rx_num);
6214 + packet = ltq_eth_rx_packet_align(priv->rx_num);
6217 + printf("%s: received: packet %p, len %u, rx_num %d\n",
6218 + __func__, packet, len, priv->rx_num);
6222 + NetReceive(packet, len);
6224 + ltq_dma_rx_map(dma_dev, priv->rx_num, packet,
6225 + LTQ_ETH_RX_DATA_SIZE);
6227 + priv->rx_num = (priv->rx_num + 1) % LTQ_ETH_RX_BUFFER_CNT;
6232 +static void ltq_eth_hw_init(const struct ltq_eth_port_config *port)
6236 + /* Power up ethernet subsystems */
6237 + ltq_pm_enable(LTQ_PM_ETH);
6239 + /* Reset ethernet subsystems */
6240 + ltq_reset_once(LTQ_RESET_ETH, 1);
6242 + /* Disable MDIO auto-detection */
6243 + ltq_clrbits(<q_ppe_etop_regs->mdio_cfg, LTQ_PPE_ETOP_MDIO_CFG_UMM1 |
6244 + LTQ_PPE_ETOP_MDIO_CFG_UMM0);
6246 + /* Enable CRC generation, Full Duplex, 100Mbps, Link up */
6247 + ltq_writel(<q_ppe_enet0_regs->mac_cfg, LTQ_PPE_ENET0_MAC_CFG_CGEN |
6248 + LTQ_PPE_ENET0_MAC_CFG_DUPLEX |
6249 + LTQ_PPE_ENET0_MAC_CFG_SPEED |
6250 + LTQ_PPE_ENET0_MAC_CFG_LINK);
6252 + /* Reset ETOP cfg and disable all */
6253 + data = LTQ_PPE_ETOP_CFG_OFF0 | LTQ_PPE_ETOP_CFG_OFF1;
6255 + /* Enable ENET0, enable store and fetch */
6256 + data &= ~LTQ_PPE_ETOP_CFG_OFF0;
6257 + data |= LTQ_PPE_ETOP_CFG_SEN0 | LTQ_PPE_ETOP_CFG_FEN0;
6259 + if (port->phy_if == PHY_INTERFACE_MODE_RMII)
6260 + data |= LTQ_PPE_ETOP_CFG_REMII0;
6262 + data &= ~LTQ_PPE_ETOP_CFG_REMII0;
6264 + ltq_writel(<q_ppe_etop_regs->cfg, data);
6266 + /* Set allowed packet length from 64 bytes to 1518 bytes */
6267 + ltq_writel(<q_ppe_etop_regs->ig_plen_ctrl, (64 << 16) | 1518);
6269 + /* Enable filter for unicast packets */
6270 + ltq_setbits(<q_ppe_enet0_regs->ig_cfg, LTQ_PPE_ENETS0_CFG_FTUC);
6273 +int ltq_eth_initialize(const struct ltq_eth_board_config *board_config)
6275 + struct eth_device *dev;
6276 + struct mii_dev *bus;
6277 + struct ltq_eth_priv *priv;
6278 + struct ltq_dma_device *dma_dev;
6279 + const struct ltq_eth_port_config *port = &board_config->ports[0];
6280 + struct phy_device *phy;
6281 + struct switch_device *sw;
6285 + ltq_eth_hw_init(port);
6287 + dev = calloc(1, sizeof(*dev));
6291 + priv = calloc(1, sizeof(*priv));
6295 + bus = mdio_alloc();
6299 + sprintf(dev->name, LTQ_ETH_DRV_NAME);
6301 + dev->init = ltq_eth_init;
6302 + dev->halt = ltq_eth_halt;
6303 + dev->recv = ltq_eth_recv;
6304 + dev->send = ltq_eth_send;
6306 + sprintf(bus->name, LTQ_MDIO_DRV_NAME);
6307 + bus->read = ltq_mdio_read;
6308 + bus->write = ltq_mdio_write;
6311 + dma_dev = &priv->dma_dev;
6312 + dma_dev->port = 0;
6313 + dma_dev->rx_chan.chan_no = 6;
6314 + dma_dev->rx_chan.class = 3;
6315 + dma_dev->rx_chan.num_desc = LTQ_ETH_RX_BUFFER_CNT;
6316 + dma_dev->rx_endian_swap = LTQ_DMA_ENDIANESS_B3_B2_B1_B0;
6317 + dma_dev->rx_burst_len = LTQ_DMA_BURST_2WORDS;
6318 + dma_dev->tx_chan.chan_no = 7;
6319 + dma_dev->tx_chan.class = 3;
6320 + dma_dev->tx_chan.num_desc = LTQ_ETH_TX_BUFFER_CNT;
6321 + dma_dev->tx_endian_swap = LTQ_DMA_ENDIANESS_B3_B2_B1_B0;
6322 + dma_dev->tx_burst_len = LTQ_DMA_BURST_2WORDS;
6327 + ret = ltq_dma_register(dma_dev);
6331 + ret = mdio_register(bus);
6335 + ret = eth_register(dev);
6339 + if (port->flags & LTQ_ETH_PORT_SWITCH) {
6340 + sw = switch_connect(bus);
6347 + if (port->flags & LTQ_ETH_PORT_PHY) {
6348 + phy = phy_connect(bus, port->phy_addr, dev, port->phy_if);
6358 +++ b/drivers/net/lantiq_vrx200_switch.c
6361 + * Copyright (C) 2010-2011 Lantiq Deutschland GmbH
6362 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
6364 + * SPDX-License-Identifier: GPL-2.0+
6369 +#include <common.h>
6370 +#include <malloc.h>
6371 +#include <netdev.h>
6372 +#include <miiphy.h>
6373 +#include <linux/compiler.h>
6374 +#include <asm/gpio.h>
6375 +#include <asm/processor.h>
6376 +#include <asm/lantiq/io.h>
6377 +#include <asm/lantiq/eth.h>
6378 +#include <asm/lantiq/pm.h>
6379 +#include <asm/lantiq/reset.h>
6380 +#include <asm/lantiq/dma.h>
6381 +#include <asm/arch/soc.h>
6382 +#include <asm/arch/switch.h>
6384 +#define LTQ_ETH_RX_BUFFER_CNT PKTBUFSRX
6385 +#define LTQ_ETH_TX_BUFFER_CNT 8
6386 +#define LTQ_ETH_RX_DATA_SIZE PKTSIZE_ALIGN
6387 +#define LTQ_ETH_IP_ALIGN 2
6389 +#define LTQ_MDIO_DRV_NAME "ltq-mdio"
6390 +#define LTQ_ETH_DRV_NAME "ltq-eth"
6392 +#define LTQ_ETHSW_MAX_GMAC 6
6393 +#define LTQ_ETHSW_PMAC 6
6395 +struct ltq_mdio_phy_addr_reg {
6399 + unsigned lnkst:2; /* Link status control */
6400 + unsigned speed:2; /* Speed control */
6401 + unsigned fdup:2; /* Full duplex control */
6402 + unsigned fcontx:2; /* Flow control mode TX */
6403 + unsigned fconrx:2; /* Flow control mode RX */
6404 + unsigned addr:5; /* PHY address */
6410 +enum ltq_mdio_phy_addr_lnkst {
6411 + LTQ_MDIO_PHY_ADDR_LNKST_AUTO = 0,
6412 + LTQ_MDIO_PHY_ADDR_LNKST_UP = 1,
6413 + LTQ_MDIO_PHY_ADDR_LNKST_DOWN = 2,
6416 +enum ltq_mdio_phy_addr_speed {
6417 + LTQ_MDIO_PHY_ADDR_SPEED_M10 = 0,
6418 + LTQ_MDIO_PHY_ADDR_SPEED_M100 = 1,
6419 + LTQ_MDIO_PHY_ADDR_SPEED_G1 = 2,
6420 + LTQ_MDIO_PHY_ADDR_SPEED_AUTO = 3,
6423 +enum ltq_mdio_phy_addr_fdup {
6424 + LTQ_MDIO_PHY_ADDR_FDUP_AUTO = 0,
6425 + LTQ_MDIO_PHY_ADDR_FDUP_ENABLE = 1,
6426 + LTQ_MDIO_PHY_ADDR_FDUP_DISABLE = 3,
6429 +enum ltq_mdio_phy_addr_fcon {
6430 + LTQ_MDIO_PHY_ADDR_FCON_AUTO = 0,
6431 + LTQ_MDIO_PHY_ADDR_FCON_ENABLE = 1,
6432 + LTQ_MDIO_PHY_ADDR_FCON_DISABLE = 3,
6435 +struct ltq_mii_mii_cfg_reg {
6438 + unsigned res:1; /* Hardware reset */
6439 + unsigned en:1; /* xMII interface enable */
6440 + unsigned isol:1; /* xMII interface isolate */
6441 + unsigned ldclkdis:1; /* Link down clock disable */
6443 + unsigned crs:2; /* CRS sensitivity config */
6444 + unsigned rgmii_ibs:1; /* RGMII In Band status */
6445 + unsigned rmii:1; /* RMII ref clock direction */
6446 + unsigned miirate:3; /* xMII interface clock rate */
6447 + unsigned miimode:4; /* xMII interface mode */
6453 +enum ltq_mii_mii_cfg_miirate {
6454 + LTQ_MII_MII_CFG_MIIRATE_M2P5 = 0,
6455 + LTQ_MII_MII_CFG_MIIRATE_M25 = 1,
6456 + LTQ_MII_MII_CFG_MIIRATE_M125 = 2,
6457 + LTQ_MII_MII_CFG_MIIRATE_M50 = 3,
6458 + LTQ_MII_MII_CFG_MIIRATE_AUTO = 4,
6461 +enum ltq_mii_mii_cfg_miimode {
6462 + LTQ_MII_MII_CFG_MIIMODE_MIIP = 0,
6463 + LTQ_MII_MII_CFG_MIIMODE_MIIM = 1,
6464 + LTQ_MII_MII_CFG_MIIMODE_RMIIP = 2,
6465 + LTQ_MII_MII_CFG_MIIMODE_RMIIM = 3,
6466 + LTQ_MII_MII_CFG_MIIMODE_RGMII = 4,
6469 +struct ltq_eth_priv {
6470 + struct ltq_dma_device dma_dev;
6471 + struct mii_dev *bus;
6472 + struct eth_device *dev;
6473 + struct phy_device *phymap[LTQ_ETHSW_MAX_GMAC];
6478 +static struct vr9_switch_regs *switch_regs =
6479 + (struct vr9_switch_regs *) CKSEG1ADDR(LTQ_SWITCH_BASE);
6481 +static inline void vr9_switch_sync(void)
6486 +static inline int vr9_switch_mdio_is_busy(void)
6488 + u32 mdio_ctrl = ltq_readl(&switch_regs->mdio.mdio_ctrl);
6490 + return mdio_ctrl & MDIO_CTRL_MBUSY;
6493 +static inline void vr9_switch_mdio_poll(void)
6495 + while (vr9_switch_mdio_is_busy())
6499 +static int vr9_switch_mdio_read(struct mii_dev *bus, int phyad, int devad,
6505 + mdio_ctrl = MDIO_CTRL_OP_READ |
6506 + ((phyad << MDIO_CTRL_PHYAD_SHIFT) & MDIO_CTRL_PHYAD_MASK) |
6507 + (regad & MDIO_CTRL_REGAD_MASK);
6509 + vr9_switch_mdio_poll();
6510 + ltq_writel(&switch_regs->mdio.mdio_ctrl, mdio_ctrl);
6511 + vr9_switch_mdio_poll();
6512 + retval = ltq_readl(&switch_regs->mdio.mdio_read);
6517 +static int vr9_switch_mdio_write(struct mii_dev *bus, int phyad, int devad,
6518 + int regad, u16 val)
6522 + mdio_ctrl = MDIO_CTRL_OP_WRITE |
6523 + ((phyad << MDIO_CTRL_PHYAD_SHIFT) & MDIO_CTRL_PHYAD_MASK) |
6524 + (regad & MDIO_CTRL_REGAD_MASK);
6526 + vr9_switch_mdio_poll();
6527 + ltq_writel(&switch_regs->mdio.mdio_write, val);
6528 + ltq_writel(&switch_regs->mdio.mdio_ctrl, mdio_ctrl);
6533 +static void ltq_eth_gmac_update(struct phy_device *phydev, int num)
6535 + struct ltq_mdio_phy_addr_reg phy_addr_reg;
6536 + struct ltq_mii_mii_cfg_reg mii_cfg_reg;
6538 + phy_addr_reg.val = ltq_readl(to_mdio_phyaddr(switch_regs, num));
6544 + mii_cfg_reg.val = ltq_readl(to_mii_miicfg(switch_regs, num));
6547 + mii_cfg_reg.val = 0;
6551 + phy_addr_reg.bits.addr = phydev->addr;
6554 + phy_addr_reg.bits.lnkst = LTQ_MDIO_PHY_ADDR_LNKST_UP;
6556 + phy_addr_reg.bits.lnkst = LTQ_MDIO_PHY_ADDR_LNKST_DOWN;
6558 + switch (phydev->speed) {
6560 + phy_addr_reg.bits.speed = LTQ_MDIO_PHY_ADDR_SPEED_G1;
6561 + mii_cfg_reg.bits.miirate = LTQ_MII_MII_CFG_MIIRATE_M125;
6564 + phy_addr_reg.bits.speed = LTQ_MDIO_PHY_ADDR_SPEED_M100;
6565 + switch (mii_cfg_reg.bits.miimode) {
6566 + case LTQ_MII_MII_CFG_MIIMODE_RMIIM:
6567 + case LTQ_MII_MII_CFG_MIIMODE_RMIIP:
6568 + mii_cfg_reg.bits.miirate = LTQ_MII_MII_CFG_MIIRATE_M50;
6571 + mii_cfg_reg.bits.miirate = LTQ_MII_MII_CFG_MIIRATE_M25;
6576 + phy_addr_reg.bits.speed = LTQ_MDIO_PHY_ADDR_SPEED_M10;
6577 + mii_cfg_reg.bits.miirate = LTQ_MII_MII_CFG_MIIRATE_M2P5;
6581 + if (phydev->duplex == DUPLEX_FULL)
6582 + phy_addr_reg.bits.fdup = LTQ_MDIO_PHY_ADDR_FDUP_ENABLE;
6584 + phy_addr_reg.bits.fdup = LTQ_MDIO_PHY_ADDR_FDUP_DISABLE;
6586 + ltq_writel(to_mdio_phyaddr(switch_regs, num), phy_addr_reg.val);
6592 + ltq_writel(to_mii_miicfg(switch_regs, num), mii_cfg_reg.val);
6599 +static inline u8 *ltq_eth_rx_packet_align(int rx_num)
6601 + u8 *packet = (u8 *) NetRxPackets[rx_num];
6606 + return packet + LTQ_ETH_IP_ALIGN;
6609 +static int ltq_eth_init(struct eth_device *dev, bd_t *bis)
6611 + struct ltq_eth_priv *priv = dev->priv;
6612 + struct ltq_dma_device *dma_dev = &priv->dma_dev;
6613 + struct phy_device *phydev;
6616 + for (i = 0; i < LTQ_ETHSW_MAX_GMAC; i++) {
6617 + phydev = priv->phymap[i];
6621 + phy_startup(phydev);
6622 + ltq_eth_gmac_update(phydev, i);
6625 + for (i = 0; i < LTQ_ETH_RX_BUFFER_CNT; i++)
6626 + ltq_dma_rx_map(dma_dev, i, ltq_eth_rx_packet_align(i),
6627 + LTQ_ETH_RX_DATA_SIZE);
6629 + ltq_dma_enable(dma_dev);
6637 +static void ltq_eth_halt(struct eth_device *dev)
6639 + struct ltq_eth_priv *priv = dev->priv;
6640 + struct ltq_dma_device *dma_dev = &priv->dma_dev;
6641 + struct phy_device *phydev;
6644 + ltq_dma_reset(dma_dev);
6646 + for (i = 0; i < LTQ_ETHSW_MAX_GMAC; i++) {
6647 + phydev = priv->phymap[i];
6651 + phy_shutdown(phydev);
6653 + ltq_eth_gmac_update(phydev, i);
6657 +static int ltq_eth_send(struct eth_device *dev, void *packet, int length)
6659 + struct ltq_eth_priv *priv = dev->priv;
6660 + struct ltq_dma_device *dma_dev = &priv->dma_dev;
6663 + printf("%s: packet %p, len %d\n", __func__, packet, length);
6666 + ltq_dma_tx_map(dma_dev, priv->tx_num, packet, length, 10);
6667 + priv->tx_num = (priv->tx_num + 1) % LTQ_ETH_TX_BUFFER_CNT;
6672 +static int ltq_eth_recv(struct eth_device *dev)
6674 + struct ltq_eth_priv *priv = dev->priv;
6675 + struct ltq_dma_device *dma_dev = &priv->dma_dev;
6679 + if (!ltq_dma_rx_poll(dma_dev, priv->rx_num))
6683 + printf("%s: rx_num %d\n", __func__, priv->rx_num);
6686 + len = ltq_dma_rx_length(dma_dev, priv->rx_num);
6687 + packet = ltq_eth_rx_packet_align(priv->rx_num);
6690 + printf("%s: received: packet %p, len %u, rx_num %d\n",
6691 + __func__, packet, len, priv->rx_num);
6695 + NetReceive(packet, len);
6697 + ltq_dma_rx_map(dma_dev, priv->rx_num, packet,
6698 + LTQ_ETH_RX_DATA_SIZE);
6700 + priv->rx_num = (priv->rx_num + 1) % LTQ_ETH_RX_BUFFER_CNT;
6705 +static void ltq_eth_gmac_init(int num)
6707 + struct ltq_mdio_phy_addr_reg phy_addr_reg;
6708 + struct ltq_mii_mii_cfg_reg mii_cfg_reg;
6710 + /* Reset PHY status to link down */
6711 + phy_addr_reg.val = ltq_readl(to_mdio_phyaddr(switch_regs, num));
6712 + phy_addr_reg.bits.addr = num;
6713 + phy_addr_reg.bits.lnkst = LTQ_MDIO_PHY_ADDR_LNKST_DOWN;
6714 + phy_addr_reg.bits.speed = LTQ_MDIO_PHY_ADDR_SPEED_M10;
6715 + phy_addr_reg.bits.fdup = LTQ_MDIO_PHY_ADDR_FDUP_DISABLE;
6716 + ltq_writel(to_mdio_phyaddr(switch_regs, num), phy_addr_reg.val);
6718 + /* Reset and disable MII interface */
6723 + mii_cfg_reg.val = ltq_readl(to_mii_miicfg(switch_regs, num));
6724 + mii_cfg_reg.bits.en = 0;
6725 + mii_cfg_reg.bits.res = 1;
6726 + mii_cfg_reg.bits.miirate = LTQ_MII_MII_CFG_MIIRATE_M2P5;
6727 + ltq_writel(to_mii_miicfg(switch_regs, num), mii_cfg_reg.val);
6734 + * - enable frame checksum generation
6735 + * - enable padding of short frames
6736 + * - disable flow control
6738 + ltq_writel(to_mac_ctrl(switch_regs, num, 0),
6739 + MAC_CTRL0_PADEN | MAC_CTRL0_FCS | MAC_CTRL0_FCON_NONE);
6741 + vr9_switch_sync();
6744 +static void ltq_eth_pmac_init(void)
6747 + * WAR: buffer congestion:
6748 + * - shorten preambel to 1 byte
6749 + * - set TX IPG to 7 bytes
6752 + ltq_writel(to_mac_ctrl(switch_regs, LTQ_ETHSW_PMAC, 1),
6753 + MAC_CTRL1_SHORTPRE | 7);
6757 + * WAR: systematical concept weakness ACM bug
6758 + * - set maximum number of used buffer segments to 254
6759 + * - soft-reset BM FSQM
6762 + ltq_writel(&switch_regs->bm.core.fsqm_gctrl, 253);
6763 + ltq_setbits(&switch_regs->bm.core.gctrl, BM_GCTRL_F_SRES);
6764 + ltq_clrbits(&switch_regs->bm.core.gctrl, BM_GCTRL_F_SRES);
6768 + * WAR: switch MAC drop bug
6771 + ltq_writel(to_pce_tbl_key(switch_regs, 0), 0xf);
6772 + ltq_writel(to_pce_tbl_value(switch_regs, 0), 0x40);
6773 + ltq_writel(&switch_regs->pce.core.tbl_addr, 0x3);
6774 + ltq_writel(&switch_regs->pce.core.tbl_ctrl, 0x902f);
6778 + * Configure frame header control:
6779 + * - enable flow control
6780 + * - enable CRC check for packets from DMA to PMAC
6781 + * - remove special tag from packets from PMAC to DMA
6782 + * - add CRC for packets from DMA to PMAC
6784 + ltq_writel(&switch_regs->pmac.hd_ctl, /*PMAC_HD_CTL_FC |*/
6785 + PMAC_HD_CTL_CCRC | PMAC_HD_CTL_RST | PMAC_HD_CTL_AC |
6789 + ltq_writel(&switch_regs->pmac.rx_ipg, 0x8b);
6793 + * - enable frame checksum generation
6794 + * - enable padding of short frames
6795 + * - disable flow control
6797 + ltq_writel(to_mac_ctrl(switch_regs, LTQ_ETHSW_PMAC, 0),
6798 + MAC_CTRL0_PADEN | MAC_CTRL0_FCS | MAC_CTRL0_FCON_NONE);
6800 + vr9_switch_sync();
6803 +static void ltq_eth_hw_init(void)
6807 + /* Power up ethernet and switch subsystems */
6808 + ltq_pm_enable(LTQ_PM_ETH);
6810 + /* Reset ethernet and switch subsystems */
6812 + ltq_reset_once(LTQ_RESET_ETH, 10);
6815 + /* Enable switch macro */
6816 + ltq_setbits(&switch_regs->mdio.glob_ctrl, MDIO_GLOB_CTRL_SE);
6818 + /* Disable MDIO auto-polling for all ports */
6819 + ltq_writel(&switch_regs->mdio.mdc_cfg_0, 0);
6822 + * Enable and set MDIO management clock to 2.5 MHz. This is the
6823 + * maximum clock for FE PHYs.
6824 + * Formula for clock is:
6827 + * x = ----------- - 1
6830 + ltq_writel(&switch_regs->mdio.mdc_cfg_1, MDIO_MDC_CFG1_RES |
6831 + MDIO_MDC_CFG1_MCEN | 5);
6833 + vr9_switch_sync();
6835 + /* Init MAC connected to CPU */
6836 + ltq_eth_pmac_init();
6838 + /* Init MACs connected to external MII interfaces */
6839 + for (i = 0; i < LTQ_ETHSW_MAX_GMAC; i++)
6840 + ltq_eth_gmac_init(i);
6843 +static void ltq_eth_port_config(struct ltq_eth_priv *priv,
6844 + const struct ltq_eth_port_config *port)
6846 + struct ltq_mii_mii_cfg_reg mii_cfg_reg;
6847 + struct phy_device *phydev;
6848 + int setup_gpio = 0;
6850 + switch (port->num) {
6851 + case 0: /* xMII0 */
6852 + case 1: /* xMII1 */
6853 + mii_cfg_reg.val = ltq_readl(to_mii_miicfg(switch_regs,
6855 + mii_cfg_reg.bits.en = port->flags ? 1 : 0;
6857 + switch (port->phy_if) {
6858 + case PHY_INTERFACE_MODE_MII:
6859 + if (port->flags & LTQ_ETH_PORT_PHY)
6860 + /* MII MAC mode, connected to external PHY */
6861 + mii_cfg_reg.bits.miimode =
6862 + LTQ_MII_MII_CFG_MIIMODE_MIIM;
6864 + /* MII PHY mode, connected to external MAC */
6865 + mii_cfg_reg.bits.miimode =
6866 + LTQ_MII_MII_CFG_MIIMODE_MIIP;
6869 + case PHY_INTERFACE_MODE_RMII:
6870 + if (port->flags & LTQ_ETH_PORT_PHY)
6871 + /* RMII MAC mode, connected to external PHY */
6872 + mii_cfg_reg.bits.miimode =
6873 + LTQ_MII_MII_CFG_MIIMODE_RMIIM;
6875 + /* RMII PHY mode, connected to external MAC */
6876 + mii_cfg_reg.bits.miimode =
6877 + LTQ_MII_MII_CFG_MIIMODE_RMIIP;
6880 + case PHY_INTERFACE_MODE_RGMII:
6881 + /* RGMII MAC mode, connected to external PHY */
6882 + mii_cfg_reg.bits.miimode =
6883 + LTQ_MII_MII_CFG_MIIMODE_RGMII;
6886 + /* RGMII clock delays */
6887 + ltq_writel(to_mii_pcdu(switch_regs, port->num),
6888 + port->rgmii_rx_delay << PCDU_RXDLY_SHIFT |
6889 + port->rgmii_tx_delay);
6895 + ltq_writel(to_mii_miicfg(switch_regs, port->num),
6898 + case 2: /* internal GPHY0 */
6899 + case 3: /* internal GPHY0 */
6900 + case 4: /* internal GPHY1 */
6901 + switch (port->phy_if) {
6902 + case PHY_INTERFACE_MODE_MII:
6903 + case PHY_INTERFACE_MODE_GMII:
6910 + case 5: /* internal GPHY1 or xMII2 */
6911 + mii_cfg_reg.val = ltq_readl(to_mii_miicfg(switch_regs,
6913 + mii_cfg_reg.bits.en = port->flags ? 1 : 0;
6915 + switch (port->phy_if) {
6916 + case PHY_INTERFACE_MODE_MII:
6917 + /* MII MAC mode, connected to internal GPHY */
6918 + mii_cfg_reg.bits.miimode =
6919 + LTQ_MII_MII_CFG_MIIMODE_MIIM;
6922 + case PHY_INTERFACE_MODE_RGMII:
6923 + /* RGMII MAC mode, connected to external PHY */
6924 + mii_cfg_reg.bits.miimode =
6925 + LTQ_MII_MII_CFG_MIIMODE_RGMII;
6928 + /* RGMII clock delays */
6929 + ltq_writel(to_mii_pcdu(switch_regs, port->num),
6930 + port->rgmii_rx_delay << PCDU_RXDLY_SHIFT |
6931 + port->rgmii_tx_delay);
6937 + ltq_writel(to_mii_miicfg(switch_regs, port->num),
6944 + /* Setup GPIOs for MII with external PHYs/MACs */
6947 + gpio_set_altfunc(42, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR,
6950 + gpio_set_altfunc(43, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR,
6954 + /* Connect to internal/external PHYs */
6955 + if (port->flags & LTQ_ETH_PORT_PHY) {
6956 + phydev = phy_connect(priv->bus, port->phy_addr, priv->dev,
6959 + phy_config(phydev);
6961 + priv->phymap[port->num] = phydev;
6965 +int ltq_eth_initialize(const struct ltq_eth_board_config *board_config)
6967 + struct eth_device *dev;
6968 + struct mii_dev *bus;
6969 + struct ltq_eth_priv *priv;
6970 + struct ltq_dma_device *dma_dev;
6973 + build_check_vr9_registers();
6976 + ltq_eth_hw_init();
6978 + dev = calloc(1, sizeof(struct eth_device));
6982 + priv = calloc(1, sizeof(struct ltq_eth_priv));
6986 + bus = mdio_alloc();
6990 + sprintf(dev->name, LTQ_ETH_DRV_NAME);
6992 + dev->init = ltq_eth_init;
6993 + dev->halt = ltq_eth_halt;
6994 + dev->recv = ltq_eth_recv;
6995 + dev->send = ltq_eth_send;
6997 + sprintf(bus->name, LTQ_MDIO_DRV_NAME);
6998 + bus->read = vr9_switch_mdio_read;
6999 + bus->write = vr9_switch_mdio_write;
7002 + dma_dev = &priv->dma_dev;
7003 + dma_dev->port = 0;
7004 + dma_dev->rx_chan.chan_no = 0;
7005 + dma_dev->rx_chan.class = 0;
7006 + dma_dev->rx_chan.num_desc = LTQ_ETH_RX_BUFFER_CNT;
7007 + dma_dev->rx_endian_swap = LTQ_DMA_ENDIANESS_B3_B2_B1_B0;
7008 + dma_dev->rx_burst_len = LTQ_DMA_BURST_2WORDS;
7009 + dma_dev->tx_chan.chan_no = 1;
7010 + dma_dev->tx_chan.class = 0;
7011 + dma_dev->tx_chan.num_desc = LTQ_ETH_TX_BUFFER_CNT;
7012 + dma_dev->tx_endian_swap = LTQ_DMA_ENDIANESS_B3_B2_B1_B0;
7013 + dma_dev->tx_burst_len = LTQ_DMA_BURST_2WORDS;
7018 + ret = ltq_dma_register(dma_dev);
7022 + ret = mdio_register(bus);
7026 + ret = eth_register(dev);
7030 + for (i = 0; i < board_config->num_ports; i++)
7031 + ltq_eth_port_config(priv, &board_config->ports[i]);
7035 --- a/drivers/net/phy/Makefile
7036 +++ b/drivers/net/phy/Makefile
7037 @@ -20,6 +20,7 @@ COBJS-$(CONFIG_PHY_BROADCOM) += broadcom
7038 COBJS-$(CONFIG_PHY_DAVICOM) += davicom.o
7039 COBJS-$(CONFIG_PHY_ET1011C) += et1011c.o
7040 COBJS-$(CONFIG_PHY_ICPLUS) += icplus.o
7041 +COBJS-$(CONFIG_PHY_LANTIQ) += lantiq.o
7042 COBJS-$(CONFIG_PHY_LXT) += lxt.o
7043 COBJS-$(CONFIG_PHY_MARVELL) += marvell.o
7044 COBJS-$(CONFIG_PHY_MICREL) += micrel.o
7046 +++ b/drivers/net/phy/lantiq.c
7049 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
7051 + * SPDX-License-Identifier: GPL-2.0+
7056 +#include <common.h>
7057 +#include <miiphy.h>
7059 +#define ADVERTIZE_MPD (1 << 10)
7061 +DECLARE_GLOBAL_DATA_PTR;
7064 + * Update link status.
7066 + * Based on genphy_update_link in phylib.c
7068 +static int ltq_phy_update_link(struct phy_device *phydev)
7070 + unsigned int mii_reg;
7072 + mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
7075 + * If we already saw the link up, and it hasn't gone down, then
7076 + * we don't need to wait for autoneg again
7078 + if (phydev->link && mii_reg & BMSR_LSTATUS)
7081 + if ((mii_reg & BMSR_ANEGCAPABLE) && !(mii_reg & BMSR_ANEGCOMPLETE)) {
7085 + /* Read the link a second time to clear the latched state */
7086 + mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
7088 + if (mii_reg & BMSR_LSTATUS)
7098 + * Update speed and duplex.
7100 + * Based on genphy_parse_link in phylib.c
7102 +static int ltq_phy_parse_link(struct phy_device *phydev)
7104 + unsigned int mii_reg;
7106 + mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
7108 + /* We're using autonegotiation */
7109 + if (mii_reg & BMSR_ANEGCAPABLE) {
7113 + /* Check for gigabit capability */
7114 + if (mii_reg & BMSR_ERCAP) {
7115 + /* We want a list of states supported by
7116 + * both PHYs in the link
7118 + gblpa = phy_read(phydev, MDIO_DEVAD_NONE, MII_STAT1000);
7119 + gblpa &= phy_read(phydev,
7120 + MDIO_DEVAD_NONE, MII_CTRL1000) << 2;
7123 + /* Set the baseline so we only have to set them
7124 + * if they're different
7126 + phydev->speed = SPEED_10;
7127 + phydev->duplex = DUPLEX_HALF;
7129 + /* Check the gigabit fields */
7130 + if (gblpa & (PHY_1000BTSR_1000FD | PHY_1000BTSR_1000HD)) {
7131 + phydev->speed = SPEED_1000;
7133 + if (gblpa & PHY_1000BTSR_1000FD)
7134 + phydev->duplex = DUPLEX_FULL;
7140 + lpa = phy_read(phydev, MDIO_DEVAD_NONE, MII_ADVERTISE);
7141 + lpa &= phy_read(phydev, MDIO_DEVAD_NONE, MII_LPA);
7143 + if (lpa & (LPA_100FULL | LPA_100HALF)) {
7144 + phydev->speed = SPEED_100;
7146 + if (lpa & LPA_100FULL)
7147 + phydev->duplex = DUPLEX_FULL;
7149 + } else if (lpa & LPA_10FULL)
7150 + phydev->duplex = DUPLEX_FULL;
7152 + u32 bmcr = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);
7154 + phydev->speed = SPEED_10;
7155 + phydev->duplex = DUPLEX_HALF;
7157 + if (bmcr & BMCR_FULLDPLX)
7158 + phydev->duplex = DUPLEX_FULL;
7160 + if (bmcr & BMCR_SPEED1000)
7161 + phydev->speed = SPEED_1000;
7162 + else if (bmcr & BMCR_SPEED100)
7163 + phydev->speed = SPEED_100;
7169 +static int ltq_phy_config(struct phy_device *phydev)
7173 + /* Advertise as Multi-port device */
7174 + val = phy_read(phydev, MDIO_DEVAD_NONE, MII_CTRL1000);
7175 + val |= ADVERTIZE_MPD;
7176 + phy_write(phydev, MDIO_DEVAD_NONE, MII_CTRL1000, val);
7178 + genphy_config_aneg(phydev);
7183 +static int ltq_phy_startup(struct phy_device *phydev)
7186 + * Update PHY status immediately without any delays as genphy_startup
7187 + * does because VRX200 switch needs to be configured dependent
7188 + * on this information.
7190 + ltq_phy_update_link(phydev);
7191 + ltq_phy_parse_link(phydev);
7193 + debug("ltq_phy: addr %d, link %d, speed %d, duplex %d\n",
7194 + phydev->addr, phydev->link, phydev->speed, phydev->duplex);
7199 +static struct phy_driver xrx_11g_13_driver = {
7200 + .name = "Lantiq XWAY XRX PHY11G v1.3 and earlier",
7201 + .uid = 0x030260D0,
7202 + .mask = 0xFFFFFFF0,
7203 + .features = PHY_GBIT_FEATURES,
7204 + .config = ltq_phy_config,
7205 + .startup = ltq_phy_startup,
7206 + .shutdown = genphy_shutdown,
7209 +static struct phy_driver xrx_11g_14_driver = {
7210 + .name = "Lantiq XWAY XRX PHY11G v1.4 and later",
7211 + .uid = 0xd565a408,
7212 + .mask = 0xFFFFFFF8,
7213 + .features = PHY_GBIT_FEATURES,
7214 + .config = ltq_phy_config,
7215 + .startup = ltq_phy_startup,
7216 + .shutdown = genphy_shutdown,
7219 +static struct phy_driver xrx_22f_14_driver = {
7220 + .name = "Lantiq XWAY XRX PHY22F v1.4 and later",
7221 + .uid = 0xd565a418,
7222 + .mask = 0xFFFFFFF8,
7223 + .features = PHY_BASIC_FEATURES,
7224 + .config = ltq_phy_config,
7225 + .startup = ltq_phy_startup,
7226 + .shutdown = genphy_shutdown,
7229 +static struct phy_driver pef7071_driver = {
7230 + .name = "Lantiq XWAY PEF7071",
7231 + .uid = 0xd565a400,
7232 + .mask = 0xFFFFFFFF,
7233 + .features = PHY_GBIT_FEATURES,
7234 + .config = ltq_phy_config,
7235 + .startup = ltq_phy_startup,
7236 + .shutdown = genphy_shutdown,
7239 +static struct phy_driver xrx_genphy_driver = {
7240 + .name = "Generic PHY at Lantiq XWAY XRX switch",
7244 + .config = genphy_config,
7245 + .startup = ltq_phy_startup,
7246 + .shutdown = genphy_shutdown,
7249 +int phy_lantiq_init(void)
7251 +#ifdef CONFIG_NEEDS_MANUAL_RELOC
7252 + xrx_11g_13_driver.config = ltq_phy_config;
7253 + xrx_11g_13_driver.startup = ltq_phy_startup;
7254 + xrx_11g_13_driver.shutdown = genphy_shutdown;
7255 + xrx_11g_13_driver.name += gd->reloc_off;
7257 + xrx_11g_14_driver.config = ltq_phy_config;
7258 + xrx_11g_14_driver.startup = ltq_phy_startup;
7259 + xrx_11g_14_driver.shutdown = genphy_shutdown;
7260 + xrx_11g_14_driver.name += gd->reloc_off;
7262 + xrx_22f_14_driver.config = ltq_phy_config;
7263 + xrx_22f_14_driver.startup = ltq_phy_startup;
7264 + xrx_22f_14_driver.shutdown = genphy_shutdown;
7265 + xrx_22f_14_driver.name += gd->reloc_off;
7267 + pef7071_driver.config = ltq_phy_config;
7268 + pef7071_driver.startup = ltq_phy_startup;
7269 + pef7071_driver.shutdown = genphy_shutdown;
7270 + pef7071_driver.name += gd->reloc_off;
7272 + xrx_genphy_driver.config = genphy_config;
7273 + xrx_genphy_driver.startup = ltq_phy_startup;
7274 + xrx_genphy_driver.shutdown = genphy_shutdown;
7275 + xrx_genphy_driver.name += gd->reloc_off;
7278 + phy_register(&xrx_11g_13_driver);
7279 + phy_register(&xrx_11g_14_driver);
7280 + phy_register(&xrx_22f_14_driver);
7281 + phy_register(&pef7071_driver);
7282 + phy_register(&xrx_genphy_driver);
7286 --- a/drivers/net/phy/phy.c
7287 +++ b/drivers/net/phy/phy.c
7289 #include <command.h>
7293 #include <linux/err.h>
7295 +DECLARE_GLOBAL_DATA_PTR;
7297 /* Generic PHY support and helper functions */
7300 @@ -440,6 +441,16 @@ static LIST_HEAD(phy_drivers);
7304 +#ifdef CONFIG_NEEDS_MANUAL_RELOC
7305 + INIT_LIST_HEAD(&phy_drivers);
7307 + genphy_driver.config = genphy_config;
7308 + genphy_driver.startup = genphy_startup;
7309 + genphy_driver.shutdown = genphy_shutdown;
7311 + genphy_driver.name += gd->reloc_off;
7314 #ifdef CONFIG_PHY_ATHEROS
7317 @@ -455,6 +466,9 @@ int phy_init(void)
7318 #ifdef CONFIG_PHY_ICPLUS
7321 +#ifdef CONFIG_PHY_LANTIQ
7322 + phy_lantiq_init();
7324 #ifdef CONFIG_PHY_LXT
7327 --- a/drivers/serial/Makefile
7328 +++ b/drivers/serial/Makefile
7329 @@ -24,6 +24,7 @@ COBJS-$(CONFIG_SYS_NS16550_SERIAL) += se
7330 COBJS-$(CONFIG_IMX_SERIAL) += serial_imx.o
7331 COBJS-$(CONFIG_IXP_SERIAL) += serial_ixp.o
7332 COBJS-$(CONFIG_KS8695_SERIAL) += serial_ks8695.o
7333 +COBJS-$(CONFIG_LANTIQ_SERIAL) += serial_lantiq.o
7334 COBJS-$(CONFIG_MAX3100_SERIAL) += serial_max3100.o
7335 COBJS-$(CONFIG_MXC_UART) += serial_mxc.o
7336 COBJS-$(CONFIG_PL010_SERIAL) += serial_pl01x.o
7337 --- a/drivers/serial/serial.c
7338 +++ b/drivers/serial/serial.c
7339 @@ -160,6 +160,7 @@ serial_initfunc(sa1100_serial_initialize
7340 serial_initfunc(sh_serial_initialize);
7341 serial_initfunc(arm_dcc_initialize);
7342 serial_initfunc(mxs_auart_initialize);
7343 +serial_initfunc(ltq_serial_initialize);
7346 * serial_register() - Register serial driver with serial driver core
7347 @@ -253,6 +254,7 @@ void serial_initialize(void)
7348 sh_serial_initialize();
7349 arm_dcc_initialize();
7350 mxs_auart_initialize();
7351 + ltq_serial_initialize();
7353 serial_assign(default_serial_console()->name);
7356 +++ b/drivers/serial/serial_lantiq.c
7359 + * Copyright (C) 2010 Thomas Langer <thomas.langer@lantiq.com>
7360 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
7362 + * SPDX-License-Identifier: GPL-2.0+
7365 +#include <common.h>
7366 +#include <serial.h>
7367 +#include <asm/errno.h>
7368 +#include <asm/arch/soc.h>
7369 +#include <asm/lantiq/clk.h>
7370 +#include <asm/lantiq/io.h>
7372 +#if CONFIG_CONSOLE_ASC == 0
7373 +#define LTQ_ASC_BASE LTQ_ASC0_BASE
7375 +#define LTQ_ASC_BASE LTQ_ASC1_BASE
7378 +#define LTQ_ASC_ID_TXFS_SHIFT 24
7379 +#define LTQ_ASC_ID_TXFS_MASK (0x3F << LTQ_ASC_ID_TXFS_SHIFT)
7380 +#define LTQ_ASC_ID_RXFS_SHIFT 16
7381 +#define LTQ_ASC_ID_RXFS_MASK (0x3F << LTQ_ASC_ID_RXFS_SHIFT)
7383 +#define LTQ_ASC_MCON_R (1 << 15)
7384 +#define LTQ_ASC_MCON_FDE (1 << 9)
7386 +#define LTQ_ASC_WHBSTATE_SETREN (1 << 1)
7387 +#define LTQ_ASC_WHBSTATE_CLRREN (1 << 0)
7389 +#define LTQ_ASC_RXFCON_RXFITL_SHIFT 8
7390 +#define LTQ_ASC_RXFCON_RXFITL_MASK (0x3F << LTQ_ASC_RXFCON_RXFITL_SHIFT)
7391 +#define LTQ_ASC_RXFCON_RXFITL_RXFFLU (1 << 1)
7392 +#define LTQ_ASC_RXFCON_RXFITL_RXFEN (1 << 0)
7394 +#define LTQ_ASC_TXFCON_TXFITL_SHIFT 8
7395 +#define LTQ_ASC_TXFCON_TXFITL_MASK (0x3F << LTQ_ASC_TXFCON_TXFITL_SHIFT)
7396 +#define LTQ_ASC_TXFCON_TXFITL_TXFFLU (1 << 1)
7397 +#define LTQ_ASC_TXFCON_TXFITL_TXFEN (1 << 0)
7399 +#define LTQ_ASC_FSTAT_TXFREE_SHIFT 24
7400 +#define LTQ_ASC_FSTAT_TXFREE_MASK (0x3F << LTQ_ASC_FSTAT_TXFREE_SHIFT)
7401 +#define LTQ_ASC_FSTAT_RXFREE_SHIFT 16
7402 +#define LTQ_ASC_FSTAT_RXFREE_MASK (0x3F << LTQ_ASC_FSTAT_RXFREE_SHIFT)
7403 +#define LTQ_ASC_FSTAT_TXFFL_SHIFT 8
7404 +#define LTQ_ASC_FSTAT_TXFFL_MASK (0x3F << LTQ_ASC_FSTAT_TXFFL_SHIFT)
7405 +#define LTQ_ASC_FSTAT_RXFFL_MASK 0x3F
7407 +#ifdef __BIG_ENDIAN
7408 +#define LTQ_ASC_RBUF_OFFSET 3
7409 +#define LTQ_ASC_TBUF_OFFSET 3
7411 +#define LTQ_ASC_RBUF_OFFSET 0
7412 +#define LTQ_ASC_TBUF_OFFSET 0
7415 +struct ltq_asc_regs {
7443 +DECLARE_GLOBAL_DATA_PTR;
7445 +static struct ltq_asc_regs *ltq_asc_regs =
7446 + (struct ltq_asc_regs *) CKSEG1ADDR(LTQ_ASC_BASE);
7448 +static int ltq_serial_init(void)
7450 + /* Set clock divider for normal run mode to 1 and enable module */
7451 + ltq_writel(<q_asc_regs->clc, 0x100);
7453 + /* Reset MCON register */
7454 + ltq_writel(<q_asc_regs->mcon, 0);
7456 + /* Use Port A as receiver input */
7457 + ltq_writel(<q_asc_regs->pisel, 0);
7459 + /* Enable and flush RX/TX FIFOs */
7460 + ltq_setbits(<q_asc_regs->rxfcon,
7461 + LTQ_ASC_RXFCON_RXFITL_RXFFLU | LTQ_ASC_RXFCON_RXFITL_RXFEN);
7462 + ltq_setbits(<q_asc_regs->txfcon,
7463 + LTQ_ASC_TXFCON_TXFITL_TXFFLU | LTQ_ASC_TXFCON_TXFITL_TXFEN);
7467 + /* Disable error flags, enable receiver */
7468 + ltq_writel(<q_asc_regs->whbstate, LTQ_ASC_WHBSTATE_SETREN);
7475 + * Baudrate = ----- * -------------
7476 + * 512 16 * (bg + 1)
7478 +static void ltq_serial_calc_br_fdv(unsigned long asc_clk,
7479 + unsigned long baudrate, u16 *fdv,
7482 + const u32 c = asc_clk / (16 * 512);
7484 + u32 bg_calc, br_calc, i;
7487 + for (i = 512; i > 0; i--) {
7488 + /* Calc bg for current fdv value */
7489 + bg_calc = i * c / baudrate;
7491 + /* Impossible baudrate */
7496 + * Calc diff to target baudrate dependent on current
7497 + * bg and fdv values
7499 + br_calc = i * c / bg_calc;
7500 + if (br_calc > baudrate)
7501 + diff2 = br_calc - baudrate;
7503 + diff2 = baudrate - br_calc;
7505 + /* Perfect values found */
7508 + *bg = bg_calc - 1;
7512 + if (diff2 < diff1) {
7514 + *bg = bg_calc - 1;
7520 +static void ltq_serial_setbrg(void)
7522 + unsigned long asc_clk, baudrate;
7526 + /* ASC clock is same as FPI clock with CLC.RMS = 1 */
7527 + asc_clk = ltq_get_bus_clock();
7528 + baudrate = gd->baudrate;
7530 + /* Calculate FDV and BG values */
7531 + ltq_serial_calc_br_fdv(asc_clk, baudrate, &fdv, &bg);
7533 + /* Disable baudrate generator */
7534 + ltq_clrbits(<q_asc_regs->mcon, LTQ_ASC_MCON_R);
7536 + /* Enable fractional divider */
7537 + ltq_setbits(<q_asc_regs->mcon, LTQ_ASC_MCON_FDE);
7539 + /* Set fdv and bg values */
7540 + ltq_writel(<q_asc_regs->fdv, fdv);
7541 + ltq_writel(<q_asc_regs->bg, bg);
7543 + /* Enable baudrate generator */
7544 + ltq_setbits(<q_asc_regs->mcon, LTQ_ASC_MCON_R);
7547 +static unsigned int ltq_serial_tx_free(void)
7549 + unsigned int txfree;
7551 + txfree = (ltq_readl(<q_asc_regs->fstat) &
7552 + LTQ_ASC_FSTAT_TXFREE_MASK) >>
7553 + LTQ_ASC_FSTAT_TXFREE_SHIFT;
7558 +static unsigned int ltq_serial_rx_fill(void)
7560 + unsigned int rxffl;
7562 + rxffl = ltq_readl(<q_asc_regs->fstat) & LTQ_ASC_FSTAT_RXFFL_MASK;
7567 +static void ltq_serial_tx(const char c)
7569 + ltq_writeb(<q_asc_regs->tbuf[LTQ_ASC_TBUF_OFFSET], c);
7572 +static u8 ltq_serial_rx(void)
7574 + return ltq_readb(<q_asc_regs->rbuf[LTQ_ASC_RBUF_OFFSET]);
7577 +static void ltq_serial_putc(const char c)
7580 + ltq_serial_putc('\r');
7582 + while (!ltq_serial_tx_free())
7588 +static int ltq_serial_getc(void)
7590 + while (!ltq_serial_rx_fill())
7593 + return ltq_serial_rx();
7596 +static int ltq_serial_tstc(void)
7598 + return (0 != ltq_serial_rx_fill());
7601 +static struct serial_device ltq_serial_drv = {
7602 + .name = "ltq_serial",
7603 + .start = ltq_serial_init,
7605 + .setbrg = ltq_serial_setbrg,
7606 + .putc = ltq_serial_putc,
7607 + .puts = default_serial_puts,
7608 + .getc = ltq_serial_getc,
7609 + .tstc = ltq_serial_tstc,
7612 +void ltq_serial_initialize(void)
7614 + serial_register(<q_serial_drv);
7617 +__weak struct serial_device *default_serial_console(void)
7619 + return <q_serial_drv;
7621 --- a/drivers/spi/Makefile
7622 +++ b/drivers/spi/Makefile
7623 @@ -25,6 +25,7 @@ COBJS-$(CONFIG_DAVINCI_SPI) += davinci_s
7624 COBJS-$(CONFIG_EXYNOS_SPI) += exynos_spi.o
7625 COBJS-$(CONFIG_ICH_SPI) += ich.o
7626 COBJS-$(CONFIG_KIRKWOOD_SPI) += kirkwood_spi.o
7627 +COBJS-$(CONFIG_LANTIQ_SPI) += lantiq_spi.o
7628 COBJS-$(CONFIG_MPC52XX_SPI) += mpc52xx_spi.o
7629 COBJS-$(CONFIG_MPC8XXX_SPI) += mpc8xxx_spi.o
7630 COBJS-$(CONFIG_MXC_SPI) += mxc_spi.o
7632 +++ b/drivers/spi/lantiq_spi.c
7635 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
7637 + * SPDX-License-Identifier: GPL-2.0+
7640 +#include <common.h>
7642 +#include <malloc.h>
7643 +#include <watchdog.h>
7644 +#include <asm/gpio.h>
7645 +#include <asm/lantiq/io.h>
7646 +#include <asm/lantiq/clk.h>
7647 +#include <asm/lantiq/pm.h>
7648 +#include <asm/arch/soc.h>
7650 +#define LTQ_SPI_CLC_RMC_SHIFT 8
7651 +#define LTQ_SPI_CLC_RMC_MASK (0xFF << LTQ_SPI_CLC_RMC_SHIFT)
7652 +#define LTQ_SPI_CLC_DISS (1 << 1)
7653 +#define LTQ_SPI_CLC_DISR 1
7655 +#define LTQ_SPI_ID_TXFS_SHIFT 24
7656 +#define LTQ_SPI_ID_TXFS_MASK (0x3F << LTQ_SPI_ID_TXFS_SHIFT)
7657 +#define LTQ_SPI_ID_RXFS_SHIFT 16
7658 +#define LTQ_SPI_ID_RXFS_MASK (0x3F << LTQ_SPI_ID_RXFS_SHIFT)
7660 +#define LTQ_SPI_CON_ENBV (1 << 22)
7661 +#define LTQ_SPI_CON_BM_SHIFT 16
7662 +#define LTQ_SPI_CON_BM_MASK (0x1F << LTQ_SPI_CON_BM_SHIFT)
7663 +#define LTQ_SPI_CON_IDLE (1 << 23)
7664 +#define LTQ_SPI_CON_RUEN (1 << 12)
7665 +#define LTQ_SPI_CON_AEN (1 << 10)
7666 +#define LTQ_SPI_CON_REN (1 << 9)
7667 +#define LTQ_SPI_CON_TEN (1 << 8)
7668 +#define LTQ_SPI_CON_LB (1 << 7)
7669 +#define LTQ_SPI_CON_PO (1 << 6)
7670 +#define LTQ_SPI_CON_PH (1 << 5)
7671 +#define LTQ_SPI_CON_HB (1 << 4)
7672 +#define LTQ_SPI_CON_RXOFF (1 << 1)
7673 +#define LTQ_SPI_CON_TXOFF 1
7675 +#define LTQ_SPI_STAT_RXBV_SHIFT 28
7676 +#define LTQ_SPI_STAT_RXBV_MASK (0x7 << LTQ_SPI_STAT_RXBV_SHIFT)
7677 +#define LTQ_SPI_STAT_BSY (1 << 13)
7679 +#define LTQ_SPI_WHBSTATE_SETMS (1 << 3)
7680 +#define LTQ_SPI_WHBSTATE_CLRMS (1 << 2)
7681 +#define LTQ_SPI_WHBSTATE_SETEN (1 << 1)
7682 +#define LTQ_SPI_WHBSTATE_CLREN 1
7683 +#define LTQ_SPI_WHBSTATE_CLR_ERRORS 0x0F50
7685 +#define LTQ_SPI_TXFCON_TXFLU (1 << 1)
7686 +#define LTQ_SPI_TXFCON_TXFEN 1
7688 +#define LTQ_SPI_RXFCON_RXFLU (1 << 1)
7689 +#define LTQ_SPI_RXFCON_RXFEN 1
7691 +#define LTQ_SPI_FSTAT_RXFFL_MASK 0x3f
7692 +#define LTQ_SPI_FSTAT_TXFFL_SHIFT 8
7693 +#define LTQ_SPI_FSTAT_TXFFL_MASK (0x3f << LTQ_SPI_FSTAT_TXFFL_SHIFT)
7695 +#define LTQ_SPI_RXREQ_RXCNT_MASK 0xFFFF
7696 +#define LTQ_SPI_RXCNT_TODO_MASK 0xFFFF
7698 +#define LTQ_SPI_GPIO_DIN 16
7699 +#define LTQ_SPI_GPIO_DOUT 17
7700 +#define LTQ_SPI_GPIO_CLK 18
7702 +struct ltq_spi_regs {
7703 + __be32 clc; /* Clock control */
7704 + __be32 pisel; /* Port input select */
7705 + __be32 id; /* Identification */
7707 + __be32 con; /* Control */
7708 + __be32 stat; /* Status */
7709 + __be32 whbstate; /* Write HW modified state */
7711 + __be32 tb; /* Transmit buffer */
7712 + __be32 rb; /* Receive buffer */
7714 + __be32 rxfcon; /* Recevie FIFO control */
7715 + __be32 txfcon; /* Transmit FIFO control */
7716 + __be32 fstat; /* FIFO status */
7718 + __be32 brt; /* Baudrate timer */
7719 + __be32 brstat; /* Baudrate timer status */
7721 + __be32 sfcon; /* Serial frame control */
7722 + __be32 sfstat; /* Serial frame status */
7724 + __be32 gpocon; /* General purpose output control */
7725 + __be32 gpostat; /* General purpose output status */
7726 + __be32 fgpo; /* Force general purpose output */
7728 + __be32 rxreq; /* Receive request */
7729 + __be32 rxcnt; /* Receive count */
7731 + __be32 dmacon; /* DMA control */
7733 + __be32 irnen; /* Interrupt node enable */
7734 + __be32 irnicr; /* Interrupt node interrupt capture */
7735 + __be32 irncr; /* Interrupt node control */
7738 +struct ltq_spi_drv_data {
7739 + struct ltq_spi_regs __iomem *regs;
7741 + struct spi_slave slave;
7742 + unsigned int max_hz;
7743 + unsigned int mode;
7744 + unsigned int tx_todo;
7745 + unsigned int rx_todo;
7746 + unsigned int rx_req;
7747 + unsigned int bits_per_word;
7748 + unsigned int speed_hz;
7754 +static struct ltq_spi_drv_data *to_ltq_spi_slave(struct spi_slave *slave)
7756 + return container_of(slave, struct ltq_spi_drv_data, slave);
7759 +#ifdef CONFIG_SPL_BUILD
7761 + * We do not have or want malloc in a SPI flash SPL.
7762 + * Neither we have to support multiple SPI slaves. Thus we put the
7763 + * SPI slave context in BSS for SPL builds.
7765 +static struct ltq_spi_drv_data ltq_spi_slave;
7767 +static struct ltq_spi_drv_data *ltq_spi_slave_alloc(unsigned int bus,
7770 + ltq_spi_slave.slave.bus = bus;
7771 + ltq_spi_slave.slave.cs = cs;
7773 + return <q_spi_slave;
7776 +static void ltq_spi_slave_free(struct spi_slave *slave)
7780 +static struct ltq_spi_drv_data *ltq_spi_slave_alloc(unsigned int bus,
7783 + return spi_alloc_slave(struct ltq_spi_drv_data, bus, cs);
7786 +static void ltq_spi_slave_free(struct spi_slave *slave)
7788 + struct ltq_spi_drv_data *drv;
7791 + drv = to_ltq_spi_slave(slave);
7797 +static unsigned int tx_fifo_size(struct ltq_spi_drv_data *drv)
7799 + u32 id = ltq_readl(&drv->regs->id);
7801 + return (id & LTQ_SPI_ID_TXFS_MASK) >> LTQ_SPI_ID_TXFS_SHIFT;
7804 +static unsigned int rx_fifo_size(struct ltq_spi_drv_data *drv)
7806 + u32 id = ltq_readl(&drv->regs->id);
7808 + return (id & LTQ_SPI_ID_RXFS_MASK) >> LTQ_SPI_ID_RXFS_SHIFT;
7811 +static unsigned int tx_fifo_level(struct ltq_spi_drv_data *drv)
7813 + u32 fstat = ltq_readl(&drv->regs->fstat);
7815 + return (fstat & LTQ_SPI_FSTAT_TXFFL_MASK) >> LTQ_SPI_FSTAT_TXFFL_SHIFT;
7818 +static unsigned int rx_fifo_level(struct ltq_spi_drv_data *drv)
7820 + u32 fstat = ltq_readl(&drv->regs->fstat);
7822 + return fstat & LTQ_SPI_FSTAT_RXFFL_MASK;
7825 +static unsigned int tx_fifo_free(struct ltq_spi_drv_data *drv)
7827 + return tx_fifo_size(drv) - tx_fifo_level(drv);
7830 +static void hw_power_on(struct ltq_spi_drv_data *drv)
7834 + /* Power-up mdule */
7835 + ltq_pm_enable(LTQ_PM_SPI);
7838 + * Set clock divider for run mode to 1 to
7839 + * run at same frequency as FPI bus
7841 + clc = (1 << LTQ_SPI_CLC_RMC_SHIFT);
7842 + ltq_writel(&drv->regs->clc, clc);
7845 +static void hw_reset_fifos(struct ltq_spi_drv_data *drv)
7849 + val = LTQ_SPI_TXFCON_TXFEN | LTQ_SPI_TXFCON_TXFLU;
7850 + ltq_writel(&drv->regs->txfcon, val);
7852 + val = LTQ_SPI_RXFCON_RXFEN | LTQ_SPI_RXFCON_RXFLU;
7853 + ltq_writel(&drv->regs->rxfcon, val);
7856 +static int hw_is_busy(struct ltq_spi_drv_data *drv)
7858 + u32 stat = ltq_readl(&drv->regs->stat);
7860 + return stat & LTQ_SPI_STAT_BSY;
7863 +static void hw_enter_config_mode(struct ltq_spi_drv_data *drv)
7865 + ltq_writel(&drv->regs->whbstate, LTQ_SPI_WHBSTATE_CLREN);
7868 +static void hw_enter_active_mode(struct ltq_spi_drv_data *drv)
7870 + ltq_writel(&drv->regs->whbstate, LTQ_SPI_WHBSTATE_SETEN);
7873 +static void hw_setup_speed_hz(struct ltq_spi_drv_data *drv,
7874 + unsigned int max_speed_hz)
7876 + unsigned int spi_hz, speed_hz, brt;
7879 + * SPI module clock is derived from FPI bus clock dependent on
7880 + * divider value in CLC.RMS which is always set to 1.
7883 + * baudrate = --------------
7886 + spi_hz = ltq_get_bus_clock() / 2;
7888 + /* TODO: optimize baudrate calculation */
7889 + for (brt = 0; brt < 0xFFFF; brt++) {
7890 + speed_hz = spi_hz / (brt + 1);
7891 + if (speed_hz <= max_speed_hz)
7895 + ltq_writel(&drv->regs->brt, brt);
7898 +static void hw_setup_bits_per_word(struct ltq_spi_drv_data *drv,
7899 + unsigned int bits_per_word)
7903 + /* CON.BM value = bits_per_word - 1 */
7904 + bm = (bits_per_word - 1) << LTQ_SPI_CON_BM_SHIFT;
7906 + ltq_clrsetbits(&drv->regs->con, LTQ_SPI_CON_BM_MASK, bm);
7909 +static void hw_setup_clock_mode(struct ltq_spi_drv_data *drv, unsigned int mode)
7911 + u32 con_set = 0, con_clr = 0;
7914 + * SPI mode mapping in CON register:
7915 + * Mode CPOL CPHA CON.PO CON.PH
7921 + if (mode & SPI_CPHA)
7922 + con_clr |= LTQ_SPI_CON_PH;
7924 + con_set |= LTQ_SPI_CON_PH;
7926 + if (mode & SPI_CPOL)
7927 + con_set |= LTQ_SPI_CON_PO | LTQ_SPI_CON_IDLE;
7929 + con_clr |= LTQ_SPI_CON_PO | LTQ_SPI_CON_IDLE;
7931 + /* Set heading control */
7932 + if (mode & SPI_LSB_FIRST)
7933 + con_clr |= LTQ_SPI_CON_HB;
7935 + con_set |= LTQ_SPI_CON_HB;
7937 + /* Set loopback mode */
7938 + if (mode & SPI_LOOP)
7939 + con_set |= LTQ_SPI_CON_LB;
7941 + con_clr |= LTQ_SPI_CON_LB;
7943 + ltq_clrsetbits(&drv->regs->con, con_clr, con_set);
7946 +static void hw_set_rxtx(struct ltq_spi_drv_data *drv)
7950 + /* Configure transmitter and receiver */
7951 + con = ltq_readl(&drv->regs->con);
7953 + con &= ~LTQ_SPI_CON_TXOFF;
7955 + con |= LTQ_SPI_CON_TXOFF;
7958 + con &= ~LTQ_SPI_CON_RXOFF;
7960 + con |= LTQ_SPI_CON_RXOFF;
7962 + ltq_writel(&drv->regs->con, con);
7965 +static void hw_init(struct ltq_spi_drv_data *drv)
7969 + /* Put controller into config mode */
7970 + hw_enter_config_mode(drv);
7972 + /* Disable all interrupts */
7973 + ltq_writel(&drv->regs->irnen, 0);
7975 + /* Clear error flags */
7976 + ltq_clrsetbits(&drv->regs->whbstate, 0, LTQ_SPI_WHBSTATE_CLR_ERRORS);
7978 + /* Enable error checking, disable TX/RX */
7979 + ltq_writel(&drv->regs->con, LTQ_SPI_CON_RUEN | LTQ_SPI_CON_AEN |
7980 + LTQ_SPI_CON_TEN | LTQ_SPI_CON_REN | LTQ_SPI_CON_TXOFF |
7981 + LTQ_SPI_CON_RXOFF);
7983 + /* Setup default SPI mode */
7984 + drv->bits_per_word = 8;
7985 + drv->speed_hz = 0;
7986 + hw_setup_bits_per_word(drv, drv->bits_per_word);
7987 + hw_setup_clock_mode(drv, SPI_MODE_0);
7989 + /* Enable master mode and clear error flags */
7990 + ltq_writel(&drv->regs->whbstate, LTQ_SPI_WHBSTATE_SETMS |
7991 + LTQ_SPI_WHBSTATE_CLR_ERRORS);
7993 + /* Reset GPIO/CS registers */
7994 + ltq_writel(&drv->regs->gpocon, 0);
7995 + ltq_writel(&drv->regs->fgpo, 0xFF00);
7997 + /* Enable and flush FIFOs */
7998 + hw_reset_fifos(drv);
8000 + /* SPI/DIN input */
8001 + gpio_set_altfunc(16, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_IN);
8002 + /* SPI/DOUT output */
8003 + gpio_set_altfunc(17, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT);
8004 + /* SPI/CLK output */
8005 + gpio_set_altfunc(18, GPIO_ALTSEL_SET, GPIO_ALTSEL_CLR, GPIO_DIR_OUT);
8008 +static void tx_fifo_write(struct ltq_spi_drv_data *drv)
8014 + unsigned int tx_free = tx_fifo_free(drv);
8016 + while (drv->tx_todo && tx_free) {
8017 + switch (drv->bits_per_word) {
8025 + tx16 = (u16 *) drv->tx;
8027 + drv->tx_todo -= 2;
8031 + tx32 = (u32 *) drv->tx;
8033 + drv->tx_todo -= 4;
8040 + ltq_writel(&drv->regs->tb, data);
8045 +static void rx_fifo_read_full_duplex(struct ltq_spi_drv_data *drv)
8051 + unsigned int rx_fill = rx_fifo_level(drv);
8054 + data = ltq_readl(&drv->regs->rb);
8056 + switch (drv->bits_per_word) {
8064 + rx16 = (u16 *) drv->rx;
8066 + drv->rx_todo -= 2;
8070 + rx32 = (u32 *) drv->rx;
8072 + drv->rx_todo -= 4;
8083 +static void rx_fifo_read_half_duplex(struct ltq_spi_drv_data *drv)
8087 + unsigned int rxbv, shift;
8088 + unsigned int rx_fill = rx_fifo_level(drv);
8091 + * In RX-only mode the bits per word value is ignored by HW. A value
8092 + * of 32 is used instead. Thus all 4 bytes per FIFO must be read.
8093 + * If remaining RX bytes are less than 4, the FIFO must be read
8094 + * differently. The amount of received and valid bytes is indicated
8095 + * by STAT.RXBV register value.
8098 + if (drv->rx_todo < 4) {
8099 + rxbv = (ltq_readl(&drv->regs->stat) &
8100 + LTQ_SPI_STAT_RXBV_MASK) >>
8101 + LTQ_SPI_STAT_RXBV_SHIFT;
8102 + data = ltq_readl(&drv->regs->rb);
8104 + shift = (rxbv - 1) * 8;
8108 + *rx8++ = (data >> shift) & 0xFF;
8118 + data = ltq_readl(&drv->regs->rb);
8119 + rx32 = (u32 *) drv->rx;
8122 + drv->rx_todo -= 4;
8125 + if (drv->rx_req >= 4)
8132 +static void rx_request(struct ltq_spi_drv_data *drv)
8134 + unsigned int rxreq, rxreq_max;
8140 + * To avoid receive overflows at high clocks it is better to request
8141 + * only the amount of bytes that fits into all FIFOs. This value
8142 + * depends on the FIFO size implemented in hardware.
8144 + rxreq = drv->rx_todo;
8145 + rxreq_max = rx_fifo_size(drv) * 4;
8146 + if (rxreq > rxreq_max)
8147 + rxreq = rxreq_max;
8149 + drv->rx_req = rxreq;
8150 + ltq_writel(&drv->regs->rxreq, rxreq);
8153 +void spi_init(void)
8157 +struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
8158 + unsigned int max_hz, unsigned int mode)
8160 + struct ltq_spi_drv_data *drv;
8162 + if (!spi_cs_is_valid(bus, cs))
8165 + drv = ltq_spi_slave_alloc(bus, cs);
8169 + drv->regs = (struct ltq_spi_regs *) CKSEG1ADDR(LTQ_SPI_BASE);
8173 + drv->max_hz = max_hz;
8176 + return &drv->slave;
8179 +void spi_free_slave(struct spi_slave *slave)
8181 + ltq_spi_slave_free(slave);
8184 +static int ltq_spi_wait_ready(struct ltq_spi_drv_data *drv)
8186 + const unsigned long timeout = 20000;
8187 + unsigned long timebase;
8189 + timebase = get_timer(0);
8194 + if (!hw_is_busy(drv))
8196 + } while (get_timer(timebase) < timeout);
8201 +int spi_claim_bus(struct spi_slave *slave)
8203 + struct ltq_spi_drv_data *drv = to_ltq_spi_slave(slave);
8206 + ret = ltq_spi_wait_ready(drv);
8208 + debug("cannot claim bus\n");
8212 + hw_enter_config_mode(drv);
8213 + hw_setup_clock_mode(drv, drv->mode);
8214 + hw_setup_speed_hz(drv, drv->max_hz);
8215 + hw_setup_bits_per_word(drv, drv->bits_per_word);
8216 + hw_enter_active_mode(drv);
8221 +void spi_release_bus(struct spi_slave *slave)
8223 + struct ltq_spi_drv_data *drv = to_ltq_spi_slave(slave);
8225 + hw_enter_config_mode(drv);
8228 +int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
8229 + const void *dout, void *din, unsigned long flags)
8232 + struct ltq_spi_drv_data *drv = to_ltq_spi_slave(slave);
8243 + if (flags & SPI_XFER_BEGIN)
8244 + spi_cs_activate(slave);
8253 + drv->tx_todo = bitlen / 8;
8255 + tx_fifo_write(drv);
8259 + drv->rx_todo = bitlen / 8;
8267 + if (drv->rx && drv->rx_todo)
8268 + rx_fifo_read_full_duplex(drv);
8271 + tx_fifo_write(drv);
8274 + } else if (drv->rx) {
8275 + if (drv->rx_todo) {
8276 + rx_fifo_read_half_duplex(drv);
8289 + ret = ltq_spi_wait_ready(drv);
8295 + if (flags & SPI_XFER_END)
8296 + spi_cs_deactivate(slave);
8302 @@ -214,6 +214,7 @@ int phy_atheros_init(void);
8303 int phy_broadcom_init(void);
8304 int phy_davicom_init(void);
8305 int phy_et1011c_init(void);
8306 +int phy_lantiq_init(void);
8307 int phy_lxt_init(void);
8308 int phy_marvell_init(void);
8309 int phy_micrel_init(void);
8312 @@ -100,6 +100,8 @@ LIBS-$(CONFIG_SPL_USBETH_SUPPORT) += dri
8313 LIBS-$(CONFIG_SPL_MUSB_NEW_SUPPORT) += drivers/usb/musb-new/libusb_musb-new.o
8314 LIBS-$(CONFIG_SPL_USBETH_SUPPORT) += drivers/usb/gadget/libusb_gadget.o
8315 LIBS-$(CONFIG_SPL_WATCHDOG_SUPPORT) += drivers/watchdog/libwatchdog.o
8316 +LIBS-$(CONFIG_SPL_LZMA_SUPPORT) += lib/lzma/liblzma.o
8317 +LIBS-$(CONFIG_SPL_LZO_SUPPORT) += lib/lzo/liblzo.o
8319 ifneq ($(CONFIG_OMAP_COMMON),)
8320 LIBS-y += $(CPUDIR)/omap-common/libomap-common.o
8321 --- a/tools/.gitignore
8322 +++ b/tools/.gitignore
8331 --- a/tools/Makefile
8332 +++ b/tools/Makefile
8333 @@ -49,6 +49,7 @@ BIN_FILES-$(CONFIG_VIDEO_LOGO) += bmp_lo
8334 BIN_FILES-$(CONFIG_BUILD_ENVCRC) += envcrc$(SFX)
8335 BIN_FILES-$(CONFIG_CMD_NET) += gen_eth_addr$(SFX)
8336 BIN_FILES-$(CONFIG_CMD_LOADS) += img2srec$(SFX)
8337 +BIN_FILES-$(CONFIG_SOC_LANTIQ) += ltq-boot-image$(SFX)
8338 BIN_FILES-$(CONFIG_XWAY_SWAP_BYTES) += xway-swap-bytes$(SFX)
8339 BIN_FILES-y += mkenvimage$(SFX)
8340 BIN_FILES-y += mkimage$(SFX)
8341 @@ -95,6 +96,7 @@ OBJ_FILES-$(CONFIG_MX28) += mxsboot.o
8342 OBJ_FILES-$(CONFIG_NETCONSOLE) += ncb.o
8343 OBJ_FILES-$(CONFIG_SHA1_CHECK_UB_IMG) += ubsha1.o
8344 OBJ_FILES-$(CONFIG_SMDK5250) += mkexynosspl.o
8345 +OBJ_FILES-$(CONFIG_SOC_LANTIQ) += ltq-boot-image.o
8346 OBJ_FILES-$(CONFIG_VIDEO_LOGO) += bmp_logo.o
8347 OBJ_FILES-$(CONFIG_XWAY_SWAP_BYTES) += xway-swap-bytes.o
8349 @@ -195,6 +197,10 @@ $(obj)img2srec$(SFX): $(obj)img2srec.o
8350 $(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^
8353 +$(obj)ltq-boot-image$(SFX): $(obj)ltq-boot-image.o
8354 + $(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^
8357 $(obj)xway-swap-bytes$(SFX): $(obj)xway-swap-bytes.o
8358 $(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^
8361 +++ b/tools/ltq-boot-image.c
8364 + * Copyright (C) 2011-2013 Daniel Schwierzeck, daniel.schwierzeck@gmail.com
8366 + * SPDX-License-Identifier: GPL-2.0+
8370 +#include <stdlib.h>
8371 +#include <string.h>
8372 +#include <unistd.h>
8373 +#include <getopt.h>
8374 +#include <compiler.h>
8375 +#include <sys/stat.h>
8382 +/* Lantiq non-volatile bootstrap command IDs */
8384 + NVB_CMD_DEBUG = 0x11,
8385 + NVB_CMD_REGCFG = 0x22,
8386 + NVB_CMD_IDWNLD = 0x33,
8387 + NVB_CMD_CDWNLD = 0x44,
8388 + NVB_CMD_DWNLD = 0x55,
8389 + NVB_CMD_IFCFG = 0x66,
8390 + NVB_CMD_START = 0x77
8393 +/* Lantiq non-volatile bootstrap command flags */
8394 +enum nvb_cmd_flags {
8395 + NVB_FLAG_START = 1,
8396 + NVB_FLAG_DEC = (1 << 1),
8397 + NVB_FLAG_DBG = (1 << 2),
8398 + NVB_FLAG_SDBG = (1 << 3),
8399 + NVB_FLAG_CFG0 = (1 << 4),
8400 + NVB_FLAG_CFG1 = (1 << 5),
8401 + NVB_FLAG_CFG2 = (1 << 6),
8402 + NVB_FLAG_RST = (1 << 7)
8406 + enum image_types type;
8408 + const char *uboot_bin;
8409 + const char *spl_bin;
8410 + const char *out_bin;
8413 +static void usage_msg(const char *name)
8415 + fprintf(stderr, "%s: [-h] -t type -e entry-addr -u uboot-bin [-s spl-bin] -o out-bin\n",
8417 + fprintf(stderr, " Image types:\n"
8418 + " sfspl - SPL + [compressed] U-Boot for SPI flash\n");
8421 +static enum image_types parse_image_type(const char *type)
8424 + return IMAGE_NONE;
8426 + if (!strncmp(type, "sfspl", 6))
8427 + return IMAGE_SFSPL;
8429 + return IMAGE_NONE;
8432 +static int parse_args(int argc, char *argv[], struct args *arg)
8436 + memset(arg, 0, sizeof(*arg));
8438 + while ((opt = getopt(argc, argv, "ht:e:u:s:o:")) != -1) {
8441 + usage_msg(argv[0]);
8444 + arg->type = parse_image_type(optarg);
8447 + arg->entry_addr = strtoul(optarg, NULL, 16);
8450 + arg->uboot_bin = optarg;
8453 + arg->spl_bin = optarg;
8456 + arg->out_bin = optarg;
8459 + fprintf(stderr, "Invalid option -%c\n", opt);
8464 + if (arg->type == IMAGE_NONE) {
8465 + fprintf(stderr, "Invalid image type\n");
8469 + if (!arg->uboot_bin) {
8470 + fprintf(stderr, "Missing U-Boot binary\n");
8474 + if (!arg->out_bin) {
8475 + fprintf(stderr, "Missing output binary\n");
8479 + if (arg->type == IMAGE_SFSPL && !arg->spl_bin) {
8480 + fprintf(stderr, "Missing SPL binary\n");
8487 + usage_msg(argv[0]);
8491 +static __u32 build_nvb_command(unsigned cmdid, unsigned cmdflags)
8496 + tag = (cmdid << 8) | cmdflags;
8497 + cmd = (tag << 16) | (0xFFFF - tag);
8499 + return cpu_to_be32(cmd);
8502 +static int write_header(int fd, const void *hdr, size_t size)
8506 + n = write(fd, hdr, size);
8508 + fprintf(stderr, "Cannot write header: %s\n",
8516 +static int write_nvb_dwnld_header(int fd, size_t size, __u32 addr)
8520 + hdr[0] = build_nvb_command(NVB_CMD_DWNLD, NVB_FLAG_START |
8522 + hdr[1] = cpu_to_be32(size + 4);
8523 + hdr[2] = cpu_to_be32(addr);
8525 + return write_header(fd, hdr, sizeof(hdr));
8528 +static int write_nvb_start_header(int fd, __u32 addr)
8532 + hdr[0] = build_nvb_command(NVB_CMD_START, NVB_FLAG_SDBG);
8533 + hdr[1] = cpu_to_be32(4);
8534 + hdr[2] = cpu_to_be32(addr);
8536 + return write_header(fd, hdr, sizeof(hdr));
8539 +static int open_input_bin(const char *name, void **ptr, size_t *size)
8544 + fd = open(name, O_RDONLY | O_BINARY);
8546 + fprintf(stderr, "Cannot open %s: %s\n", name,
8551 + ret = fstat(fd, &sbuf);
8553 + fprintf(stderr, "Cannot fstat %s: %s\n", name,
8558 + *ptr = mmap(0, sbuf.st_size, PROT_READ, MAP_SHARED, fd, 0);
8559 + if (*ptr == MAP_FAILED) {
8560 + fprintf(stderr, "Cannot mmap %s: %s\n", name,
8565 + *size = sbuf.st_size;
8570 +static void close_input_bin(int fd, void *ptr, size_t size)
8572 + munmap(ptr, size);
8576 +static int copy_bin(int fd, void *ptr, size_t size)
8580 + n = write(fd, ptr, size);
8582 + fprintf(stderr, "Cannot copy binary: %s\n", strerror(errno));
8589 +static int open_output_bin(const char *name)
8593 + fd = open(name, O_RDWR | O_CREAT | O_TRUNC | O_BINARY, 0666);
8595 + fprintf(stderr, "Cannot open %s: %s\n", name,
8603 +static int create_sfspl(const struct args *arg)
8605 + int out_fd, uboot_fd, spl_fd, ret;
8606 + void *uboot_ptr, *spl_ptr;
8607 + size_t uboot_size, spl_size;
8609 + out_fd = open_output_bin(arg->out_bin);
8613 + spl_fd = open_input_bin(arg->spl_bin, &spl_ptr, &spl_size);
8617 + uboot_fd = open_input_bin(arg->uboot_bin, &uboot_ptr, &uboot_size);
8621 + ret = write_nvb_dwnld_header(out_fd, spl_size, arg->entry_addr);
8625 + ret = copy_bin(out_fd, spl_ptr, spl_size);
8629 + ret = write_nvb_start_header(out_fd, arg->entry_addr);
8633 + ret = copy_bin(out_fd, uboot_ptr, uboot_size);
8637 + close_input_bin(uboot_fd, uboot_ptr, uboot_size);
8638 + close_input_bin(spl_fd, spl_ptr, spl_size);
8644 + close_input_bin(uboot_fd, uboot_ptr, uboot_size);
8646 + close_input_bin(spl_fd, spl_ptr, spl_size);
8653 +int main(int argc, char *argv[])
8658 + ret = parse_args(argc, argv, &arg);
8662 + switch (arg.type) {
8664 + ret = create_sfspl(&arg);
8667 + fprintf(stderr, "Image type not implemented\n");
8674 + return EXIT_SUCCESS;
8676 + return EXIT_FAILURE;