aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile13
-rw-r--r--arch/mips/Kconfig64
-rw-r--r--arch/mips/cpu/start.S16
-rw-r--r--arch/mips/cpu/u-boot-spl.lds4
-rw-r--r--arch/mips/dts/Makefile2
-rw-r--r--arch/mips/dts/mediatek,mt7628-rfb.dts67
-rw-r--r--arch/mips/dts/mt7628-u-boot.dtsi38
-rw-r--r--arch/mips/dts/mt7628a.dtsi17
-rw-r--r--arch/mips/dts/vocore_vocore2.dts85
-rw-r--r--arch/mips/include/asm/global_data.h3
-rw-r--r--arch/mips/include/asm/u-boot-mips.h2
-rw-r--r--arch/mips/lib/Makefile1
-rw-r--r--arch/mips/lib/bootm.c3
-rw-r--r--arch/mips/lib/spl.c21
-rw-r--r--arch/mips/lib/traps.c19
-rw-r--r--arch/mips/mach-mtmips/Kconfig142
-rw-r--r--arch/mips/mach-mtmips/Makefile8
-rw-r--r--arch/mips/mach-mtmips/cpu.c58
-rw-r--r--arch/mips/mach-mtmips/ddr_cal.c205
-rw-r--r--arch/mips/mach-mtmips/ddr_calibrate.c309
-rw-r--r--arch/mips/mach-mtmips/ddr_init.c194
-rw-r--r--arch/mips/mach-mtmips/include/mach/ddr.h52
-rw-r--r--arch/mips/mach-mtmips/include/mach/mc.h180
-rw-r--r--arch/mips/mach-mtmips/include/mach/serial.h13
-rw-r--r--arch/mips/mach-mtmips/lowlevel_init.S328
-rw-r--r--arch/mips/mach-mtmips/mt7628/Makefile6
-rw-r--r--arch/mips/mach-mtmips/mt7628/ddr.c173
-rw-r--r--arch/mips/mach-mtmips/mt7628/init.c109
-rw-r--r--arch/mips/mach-mtmips/mt7628/lowlevel_init.S161
-rw-r--r--arch/mips/mach-mtmips/mt7628/mt7628.h104
-rw-r--r--arch/mips/mach-mtmips/mt7628/serial.c34
-rw-r--r--arch/mips/mach-mtmips/mt76xx.h32
-rw-r--r--arch/mips/mach-mtmips/spl.c44
-rw-r--r--board/gardena/smart-gateway-mt7688/board.c2
-rw-r--r--board/mediatek/mt7628/Kconfig12
-rw-r--r--board/mediatek/mt7628/MAINTAINERS7
-rw-r--r--board/mediatek/mt7628/Makefile3
-rw-r--r--board/mediatek/mt7628/board.c8
-rw-r--r--board/vocore/vocore2/Kconfig12
-rw-r--r--board/vocore/vocore2/MAINTAINERS7
-rw-r--r--board/vocore/vocore2/Makefile3
-rw-r--r--board/vocore/vocore2/board.c6
-rw-r--r--common/spl/Makefile1
-rw-r--r--common/spl/spl.c56
-rw-r--r--common/spl/spl_legacy.c131
-rw-r--r--common/spl/spl_nor.c27
-rw-r--r--configs/gardena-smart-gateway-mt7688-ram_defconfig74
-rw-r--r--configs/gardena-smart-gateway-mt7688_defconfig17
-rw-r--r--configs/linkit-smart-7688-ram_defconfig65
-rw-r--r--configs/linkit-smart-7688_defconfig17
-rw-r--r--configs/mt7628_rfb_defconfig47
-rw-r--r--configs/vocore2_defconfig101
-rw-r--r--drivers/mtd/nand/raw/brcmnand/brcmnand.c9
-rw-r--r--drivers/sysreset/Kconfig6
-rw-r--r--drivers/sysreset/Makefile1
-rw-r--r--drivers/sysreset/sysreset_resetctl.c48
-rw-r--r--include/configs/bmips_bcm6318.h2
-rw-r--r--include/configs/bmips_bcm63268.h2
-rw-r--r--include/configs/bmips_bcm6328.h2
-rw-r--r--include/configs/bmips_bcm6348.h2
-rw-r--r--include/configs/bmips_bcm6358.h2
-rw-r--r--include/configs/bmips_bcm6362.h2
-rw-r--r--include/configs/bmips_bcm6368.h2
-rw-r--r--include/configs/gardena-smart-gateway-mt7688.h21
-rw-r--r--include/configs/linkit-smart-7688.h22
-rw-r--r--include/configs/mt7628.h56
-rw-r--r--include/configs/vocore2.h54
-rw-r--r--include/spl.h13
-rw-r--r--lib/Kconfig5
-rw-r--r--lib/Makefile1
70 files changed, 2320 insertions, 1033 deletions
diff --git a/Makefile b/Makefile
index b8a4b5058a0..ea62374e74f 100644
--- a/Makefile
+++ b/Makefile
@@ -1002,6 +1002,9 @@ append = cat $(filter-out $< $(PHONY), $^) >> $@
quiet_cmd_pad_cat = CAT $@
cmd_pad_cat = $(cmd_objcopy) && $(append) || rm -f $@
+quiet_cmd_lzma = LZMA $@
+cmd_lzma = lzma -c -z -k -9 $< > $@
+
cfg: u-boot.cfg
quiet_cmd_cfgcheck = CFGCHK $2
@@ -1384,6 +1387,16 @@ else
UBOOT_BIN := u-boot.bin
endif
+MKIMAGEFLAGS_u-boot-lzma.img = -A $(ARCH) -T standalone -C lzma -O u-boot \
+ -a $(CONFIG_SYS_TEXT_BASE) -e $(CONFIG_SYS_UBOOT_START) \
+ -n "U-Boot $(UBOOTRELEASE) for $(BOARD) board"
+
+u-boot.bin.lzma: u-boot.bin FORCE
+ $(call if_changed,lzma)
+
+u-boot-lzma.img: u-boot.bin.lzma FORCE
+ $(call if_changed,mkimage)
+
u-boot-dtb.img u-boot.img u-boot.kwb u-boot.pbl u-boot-ivt.img: \
$(if $(CONFIG_SPL_LOAD_FIT),u-boot-nodtb.bin \
$(if $(CONFIG_OF_SEPARATE)$(CONFIG_OF_EMBED)$(CONFIG_OF_HOSTFILE),dts/dt.dtb) \
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index a3ae6030448..48e754cc46c 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -98,6 +98,7 @@ config ARCH_MTMIPS
select SUPPORTS_CPU_MIPS32_R2
select SUPPORTS_LITTLE_ENDIAN
select SYSRESET
+ select SUPPORT_SPL
config ARCH_JZ47XX
bool "Support Ingenic JZ47xx"
@@ -287,6 +288,60 @@ config MIPS_RELOCATION_TABLE_SIZE
If unsure, leave at the default value.
+config RESTORE_EXCEPTION_VECTOR_BASE
+ bool "Restore exception vector base before booting linux kernel"
+ default n
+ help
+ In U-Boot the exception vector base will be moved to top of memory,
+ to be used to display register dump when exception occurs.
+ But some old linux kernel does not honor the base set in CP0_EBASE.
+ A modified exception vector base will cause kernel crash.
+
+ This option will restore the exception vector base to its previous
+ value.
+
+ If unsure, say N.
+
+config OVERRIDE_EXCEPTION_VECTOR_BASE
+ bool "Override the exception vector base to be restored"
+ depends on RESTORE_EXCEPTION_VECTOR_BASE
+ default n
+ help
+ Enable this option if you want to use a different exception vector
+ base rather than the previously saved one.
+
+config NEW_EXCEPTION_VECTOR_BASE
+ hex "New exception vector base"
+ depends on OVERRIDE_EXCEPTION_VECTOR_BASE
+ range 0x80000000 0xbffff000
+ default 0x80000000
+ help
+ The exception vector base to be restored before booting linux kernel
+
+config INIT_STACK_WITHOUT_MALLOC_F
+ bool "Do not reserve malloc space on initial stack"
+ default n
+ help
+ Enable this option if you don't want to reserve malloc space on
+ initial stack. This is useful if the initial stack can't hold large
+ malloc space. Platform should set the malloc_base later when DRAM is
+ ready to use.
+
+config SPL_INIT_STACK_WITHOUT_MALLOC_F
+ bool "Do not reserve malloc space on initial stack in SPL"
+ default n
+ help
+ Enable this option if you don't want to reserve malloc space on
+ initial stack. This is useful if the initial stack can't hold large
+ malloc space. Platform should set the malloc_base later when DRAM is
+ ready to use.
+
+config SPL_LOADER_SUPPORT
+ bool
+ default n
+ help
+ Enable this option if you want to use SPL loaders without DM enabled.
+
endmenu
menu "OS boot interface"
@@ -389,6 +444,15 @@ config MIPS_INIT_STACK_IN_SRAM
lowlevel_init. Thus lowlevel_init does not need to be implemented
in assembler.
+config MIPS_SRAM_INIT
+ bool
+ default n
+ depends on MIPS_INIT_STACK_IN_SRAM
+ help
+ Select this if the SRAM for initial stack needs to be initialized
+ before it can be used. If enabled, a function mips_sram_init() will
+ be called just before setup_stack_gd.
+
config SYS_DCACHE_SIZE
int
default 0
diff --git a/arch/mips/cpu/start.S b/arch/mips/cpu/start.S
index 1d21b2324a7..6de9a2f3624 100644
--- a/arch/mips/cpu/start.S
+++ b/arch/mips/cpu/start.S
@@ -59,7 +59,8 @@
sp, sp, GD_SIZE # reserve space for gd
and sp, sp, t0 # force 16 byte alignment
move k0, sp # save gd pointer
-#if CONFIG_VAL(SYS_MALLOC_F_LEN)
+#if CONFIG_VAL(SYS_MALLOC_F_LEN) && \
+ !CONFIG_IS_ENABLED(INIT_STACK_WITHOUT_MALLOC_F)
li t2, CONFIG_VAL(SYS_MALLOC_F_LEN)
PTR_SUBU \
sp, sp, t2 # reserve space for early malloc
@@ -71,10 +72,12 @@
move t0, k0
1:
PTR_S zero, 0(t0)
+ PTR_ADDIU t0, PTRSIZE
blt t0, t1, 1b
- PTR_ADDIU t0, PTRSIZE
+ nop
-#if CONFIG_VAL(SYS_MALLOC_F_LEN)
+#if CONFIG_VAL(SYS_MALLOC_F_LEN) && \
+ !CONFIG_IS_ENABLED(INIT_STACK_WITHOUT_MALLOC_F)
PTR_S sp, GD_MALLOC_BASE(k0) # gd->malloc_base offset
#endif
.endm
@@ -216,6 +219,13 @@ wr_done:
#endif
#ifdef CONFIG_MIPS_INIT_STACK_IN_SRAM
+#ifdef CONFIG_MIPS_SRAM_INIT
+ /* Initialize the SRAM first */
+ PTR_LA t9, mips_sram_init
+ jalr t9
+ nop
+#endif
+
/* Set up initial stack and global data */
setup_stack_gd
diff --git a/arch/mips/cpu/u-boot-spl.lds b/arch/mips/cpu/u-boot-spl.lds
index d08d6222c4a..28ea4f2a481 100644
--- a/arch/mips/cpu/u-boot-spl.lds
+++ b/arch/mips/cpu/u-boot-spl.lds
@@ -27,7 +27,7 @@ SECTIONS
*(SORT_BY_ALIGNMENT(.sdata*))
} > .spl_mem
-#ifdef CONFIG_SPL_DM
+#if defined(CONFIG_SPL_DM) || defined(CONFIG_SPL_LOADER_SUPPORT)
. = ALIGN(4);
.u_boot_list : {
KEEP(*(SORT(.u_boot_list*)));
@@ -37,6 +37,8 @@ SECTIONS
. = ALIGN(4);
__image_copy_end = .;
+ _image_binary_end = .;
+
.bss (NOLOAD) : {
__bss_start = .;
*(.bss*)
diff --git a/arch/mips/dts/Makefile b/arch/mips/dts/Makefile
index c9d75596f25..f711e9fb59c 100644
--- a/arch/mips/dts/Makefile
+++ b/arch/mips/dts/Makefile
@@ -17,11 +17,13 @@ dtb-$(CONFIG_BOARD_COMTREND_CT5361) += comtrend,ct-5361.dtb
dtb-$(CONFIG_BOARD_COMTREND_VR3032U) += comtrend,vr-3032u.dtb
dtb-$(CONFIG_BOARD_COMTREND_WAP5813N) += comtrend,wap-5813n.dtb
dtb-$(CONFIG_BOARD_HUAWEI_HG556A) += huawei,hg556a.dtb
+dtb-$(CONFIG_BOARD_MT7628_RFB) += mediatek,mt7628-rfb.dtb
dtb-$(CONFIG_BOARD_NETGEAR_CG3100D) += netgear,cg3100d.dtb
dtb-$(CONFIG_BOARD_NETGEAR_DGND3700V2) += netgear,dgnd3700v2.dtb
dtb-$(CONFIG_BOARD_SAGEM_FAST1704) += sagem,f@st1704.dtb
dtb-$(CONFIG_BOARD_SFR_NB4_SER) += sfr,nb4-ser.dtb
dtb-$(CONFIG_BOARD_TPLINK_WDR4300) += tplink_wdr4300.dtb
+dtb-$(CONFIG_BOARD_VOCORE2) += vocore_vocore2.dtb
dtb-$(CONFIG_TARGET_JZ4780_CI20) += ci20.dtb
dtb-$(CONFIG_SOC_LUTON) += luton_pcb090.dtb luton_pcb091.dtb
dtb-$(CONFIG_SOC_OCELOT) += ocelot_pcb120.dtb ocelot_pcb123.dtb
diff --git a/arch/mips/dts/mediatek,mt7628-rfb.dts b/arch/mips/dts/mediatek,mt7628-rfb.dts
new file mode 100644
index 00000000000..6ff36daa6e7
--- /dev/null
+++ b/arch/mips/dts/mediatek,mt7628-rfb.dts
@@ -0,0 +1,67 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 MediaTek Inc.
+ *
+ * Author: Weijie Gao <weijie.gao@mediatek.com>
+ */
+
+/dts-v1/;
+
+#include "mt7628a.dtsi"
+
+/ {
+ compatible = "mediatek,mt7628-rfb", "ralink,mt7628a-soc";
+ model = "MediaTek MT7628 RFB";
+
+ aliases {
+ serial0 = &uart0;
+ spi0 = &spi0;
+ };
+
+ chosen {
+ stdout-path = &uart0;
+ };
+};
+
+&pinctrl {
+ state_default: pin_state {
+ pleds {
+ groups = "p0led", "p1led", "p2led", "p3led", "p4led";
+ function = "led";
+ };
+ };
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&spi0 {
+ status = "okay";
+ num-cs = <2>;
+
+ spi-flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "jedec,spi-nor";
+ spi-max-frequency = <25000000>;
+ reg = <0>;
+ };
+};
+
+&eth {
+ mediatek,wan-port = <0>;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&ephy_router_mode>;
+};
+
+&mmc {
+ bus-width = <4>;
+ cap-sd-highspeed;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&sd_router_mode>;
+
+ status = "okay";
+};
diff --git a/arch/mips/dts/mt7628-u-boot.dtsi b/arch/mips/dts/mt7628-u-boot.dtsi
new file mode 100644
index 00000000000..eea5dc64bf9
--- /dev/null
+++ b/arch/mips/dts/mt7628-u-boot.dtsi
@@ -0,0 +1,38 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 MediaTek Inc.
+ *
+ * Author: Weijie Gao <weijie.gao@mediatek.com>
+ */
+
+&palmbus {
+ u-boot,dm-pre-reloc;
+};
+
+&reboot {
+ u-boot,dm-pre-reloc;
+};
+
+&clkctrl {
+ u-boot,dm-pre-reloc;
+};
+
+&rstctrl {
+ u-boot,dm-pre-reloc;
+};
+
+&pinctrl {
+ u-boot,dm-pre-reloc;
+};
+
+&uart0 {
+ u-boot,dm-pre-reloc;
+};
+
+&uart1 {
+ u-boot,dm-pre-reloc;
+};
+
+&uart2 {
+ u-boot,dm-pre-reloc;
+};
diff --git a/arch/mips/dts/mt7628a.dtsi b/arch/mips/dts/mt7628a.dtsi
index 76a80c8952d..6baa63add33 100644
--- a/arch/mips/dts/mt7628a.dtsi
+++ b/arch/mips/dts/mt7628a.dtsi
@@ -33,7 +33,7 @@
#clock-cells = <0>;
};
- palmbus@10000000 {
+ palmbus: palmbus@10000000 {
compatible = "palmbus", "simple-bus";
reg = <0x10000000 0x200000>;
ranges = <0x0 0x10000000 0x1FFFFF>;
@@ -46,11 +46,11 @@
reg = <0x0 0x100>;
};
- syscon-reboot {
- compatible = "syscon-reboot";
- regmap = <&sysc>;
- offset = <0x34>;
- mask = <0x1>;
+ reboot: resetctl-reboot {
+ compatible = "resetctl-reboot";
+
+ resets = <&rstctrl MT7628_SYS_RST>;
+ reset-names = "sysreset";
};
clkctrl: clkctrl@0x2c {
@@ -110,6 +110,11 @@
function = "uart2";
};
+ uart2_pwm_pins: uart2_pwm_pins {
+ groups = "spis";
+ function = "pwm_uart2";
+ };
+
i2c_pins: i2c_pins {
groups = "i2c";
function = "i2c";
diff --git a/arch/mips/dts/vocore_vocore2.dts b/arch/mips/dts/vocore_vocore2.dts
new file mode 100644
index 00000000000..3502e4b8b79
--- /dev/null
+++ b/arch/mips/dts/vocore_vocore2.dts
@@ -0,0 +1,85 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2019 Mauro Condarelli <mc5686@mclink.it>
+ */
+
+/dts-v1/;
+
+#include "mt7628a.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+ compatible = "vocore,vocore2", "ralink,mt7628a-soc";
+ model = "VoCore2";
+
+ aliases {
+ serial0 = &uart2;
+ spi0 = &spi0;
+ };
+
+ memory@0 {
+ device_type = "memory";
+ reg = <0x0 0x08000000>;
+ };
+ leds {
+ compatible = "gpio-leds";
+
+ power {
+ label = "vocore:power";
+ gpios = <&gpio1 12 GPIO_ACTIVE_HIGH>;
+ default-state = "off";
+ };
+ };
+
+ chosen {
+ bootargs = "console=ttyS2,115200";
+ stdout-path = &uart2;
+ };
+};
+
+&pinctrl {
+ state_default: pin_state {
+ p0led {
+ groups = "p0led_a";
+ function = "led";
+ };
+ };
+};
+
+&uart2 {
+ status = "okay";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&uart2_pwm_pins>;
+};
+
+&spi0 {
+ status = "okay";
+ nor0: spi-flash@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "jedec,spi-nor";
+ spi-max-frequency = <25000000>;
+ reg = <0>;
+ };
+};
+
+&eth {
+ status = "okay";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&ephy_iot_mode>;
+ mediatek,poll-link-phy = <0>;
+};
+
+&mmc {
+ status = "okay";
+
+ bus-width = <4>;
+ max-frequency = <48000000>;
+ cap-sd-highspeed;
+ cap-mmc-highspeed;
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&sd_iot_mode>;
+};
diff --git a/arch/mips/include/asm/global_data.h b/arch/mips/include/asm/global_data.h
index 7b4ad083ba0..4c30fab8717 100644
--- a/arch/mips/include/asm/global_data.h
+++ b/arch/mips/include/asm/global_data.h
@@ -27,6 +27,9 @@ struct arch_global_data {
#ifdef CONFIG_MIPS_L2_CACHE
unsigned short l2_line_size;
#endif
+#ifdef CONFIG_ARCH_MTMIPS
+ unsigned long timer_freq;
+#endif
};
#include <asm-generic/global_data.h>
diff --git a/arch/mips/include/asm/u-boot-mips.h b/arch/mips/include/asm/u-boot-mips.h
index 88438b9576b..8b37cc4029c 100644
--- a/arch/mips/include/asm/u-boot-mips.h
+++ b/arch/mips/include/asm/u-boot-mips.h
@@ -9,4 +9,6 @@ void except_vec_ejtag_debug(void);
int arch_misc_init(void);
+void trap_restore(void);
+
#endif /* _U_BOOT_MIPS_H_ */
diff --git a/arch/mips/lib/Makefile b/arch/mips/lib/Makefile
index 24a72d9c973..9ee1fcb5c70 100644
--- a/arch/mips/lib/Makefile
+++ b/arch/mips/lib/Makefile
@@ -12,5 +12,6 @@ obj-y += traps.o
obj-$(CONFIG_CMD_BOOTM) += bootm.o
obj-$(CONFIG_CMD_GO) += boot.o
+obj-$(CONFIG_SPL_BUILD) += spl.o
lib-$(CONFIG_USE_PRIVATE_LIBGCC) += ashldi3.o ashrdi3.o lshrdi3.o
diff --git a/arch/mips/lib/bootm.c b/arch/mips/lib/bootm.c
index 8c0d7672f24..f1db6d23b84 100644
--- a/arch/mips/lib/bootm.c
+++ b/arch/mips/lib/bootm.c
@@ -294,6 +294,9 @@ static void boot_jump_linux(bootm_headers_t *images)
bootstage_report();
#endif
+ if (CONFIG_IS_ENABLED(RESTORE_EXCEPTION_VECTOR_BASE))
+ trap_restore();
+
if (images->ft_len)
kernel(-2, (ulong)images->ft_addr, 0, 0);
else
diff --git a/arch/mips/lib/spl.c b/arch/mips/lib/spl.c
new file mode 100644
index 00000000000..7ba3e53f6de
--- /dev/null
+++ b/arch/mips/lib/spl.c
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2020 Stefan Roese <sr@denx.de>
+ */
+
+#include <common.h>
+#include <cpu_func.h>
+#include <spl.h>
+
+void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image)
+{
+ typedef void __noreturn (*image_entry_noargs_t)(void);
+ image_entry_noargs_t image_entry =
+ (image_entry_noargs_t)spl_image->entry_point;
+
+ /* Flush cache before jumping to application */
+ flush_cache((unsigned long)spl_image->load_addr, spl_image->size);
+
+ debug("image entry point: 0x%lx\n", spl_image->entry_point);
+ image_entry();
+}
diff --git a/arch/mips/lib/traps.c b/arch/mips/lib/traps.c
index b8568c00fed..8fff7541e3c 100644
--- a/arch/mips/lib/traps.c
+++ b/arch/mips/lib/traps.c
@@ -20,6 +20,8 @@
DECLARE_GLOBAL_DATA_PTR;
+static unsigned long saved_ebase;
+
static void show_regs(const struct pt_regs *regs)
{
const int field = 2 * sizeof(unsigned long);
@@ -102,7 +104,24 @@ void trap_init(ulong reloc_addr)
set_handler(0x180, &except_vec3_generic, 0x80);
set_handler(0x280, &except_vec_ejtag_debug, 0x80);
+ saved_ebase = read_c0_ebase() & 0xfffff000;
+
write_c0_ebase(ebase);
clear_c0_status(ST0_BEV);
execution_hazard_barrier();
}
+
+void trap_restore(void)
+{
+ set_c0_status(ST0_BEV);
+ execution_hazard_barrier();
+
+#ifdef CONFIG_OVERRIDE_EXCEPTION_VECTOR_BASE
+ write_c0_ebase(CONFIG_NEW_EXCEPTION_VECTOR_BASE & 0xfffff000);
+#else
+ write_c0_ebase(saved_ebase);
+#endif
+
+ clear_c0_status(ST0_BEV);
+ execution_hazard_barrier();
+}
diff --git a/arch/mips/mach-mtmips/Kconfig b/arch/mips/mach-mtmips/Kconfig
index c8dcf19c0de..737de2cb8e2 100644
--- a/arch/mips/mach-mtmips/Kconfig
+++ b/arch/mips/mach-mtmips/Kconfig
@@ -7,14 +7,52 @@ config SYS_MALLOC_F_LEN
config SYS_SOC
default "mt7628" if SOC_MT7628
+config SYS_DCACHE_SIZE
+ default 32768
+
+config SYS_DCACHE_LINE_SIZE
+ default 32
+
+config SYS_ICACHE_SIZE
+ default 65536
+
+config SYS_ICACHE_LINE_SIZE
+ default 32
+
+config SYS_TEXT_BASE
+ default 0x9c000000 if !SPL
+ default 0x80200000 if SPL
+
+config SPL_TEXT_BASE
+ default 0x9c000000
+
+config SPL_PAYLOAD
+ default "u-boot-lzma.img" if SPL_LZMA
+
+config BUILD_TARGET
+ default "u-boot-with-spl.bin" if SPL
+
choice
prompt "MediaTek MIPS SoC select"
config SOC_MT7628
bool "MT7628"
select MIPS_L1_CACHE_SHIFT_5
+ select MIPS_INIT_STACK_IN_SRAM
+ select MIPS_SRAM_INIT
+ select SYS_MIPS_CACHE_INIT_RAM_LOAD
select PINCTRL_MT7628
select MTK_SERIAL
+ select SYSRESET_RESETCTL
+ select SPL_SEPARATE_BSS if SPL
+ select SPL_INIT_STACK_WITHOUT_MALLOC_F if SPL
+ select SPL_LOADER_SUPPORT if SPL
+ select SPL_OF_CONTROL if SPL_DM
+ select SPL_SIMPLE_BUS if SPL_DM
+ select SPL_DM_SERIAL if SPL_DM
+ select SPL_CLK if SPL_DM && SPL_SERIAL_SUPPORT
+ select SPL_SYSRESET if SPL_DM
+ select SPL_OF_LIBFDT if SPL_OF_CONTROL
help
This supports MediaTek MT7628/MT7688.
@@ -27,7 +65,6 @@ config BOARD_GARDENA_SMART_GATEWAY_MT7688
bool "GARDENA smart Gateway"
depends on SOC_MT7628
select BOARD_LATE_INIT
- select SUPPORTS_BOOT_RAM
help
GARDENA smart Gateway boards have a MT7688 SoC with 128 MiB of RAM
and 8 MiB of flash (SPI NOR) and additional SPI NAND storage.
@@ -35,7 +72,6 @@ config BOARD_GARDENA_SMART_GATEWAY_MT7688
config BOARD_LINKIT_SMART_7688
bool "LinkIt Smart 7688"
depends on SOC_MT7628
- select SUPPORTS_BOOT_RAM
help
Seeed LinkIt Smart 7688 boards have a MT7688 SoC with 128 MiB of RAM
and 32 MiB of flash (SPI).
@@ -43,96 +79,36 @@ config BOARD_LINKIT_SMART_7688
ethernet ports, 1 USB port, 1 UART, GPIO buttons and LEDs, and
a MT7688 (PCIe).
-endchoice
-
-choice
- prompt "Boot mode"
-
-config BOOT_RAM
- bool "RAM boot"
- depends on SUPPORTS_BOOT_RAM
- help
- This builds an image that is linked to a RAM address. It can be used
- for booting from CFE via TFTP using an ELF image, but it can also be
- booted from RAM by other bootloaders using a BIN image.
-
-config BOOT_ROM
- bool "ROM boot"
- depends on SUPPORTS_BOOT_RAM
- help
- This builds an image that is linked to a ROM address. It can be
- used as main bootloader image which is programmed onto the onboard
- flash storage (SPI NOR).
-
-endchoice
-
-choice
- prompt "DDR2 size"
-
-config ONBOARD_DDR2_SIZE_256MBIT
- bool "256MBit (32MByte) total size"
- depends on BOOT_ROM
- help
- Use 256MBit (32MByte) of DDR total size
-
-config ONBOARD_DDR2_SIZE_512MBIT
- bool "512MBit (64MByte) total size"
- depends on BOOT_ROM
- help
- Use 512MBit (64MByte) of DDR total size
-
-config ONBOARD_DDR2_SIZE_1024MBIT
- bool "1024MBit (128MByte) total size"
- depends on BOOT_ROM
- help
- Use 1024MBit (128MByte) of DDR total size
-
-config ONBOARD_DDR2_SIZE_2048MBIT
- bool "2048MBit (256MByte) total size"
- depends on BOOT_ROM
- help
- Use 2048MBit (256MByte) of DDR total size
-
-endchoice
-
-choice
- prompt "DDR2 chip width"
-
-config ONBOARD_DDR2_CHIP_WIDTH_8BIT
- bool "8bit DDR chip width"
- depends on BOOT_ROM
+config BOARD_MT7628_RFB
+ bool "MediaTek MT7628 RFB"
+ depends on SOC_MT7628
help
- Use DDR chips with 8bit width
+ The reference design of MT7628. The board has 128 MiB DDR2, 8 MiB
+ SPI-NOR flash, 1 built-in switch with 5 ports, 1 UART, 1 USB host,
+ 1 SDXC, 1 PCIe socket and JTAG pins.
-config ONBOARD_DDR2_CHIP_WIDTH_16BIT
- bool "16bit DDR chip width"
- depends on BOOT_ROM
+config BOARD_VOCORE2
+ bool "VoCore2"
+ depends on SOC_MT7628
+ select SPL_SERIAL_SUPPORT
+ select SPL_UART2_SPIS_PINMUX
help
- Use DDR chips with 16bit width
+ VoCore VoCore2 board has a MT7628 SoC with 128 MiB of RAM
+ and 16 MiB of flash (SPI).
endchoice
-choice
- prompt "DDR2 bus width"
-
-config ONBOARD_DDR2_BUS_WIDTH_16BIT
- bool "16bit DDR bus width"
- depends on BOOT_ROM
+config SPL_UART2_SPIS_PINMUX
+ bool "Use alternative pinmux for UART2 in SPL stage"
+ depends on SPL_SERIAL_SUPPORT
+ default n
help
- Use 16bit DDR bus width
-
-config ONBOARD_DDR2_BUS_WIDTH_32BIT
- bool "32bit DDR bus width"
- depends on BOOT_ROM
- help
- Use 32bit DDR bus width
-
-endchoice
-
-config SUPPORTS_BOOT_RAM
- bool
+ Select this if the UART2 of your board is connected to GPIO 16/17
+ (shared with SPIS) rather than the usual GPIO 20/21.
source "board/gardena/smart-gateway-mt7688/Kconfig"
+source "board/mediatek/mt7628/Kconfig"
source "board/seeed/linkit-smart-7688/Kconfig"
+source "board/vocore/vocore2/Kconfig"
endmenu
diff --git a/arch/mips/mach-mtmips/Makefile b/arch/mips/mach-mtmips/Makefile
index 1f3e65e8a55..a7e6a663047 100644
--- a/arch/mips/mach-mtmips/Makefile
+++ b/arch/mips/mach-mtmips/Makefile
@@ -1,8 +1,8 @@
# SPDX-License-Identifier: GPL-2.0+
obj-y += cpu.o
+obj-y += ddr_init.o
+obj-y += ddr_cal.o
+obj-$(CONFIG_SPL_BUILD) += spl.o
-ifndef CONFIG_SKIP_LOWLEVEL_INIT
-obj-y += ddr_calibrate.o
-obj-y += lowlevel_init.o
-endif
+obj-$(CONFIG_SOC_MT7628) += mt7628/
diff --git a/arch/mips/mach-mtmips/cpu.c b/arch/mips/mach-mtmips/cpu.c
index 8976ef57c70..459a9673ebe 100644
--- a/arch/mips/mach-mtmips/cpu.c
+++ b/arch/mips/mach-mtmips/cpu.c
@@ -4,69 +4,17 @@
*/
#include <common.h>
-#include <dm.h>
-#include <init.h>
#include <malloc.h>
-#include <ram.h>
-#include <wdt.h>
-#include <asm/io.h>
#include <linux/io.h>
#include <linux/sizes.h>
-#include "mt76xx.h"
-#define STR_LEN 6
-
-#ifdef CONFIG_BOOT_ROM
-int mach_cpu_init(void)
-{
- ddr_calibrate();
-
- return 0;
-}
-#endif
+DECLARE_GLOBAL_DATA_PTR;
int dram_init(void)
{
+#ifdef CONFIG_SKIP_LOWLEVEL_INIT
gd->ram_size = get_ram_size((void *)CONFIG_SYS_SDRAM_BASE, SZ_256M);
-
- return 0;
-}
-
-int print_cpuinfo(void)
-{
- static const char * const boot_str[] = { "PLL (3-Byte SPI Addr)",
- "PLL (4-Byte SPI Addr)",
- "XTAL (3-Byte SPI Addr)",
- "XTAL (4-Byte SPI Addr)" };
- const void *blob = gd->fdt_blob;
- void __iomem *sysc_base;
- char buf[STR_LEN + 1];
- fdt_addr_t base;
- fdt_size_t size;
- char *str;
- int node;
- u32 val;
-
- /* Get system controller base address */
- node = fdt_node_offset_by_compatible(blob, -1, "ralink,mt7620a-sysc");
- if (node < 0)
- return -FDT_ERR_NOTFOUND;
-
- base = fdtdec_get_addr_size_auto_noparent(blob, node, "reg",
- 0, &size, true);
- if (base == FDT_ADDR_T_NONE)
- return -EINVAL;
-
- sysc_base = ioremap_nocache(base, size);
-
- str = (char *)sysc_base + MT76XX_CHIPID_OFFS;
- snprintf(buf, STR_LEN + 1, "%s", str);
- val = readl(sysc_base + MT76XX_CHIP_REV_ID_OFFS);
- printf("CPU: %-*s Rev %ld.%ld - ", STR_LEN, buf,
- (val & GENMASK(11, 8)) >> 8, val & GENMASK(3, 0));
-
- val = (readl(sysc_base + MT76XX_SYSCFG0_OFFS) & GENMASK(3, 1)) >> 1;
- printf("Boot from %s\n", boot_str[val]);
+#endif
return 0;
}
diff --git a/arch/mips/mach-mtmips/ddr_cal.c b/arch/mips/mach-mtmips/ddr_cal.c
new file mode 100644
index 00000000000..71a53c3c9cb
--- /dev/null
+++ b/arch/mips/mach-mtmips/ddr_cal.c
@@ -0,0 +1,205 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 MediaTek Inc.
+ *
+ * Author: Weijie Gao <weijie.gao@mediatek.com>
+ */
+
+#include <common.h>
+#include <asm/addrspace.h>
+#include <asm/cacheops.h>
+#include <linux/bitops.h>
+#include <linux/io.h>
+#include <mach/mc.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define COARSE_MIN_START 6
+#define FINE_MIN_START 15
+#define COARSE_MAX_START 7
+#define FINE_MAX_START 0
+
+#define NUM_OF_CACHELINE 128
+#define TEST_PAT_SIZE (NUM_OF_CACHELINE * CONFIG_SYS_CACHELINE_SIZE)
+
+#define INIT_DQS_VAL ((7 << DQS1_DELAY_COARSE_TUNING_S) | \
+ (4 << DQS1_DELAY_FINE_TUNING_S) | \
+ (7 << DQS0_DELAY_COARSE_TUNING_S) | \
+ (4 << DQS0_DELAY_FINE_TUNING_S))
+
+static inline void pref_op(int op, const volatile void *addr)
+{
+ __asm__ __volatile__("pref %0, 0(%1)" : : "i" (op), "r" (addr));
+}
+
+static inline bool dqs_test_error(void __iomem *memc, u32 memsize, u32 dqsval,
+ u32 bias)
+{
+ u32 *nca, *ca;
+ u32 off;
+ int i;
+
+ for (off = 0; off < memsize - TEST_PAT_SIZE; off += (memsize >> 6)) {
+ nca = (u32 *)KSEG1ADDR(off);
+ ca = (u32 *)KSEG0ADDR(off);
+
+ writel(INIT_DQS_VAL, memc + MEMCTL_DDR_DQS_DLY_REG);
+ wmb();
+
+ for (i = 0; i < TEST_PAT_SIZE / sizeof(u32); i++)
+ ca[i] = 0x1f1f1f1f;
+
+ for (i = 0; i < TEST_PAT_SIZE / sizeof(u32); i++)
+ nca[i] = (u32)nca + i + bias;
+
+ writel(dqsval, memc + MEMCTL_DDR_DQS_DLY_REG);
+ wmb();
+
+ for (i = 0; i < TEST_PAT_SIZE; i += CONFIG_SYS_CACHELINE_SIZE)
+ mips_cache(HIT_INVALIDATE_D, (u8 *)ca + i);
+ wmb();
+
+ for (i = 0; i < TEST_PAT_SIZE; i += CONFIG_SYS_CACHELINE_SIZE)
+ pref_op(0, (u8 *)ca + i);
+
+ for (i = 0; i < TEST_PAT_SIZE / sizeof(u32); i++) {
+ if (ca[i] != (u32)nca + i + bias)
+ return true;
+ }
+ }
+
+ return false;
+}
+
+static inline int dqs_find_max(void __iomem *memc, u32 memsize, int initval,
+ int maxval, int shift, u32 regval)
+{
+ int fieldval;
+ u32 dqsval;
+
+ for (fieldval = initval; fieldval <= maxval; fieldval++) {
+ dqsval = regval | (fieldval << shift);
+ if (dqs_test_error(memc, memsize, dqsval, 3))
+ return max(fieldval - 1, initval);
+ }
+
+ return maxval;
+}
+
+static inline int dqs_find_min(void __iomem *memc, u32 memsize, int initval,
+ int minval, int shift, u32 regval)
+{
+ int fieldval;
+ u32 dqsval;
+
+ for (fieldval = initval; fieldval >= minval; fieldval--) {
+ dqsval = regval | (fieldval << shift);
+ if (dqs_test_error(memc, memsize, dqsval, 1))
+ return min(fieldval + 1, initval);
+ }
+
+ return minval;
+}
+
+void ddr_calibrate(void __iomem *memc, u32 memsize, u32 bw)
+{
+ u32 dqs_coarse_min, dqs_coarse_max, dqs_coarse_val;
+ u32 dqs_fine_min, dqs_fine_max, dqs_fine_val;
+ u32 dqs_coarse_min_limit, dqs_fine_min_limit;
+ u32 dlls, dqs_dll, ddr_cfg2_reg;
+ u32 dqs_dly_tmp, dqs_dly, test_dqs, shift;
+ u32 rem, mask;
+ int i;
+
+ /* Disable Self-refresh */
+ clrbits_32(memc + MEMCTL_DDR_SELF_REFRESH_REG, SR_AUTO_EN);
+
+ /* Save DDR_CFG2 and modify its DQS gating window */
+ ddr_cfg2_reg = readl(memc + MEMCTL_DDR_CFG2_REG);
+ mask = DQS0_GATING_WINDOW_M;
+ if (bw == IND_SDRAM_WIDTH_16BIT)
+ mask |= DQS1_GATING_WINDOW_M;
+ clrbits_32(memc + MEMCTL_DDR_CFG2_REG, mask);
+
+ /* Get minimum available DQS value */
+ dlls = readl(memc + MEMCTL_DLL_DBG_REG);
+ dlls = (dlls & MST_DLY_SEL_M) >> MST_DLY_SEL_S;
+
+ dqs_dll = dlls >> 4;
+ if (dqs_dll <= 8)
+ dqs_coarse_min_limit = 8 - dqs_dll;
+ else
+ dqs_coarse_min_limit = 0;
+
+ dqs_dll = dlls & 0xf;
+ if (dqs_dll <= 8)
+ dqs_fine_min_limit = 8 - dqs_dll;
+ else
+ dqs_fine_min_limit = 0;
+
+ /* Initial DQS register value */
+ dqs_dly = INIT_DQS_VAL;
+
+ /* Calibrate DQS0 and/or DQS1 */
+ for (i = 0; i < bw; i++) {
+ shift = i * 8;
+ dqs_dly &= ~(0xff << shift);
+
+ /* Find maximum DQS coarse-grain */
+ dqs_dly_tmp = dqs_dly | (0xf << shift);
+ dqs_coarse_max = dqs_find_max(memc, memsize, COARSE_MAX_START,
+ 0xf, 4 + shift, dqs_dly_tmp);
+
+ /* Find maximum DQS fine-grain */
+ dqs_dly_tmp = dqs_dly | (dqs_coarse_max << (4 + shift));
+ test_dqs = dqs_find_max(memc, memsize, FINE_MAX_START, 0xf,
+ shift, dqs_dly_tmp);
+
+ if (test_dqs == FINE_MAX_START) {
+ dqs_coarse_max--;
+ dqs_fine_max = 0xf;
+ } else {
+ dqs_fine_max = test_dqs - 1;
+ }
+
+ /* Find minimum DQS coarse-grain */
+ dqs_dly_tmp = dqs_dly;
+ dqs_coarse_min = dqs_find_min(memc, memsize, COARSE_MIN_START,
+ dqs_coarse_min_limit, 4 + shift,
+ dqs_dly_tmp);
+
+ /* Find minimum DQS fine-grain */
+ dqs_dly_tmp = dqs_dly | (dqs_coarse_min << (4 + shift));
+ test_dqs = dqs_find_min(memc, memsize, FINE_MIN_START,
+ dqs_fine_min_limit, shift, dqs_dly_tmp);
+
+ if (test_dqs == FINE_MIN_START + 1) {
+ dqs_coarse_min++;
+ dqs_fine_min = 0;
+ } else {
+ dqs_fine_min = test_dqs;
+ }
+
+ /* Calculate central DQS coarse/fine value */
+ dqs_coarse_val = (dqs_coarse_max + dqs_coarse_min) >> 1;
+ rem = (dqs_coarse_max + dqs_coarse_min) % 2;
+
+ dqs_fine_val = (rem * 4) + ((dqs_fine_max + dqs_fine_min) >> 1);
+ if (dqs_fine_val >= 0x10) {
+ dqs_coarse_val++;
+ dqs_fine_val -= 8;
+ }
+
+ /* Save current DQS value */
+ dqs_dly |= ((dqs_coarse_val << 4) | dqs_fine_val) << shift;
+ }
+
+ /* Set final DQS value */
+ writel(dqs_dly, memc + MEMCTL_DDR_DQS_DLY_REG);
+
+ /* Restore DDR_CFG2 */
+ writel(ddr_cfg2_reg, memc + MEMCTL_DDR_CFG2_REG);
+
+ /* Enable Self-refresh */
+ setbits_32(memc + MEMCTL_DDR_SELF_REFRESH_REG, SR_AUTO_EN);
+}
diff --git a/arch/mips/mach-mtmips/ddr_calibrate.c b/arch/mips/mach-mtmips/ddr_calibrate.c
deleted file mode 100644
index 3cd440804d0..00000000000
--- a/arch/mips/mach-mtmips/ddr_calibrate.c
+++ /dev/null
@@ -1,309 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Copyright (C) 2018 Stefan Roese <sr@denx.de>
- *
- * This code is mostly based on the code extracted from this MediaTek
- * github repository:
- *
- * https://github.com/MediaTek-Labs/linkit-smart-uboot.git
- *
- * I was not able to find a specific license or other developers
- * copyrights here, so I can't add them here.
- *
- * Most functions in this file are copied from the MediaTek U-Boot
- * repository. Without any documentation, it was impossible to really
- * implement this differently. So its mostly a cleaned-up version of
- * the original code, with only support for the MT7628 / MT7688 SoC.
- */
-
-#include <common.h>
-#include <cpu_func.h>
-#include <linux/io.h>
-#include <asm/cacheops.h>
-#include <asm/io.h>
-#include "mt76xx.h"
-
-#define NUM_OF_CACHELINE 128
-#define MIN_START 6
-#define MIN_FINE_START 0xf
-#define MAX_START 7
-#define MAX_FINE_START 0x0
-
-#define CPU_FRAC_DIV 1
-
-#if defined(CONFIG_ONBOARD_DDR2_SIZE_256MBIT)
-#define DRAM_BUTTOM 0x02000000
-#endif
-#if defined(CONFIG_ONBOARD_DDR2_SIZE_512MBIT)
-#define DRAM_BUTTOM 0x04000000
-#endif
-#if defined(CONFIG_ONBOARD_DDR2_SIZE_1024MBIT)
-#define DRAM_BUTTOM 0x08000000
-#endif
-#if defined(CONFIG_ONBOARD_DDR2_SIZE_2048MBIT)
-#define DRAM_BUTTOM 0x10000000
-#endif
-
-static inline void cal_memcpy(void *src, void *dst, u32 size)
-{
- u8 *psrc = (u8 *)src;
- u8 *pdst = (u8 *)dst;
- int i;
-
- for (i = 0; i < size; i++, psrc++, pdst++)
- *pdst = *psrc;
-}
-
-static inline void cal_memset(void *src, u8 pat, u32 size)
-{
- u8 *psrc = (u8 *)src;
- int i;
-
- for (i = 0; i < size; i++, psrc++)
- *psrc = pat;
-}
-
-#define pref_op(hint, addr) \
- __asm__ __volatile__( \
- ".set push\n" \
- ".set noreorder\n" \
- "pref %0, %1\n" \
- ".set pop\n" \
- : \
- : "i" (hint), "R" (*(u8 *)(addr)))
-
-static inline void cal_patgen(u32 start_addr, u32 size, u32 bias)
-{
- u32 *addr = (u32 *)start_addr;
- int i;
-
- for (i = 0; i < size; i++)
- addr[i] = start_addr + i + bias;
-}
-
-static inline int test_loop(int k, int dqs, u32 test_dqs, u32 *coarse_dqs,
- u32 offs, u32 pat, u32 val)
-{
- u32 nc_addr;
- u32 *c_addr;
- int i;
-
- for (nc_addr = 0xa0000000;
- nc_addr < (0xa0000000 + DRAM_BUTTOM - NUM_OF_CACHELINE * 32);
- nc_addr += (DRAM_BUTTOM >> 6) + offs) {
- writel(0x00007474, (void *)MT76XX_MEMCTRL_BASE + 0x64);
- wmb(); /* Make sure store if finished */
-
- c_addr = (u32 *)(nc_addr & 0xdfffffff);
- cal_memset(((u8 *)c_addr), 0x1F, NUM_OF_CACHELINE * 32);
- cal_patgen(nc_addr, NUM_OF_CACHELINE * 8, pat);
-
- if (dqs > 0)
- writel(0x00000074 |
- (((k == 1) ? coarse_dqs[dqs] : test_dqs) << 12) |
- (((k == 0) ? val : test_dqs) << 8),
- (void *)MT76XX_MEMCTRL_BASE + 0x64);
- else
- writel(0x00007400 |
- (((k == 1) ? coarse_dqs[dqs] : test_dqs) << 4) |
- (((k == 0) ? val : test_dqs) << 0),
- (void *)MT76XX_MEMCTRL_BASE + 0x64);
- wmb(); /* Make sure store if finished */
-
- invalidate_dcache_range((u32)c_addr,
- (u32)c_addr +
- NUM_OF_CACHELINE * 32);
- wmb(); /* Make sure store if finished */
-
- for (i = 0; i < NUM_OF_CACHELINE * 8; i++) {
- if (i % 8 == 0)
- pref_op(0, &c_addr[i]);
- }
-
- for (i = 0; i < NUM_OF_CACHELINE * 8; i++) {
- if (c_addr[i] != nc_addr + i + pat)
- return -1;
- }
- }
-
- return 0;
-}
-
-void ddr_calibrate(void)
-{
- u32 min_coarse_dqs[2];
- u32 max_coarse_dqs[2];
- u32 min_fine_dqs[2];
- u32 max_fine_dqs[2];
- u32 coarse_dqs[2];
- u32 fine_dqs[2];
- int reg = 0, ddr_cfg2_reg;
- int flag;
- int i, k;
- int dqs = 0;
- u32 min_coarse_dqs_bnd, min_fine_dqs_bnd, coarse_dqs_dll, fine_dqs_dll;
- u32 val;
- u32 fdiv = 0, frac = 0;
-
- /* Setup clock to run at full speed */
- val = readl((void *)MT76XX_DYN_CFG0_REG);
- fdiv = (u32)((val >> 8) & 0x0F);
- if (CPU_FRAC_DIV < 1 || CPU_FRAC_DIV > 10)
- frac = val & 0x0f;
- else
- frac = CPU_FRAC_DIV;
-
- while (frac < fdiv) {
- val = readl((void *)MT76XX_DYN_CFG0_REG);
- fdiv = (val >> 8) & 0x0f;
- fdiv--;
- val &= ~(0x0f << 8);
- val |= (fdiv << 8);
- writel(val, (void *)MT76XX_DYN_CFG0_REG);
- udelay(500);
- val = readl((void *)MT76XX_DYN_CFG0_REG);
- fdiv = (val >> 8) & 0x0f;
- }
-
- clrbits_le32((void *)MT76XX_MEMCTRL_BASE + 0x10, BIT(4));
- ddr_cfg2_reg = readl((void *)MT76XX_MEMCTRL_BASE + 0x48);
- clrbits_le32((void *)MT76XX_MEMCTRL_BASE + 0x48,
- (0x3 << 28) | (0x3 << 26));
-
- min_coarse_dqs[0] = MIN_START;
- min_coarse_dqs[1] = MIN_START;
- min_fine_dqs[0] = MIN_FINE_START;
- min_fine_dqs[1] = MIN_FINE_START;
- max_coarse_dqs[0] = MAX_START;
- max_coarse_dqs[1] = MAX_START;
- max_fine_dqs[0] = MAX_FINE_START;
- max_fine_dqs[1] = MAX_FINE_START;
- dqs = 0;
-
- /* Add by KP, DQS MIN boundary */
- reg = readl((void *)MT76XX_MEMCTRL_BASE + 0x20);
- coarse_dqs_dll = (reg & 0xf00) >> 8;
- fine_dqs_dll = (reg & 0xf0) >> 4;
- if (coarse_dqs_dll <= 8)
- min_coarse_dqs_bnd = 8 - coarse_dqs_dll;
- else
- min_coarse_dqs_bnd = 0;
-
- if (fine_dqs_dll <= 8)
- min_fine_dqs_bnd = 8 - fine_dqs_dll;
- else
- min_fine_dqs_bnd = 0;
- /* DQS MIN boundary */
-
-DQS_CAL:
-
- for (k = 0; k < 2; k++) {
- u32 test_dqs;
-
- if (k == 0)
- test_dqs = MAX_START;
- else
- test_dqs = MAX_FINE_START;
-
- do {
- flag = test_loop(k, dqs, test_dqs, max_coarse_dqs,
- 0x400, 0x3, 0xf);
- if (flag == -1)
- break;
-
- test_dqs++;
- } while (test_dqs <= 0xf);
-
- if (k == 0) {
- max_coarse_dqs[dqs] = test_dqs;
- } else {
- test_dqs--;
-
- if (test_dqs == MAX_FINE_START - 1) {
- max_coarse_dqs[dqs]--;
- max_fine_dqs[dqs] = 0xf;
- } else {
- max_fine_dqs[dqs] = test_dqs;
- }
- }
- }
-
- for (k = 0; k < 2; k++) {
- u32 test_dqs;
-
- if (k == 0)
- test_dqs = MIN_START;
- else
- test_dqs = MIN_FINE_START;
-
- do {
- flag = test_loop(k, dqs, test_dqs, min_coarse_dqs,
- 0x480, 0x1, 0x0);
- if (k == 0) {
- if (flag == -1 ||
- test_dqs == min_coarse_dqs_bnd)
- break;
-
- test_dqs--;
-
- if (test_dqs < min_coarse_dqs_bnd)
- break;
- } else {
- if (flag == -1) {
- test_dqs++;
- break;
- } else if (test_dqs == min_fine_dqs_bnd) {
- break;
- }
-
- test_dqs--;
-
- if (test_dqs < min_fine_dqs_bnd)
- break;
- }
- } while (test_dqs >= 0);
-
- if (k == 0) {
- min_coarse_dqs[dqs] = test_dqs;
- } else {
- if (test_dqs == MIN_FINE_START + 1) {
- min_coarse_dqs[dqs]++;
- min_fine_dqs[dqs] = 0x0;
- } else {
- min_fine_dqs[dqs] = test_dqs;
- }
- }
- }
-
- if (dqs == 0) {
- dqs = 1;
- goto DQS_CAL;
- }
-
- for (i = 0; i < 2; i++) {
- u32 temp;
-
- coarse_dqs[i] = (max_coarse_dqs[i] + min_coarse_dqs[i]) >> 1;
- temp =
- (((max_coarse_dqs[i] + min_coarse_dqs[i]) % 2) * 4) +
- ((max_fine_dqs[i] + min_fine_dqs[i]) >> 1);
- if (temp >= 0x10) {
- coarse_dqs[i]++;
- fine_dqs[i] = (temp - 0x10) + 0x8;
- } else {
- fine_dqs[i] = temp;
- }
- }
- reg = (coarse_dqs[1] << 12) | (fine_dqs[1] << 8) |
- (coarse_dqs[0] << 4) | fine_dqs[0];
-
- clrbits_le32((void *)MT76XX_MEMCTRL_BASE + 0x10, BIT(4));
- writel(reg, (void *)MT76XX_MEMCTRL_BASE + 0x64);
- writel(ddr_cfg2_reg, (void *)MT76XX_MEMCTRL_BASE + 0x48);
- setbits_le32((void *)MT76XX_MEMCTRL_BASE + 0x10, BIT(4));
-
- for (i = 0; i < 2; i++)
- debug("[%02X%02X%02X%02X]", min_coarse_dqs[i],
- min_fine_dqs[i], max_coarse_dqs[i], max_fine_dqs[i]);
- debug("\nDDR Calibration DQS reg = %08X\n", reg);
-}
diff --git a/arch/mips/mach-mtmips/ddr_init.c b/arch/mips/mach-mtmips/ddr_init.c
new file mode 100644
index 00000000000..cd355cc8409
--- /dev/null
+++ b/arch/mips/mach-mtmips/ddr_init.c
@@ -0,0 +1,194 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 MediaTek Inc.
+ *
+ * Author: Weijie Gao <weijie.gao@mediatek.com>
+ */
+
+#include <common.h>
+#include <linux/bitops.h>
+#include <linux/io.h>
+#include <linux/sizes.h>
+#include <mach/ddr.h>
+#include <mach/mc.h>
+
+#define DDR_BW_TEST_PAT 0xaa5555aa
+
+static const u32 dram_size[] = {
+ [DRAM_8MB] = SZ_8M,
+ [DRAM_16MB] = SZ_16M,
+ [DRAM_32MB] = SZ_32M,
+ [DRAM_64MB] = SZ_64M,
+ [DRAM_128MB] = SZ_128M,
+ [DRAM_256MB] = SZ_256M,
+};
+
+static void dram_test_write(u32 addr, u32 val)
+{
+ volatile ulong *target = (volatile ulong *)(KSEG1 + addr);
+
+ sync();
+ *target = val;
+ sync();
+}
+
+static u32 dram_test_read(u32 addr)
+{
+ volatile ulong *target = (volatile ulong *)(KSEG1 + addr);
+ u32 val;
+
+ sync();
+ val = *target;
+ sync();
+
+ return val;
+}
+
+static int dram_addr_test_bit(u32 bit)
+{
+ u32 val;
+
+ dram_test_write(0, 0);
+ dram_test_write(BIT(bit), DDR_BW_TEST_PAT);
+ val = dram_test_read(0);
+
+ if (val == DDR_BW_TEST_PAT)
+ return 1;
+
+ return 0;
+}
+
+static void mc_ddr_init(void __iomem *memc, const struct mc_ddr_cfg *cfg,
+ u32 dq_dly, u32 dqs_dly, mc_reset_t mc_reset, u32 bw)
+{
+ u32 val;
+
+ mc_reset(1);
+ __udelay(200);
+ mc_reset(0);
+
+ clrbits_32(memc + MEMCTL_SDRAM_CFG1_REG, RBC_MAPPING);
+
+ writel(cfg->cfg2, memc + MEMCTL_DDR_CFG2_REG);
+ writel(cfg->cfg3, memc + MEMCTL_DDR_CFG3_REG);
+ writel(cfg->cfg4, memc + MEMCTL_DDR_CFG4_REG);
+ writel(dq_dly, memc + MEMCTL_DDR_DQ_DLY_REG);
+ writel(dqs_dly, memc + MEMCTL_DDR_DQS_DLY_REG);
+
+ writel(cfg->cfg0, memc + MEMCTL_DDR_CFG0_REG);
+
+ val = cfg->cfg1;
+ if (bw) {
+ val &= ~IND_SDRAM_WIDTH_M;
+ val |= (bw << IND_SDRAM_WIDTH_S) & IND_SDRAM_WIDTH_M;
+ }
+
+ writel(val, memc + MEMCTL_DDR_CFG1_REG);
+
+ clrsetbits_32(memc + MEMCTL_PWR_SAVE_CNT_REG, SR_TAR_CNT_M,
+ 1 << SR_TAR_CNT_S);
+
+ setbits_32(memc + MEMCTL_DDR_SELF_REFRESH_REG, SR_AUTO_EN);
+}
+
+void ddr1_init(struct mc_ddr_init_param *param)
+{
+ enum mc_dram_size sz;
+ u32 bw = 0;
+
+ /* First initialization, determine bus width */
+ mc_ddr_init(param->memc, &param->cfgs[DRAM_8MB], param->dq_dly,
+ param->dqs_dly, param->mc_reset, IND_SDRAM_WIDTH_16BIT);
+
+ /* Test bus width */
+ dram_test_write(0, DDR_BW_TEST_PAT);
+ if (dram_test_read(0) == DDR_BW_TEST_PAT)
+ bw = IND_SDRAM_WIDTH_16BIT;
+ else
+ bw = IND_SDRAM_WIDTH_8BIT;
+
+ /* Second initialization, determine DDR capacity */
+ mc_ddr_init(param->memc, &param->cfgs[DRAM_128MB], param->dq_dly,
+ param->dqs_dly, param->mc_reset, bw);
+
+ if (dram_addr_test_bit(9)) {
+ sz = DRAM_8MB;
+ } else {
+ if (dram_addr_test_bit(10)) {
+ if (dram_addr_test_bit(23))
+ sz = DRAM_16MB;
+ else
+ sz = DRAM_32MB;
+ } else {
+ if (dram_addr_test_bit(24))
+ sz = DRAM_64MB;
+ else
+ sz = DRAM_128MB;
+ }
+ }
+
+ /* Final initialization, with DDR calibration */
+ mc_ddr_init(param->memc, &param->cfgs[sz], param->dq_dly,
+ param->dqs_dly, param->mc_reset, bw);
+
+ /* Return actual DDR configuration */
+ param->memsize = dram_size[sz];
+ param->bus_width = bw;
+}
+
+void ddr2_init(struct mc_ddr_init_param *param)
+{
+ enum mc_dram_size sz;
+ u32 bw = 0;
+
+ /* First initialization, determine bus width */
+ mc_ddr_init(param->memc, &param->cfgs[DRAM_32MB], param->dq_dly,
+ param->dqs_dly, param->mc_reset, IND_SDRAM_WIDTH_16BIT);
+
+ /* Test bus width */
+ dram_test_write(0, DDR_BW_TEST_PAT);
+ if (dram_test_read(0) == DDR_BW_TEST_PAT)
+ bw = IND_SDRAM_WIDTH_16BIT;
+ else
+ bw = IND_SDRAM_WIDTH_8BIT;
+
+ /* Second initialization, determine DDR capacity */
+ mc_ddr_init(param->memc, &param->cfgs[DRAM_256MB], param->dq_dly,
+ param->dqs_dly, param->mc_reset, bw);
+
+ if (bw == IND_SDRAM_WIDTH_16BIT) {
+ if (dram_addr_test_bit(10)) {
+ sz = DRAM_32MB;
+ } else {
+ if (dram_addr_test_bit(24)) {
+ if (dram_addr_test_bit(27))
+ sz = DRAM_64MB;
+ else
+ sz = DRAM_128MB;
+ } else {
+ sz = DRAM_256MB;
+ }
+ }
+ } else {
+ if (dram_addr_test_bit(23)) {
+ sz = DRAM_32MB;
+ } else {
+ if (dram_addr_test_bit(24)) {
+ if (dram_addr_test_bit(27))
+ sz = DRAM_64MB;
+ else
+ sz = DRAM_128MB;
+ } else {
+ sz = DRAM_256MB;
+ }
+ }
+ }
+
+ /* Final initialization, with DDR calibration */
+ mc_ddr_init(param->memc, &param->cfgs[sz], param->dq_dly,
+ param->dqs_dly, param->mc_reset, bw);
+
+ /* Return actual DDR configuration */
+ param->memsize = dram_size[sz];
+ param->bus_width = bw;
+}
diff --git a/arch/mips/mach-mtmips/include/mach/ddr.h b/arch/mips/mach-mtmips/include/mach/ddr.h
new file mode 100644
index 00000000000..f92198137b1
--- /dev/null
+++ b/arch/mips/mach-mtmips/include/mach/ddr.h
@@ -0,0 +1,52 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2020 MediaTek Inc.
+ *
+ * Author: Weijie Gao <weijie.gao@mediatek.com>
+ */
+
+#ifndef _MTMIPS_DDR_H_
+#define _MTMIPS_DDR_H_
+
+#include <linux/io.h>
+#include <linux/types.h>
+
+enum mc_dram_size {
+ DRAM_8MB,
+ DRAM_16MB,
+ DRAM_32MB,
+ DRAM_64MB,
+ DRAM_128MB,
+ DRAM_256MB,
+
+ __DRAM_SZ_MAX
+};
+
+struct mc_ddr_cfg {
+ u32 cfg0;
+ u32 cfg1;
+ u32 cfg2;
+ u32 cfg3;
+ u32 cfg4;
+};
+
+typedef void (*mc_reset_t)(int assert);
+
+struct mc_ddr_init_param {
+ void __iomem *memc;
+
+ u32 dq_dly;
+ u32 dqs_dly;
+
+ const struct mc_ddr_cfg *cfgs;
+ mc_reset_t mc_reset;
+
+ u32 memsize;
+ u32 bus_width;
+};
+
+void ddr1_init(struct mc_ddr_init_param *param);
+void ddr2_init(struct mc_ddr_init_param *param);
+void ddr_calibrate(void __iomem *memc, u32 memsize, u32 bw);
+
+#endif /* _MTMIPS_DDR_H_ */
diff --git a/arch/mips/mach-mtmips/include/mach/mc.h b/arch/mips/mach-mtmips/include/mach/mc.h
new file mode 100644
index 00000000000..d7d623a63bc
--- /dev/null
+++ b/arch/mips/mach-mtmips/include/mach/mc.h
@@ -0,0 +1,180 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2020 MediaTek Inc.
+ *
+ * Author: Weijie Gao <weijie.gao@mediatek.com>
+ */
+
+#ifndef _MTMIPS_MC_H_
+#define _MTMIPS_MC_H_
+
+#define MEMCTL_SDRAM_CFG0_REG 0x00
+#define DIS_CLK_GT 0x80000000
+#define CLK_SLEW_S 29
+#define CLK_SLEW_M 0x60000000
+#define TWR 0x10000000
+#define TMRD_S 24
+#define TMRD_M 0xf000000
+#define TRFC_S 20
+#define TRFC_M 0xf00000
+#define TCAS_S 16
+#define TCAS_M 0x30000
+#define TRAS_S 12
+#define TRAS_M 0xf000
+#define TRCD_S 8
+#define TRCD_M 0x300
+#define TRC_S 4
+#define TRC_M 0xf0
+#define TRP_S 0
+#define TRP_M 0x03
+
+#define MEMCTL_SDRAM_CFG1_REG 0x04
+#define SDRAM_INIT_START 0x80000000
+#define SDRAM_INIT_DONE 0x40000000
+#define RBC_MAPPING 0x20000000
+#define PWR_DOWN_EN 0x10000000
+#define PWR_DOWN_MODE 0x8000000
+#define SDRAM_WIDTH 0x1000000
+#define NUMCOLS_S 20
+#define NUMCOLS_M 0x300000
+#define NUMROWS_S 16
+#define NUMROWS_M 0x30000
+#define TREFR_S 0
+#define TREFR_M 0xffff
+
+#define MEMCTL_DDR_SELF_REFRESH_REG 0x10
+#define ODT_SRC_SEL_S 24
+#define ODT_SRC_SEL_M 0xf000000
+#define ODT_OFF_DLY_S 20
+#define ODT_OFF_DLY_M 0xf00000
+#define ODT_ON_DLY_S 16
+#define ODT_ON_DLY_M 0xf0000
+#define SR_AUTO_EN 0x10
+#define SRACK_B 0x02
+#define SRREQ_B 0x01
+
+#define MEMCTL_PWR_SAVE_CNT_REG 0x14
+#define PD_CNT_S 24
+#define PD_CNT_M 0xff000000
+#define SR_TAR_CNT_S 0
+#define SR_TAR_CNT_M 0xffffff
+
+#define MEMCTL_DLL_DBG_REG 0x20
+#define TDC_STABLE_S 12
+#define TDC_STABLE_M 0x3f000
+#define MST_DLY_SEL_S 4
+#define MST_DLY_SEL_M 0xff0
+#define CURR_STATE_S 1
+#define CURR_STATE_M 0x06
+#define ADLL_LOCK_DONE 0x01
+
+#define MEMCTL_DDR_CFG0_REG 0x40
+#define T_RRD_S 28
+#define T_RRD_M 0xf0000000
+#define T_RAS_S 23
+#define T_RAS_M 0xf800000
+#define T_RP_S 19
+#define T_RP_M 0x780000
+#define T_RFC_S 13
+#define T_RFC_M 0x7e000
+#define T_REFI_S 0
+#define T_REFI_M 0x1fff
+
+#define MEMCTL_DDR_CFG1_REG 0x44
+#define T_WTR_S 28
+#define T_WTR_M 0xf0000000
+#define T_RTP_S 24
+#define T_RTP_M 0xf000000
+#define USER_DATA_WIDTH 0x200000
+#define IND_SDRAM_SIZE_S 18
+#define IND_SDRAM_SIZE_M 0x1c0000
+#define IND_SDRAM_SIZE_8MB 1
+#define IND_SDRAM_SIZE_16MB 2
+#define IND_SDRAM_SIZE_32MB 3
+#define IND_SDRAM_SIZE_64MB 4
+#define IND_SDRAM_SIZE_128MB 5
+#define IND_SDRAM_SIZE_256MB 6
+#define IND_SDRAM_WIDTH_S 16
+#define IND_SDRAM_WIDTH_M 0x30000
+#define IND_SDRAM_WIDTH_8BIT 1
+#define IND_SDRAM_WIDTH_16BIT 2
+#define EXT_BANK_S 14
+#define EXT_BANK_M 0xc000
+#define TOTAL_SDRAM_WIDTH_S 12
+#define TOTAL_SDRAM_WIDTH_M 0x3000
+#define T_WR_S 8
+#define T_WR_M 0xf00
+#define T_MRD_S 4
+#define T_MRD_M 0xf0
+#define T_RCD_S 0
+#define T_RCD_M 0x0f
+
+#define MEMCTL_DDR_CFG2_REG 0x48
+#define REGE 0x80000000
+#define DDR2_MODE 0x40000000
+#define DQS0_GATING_WINDOW_S 28
+#define DQS0_GATING_WINDOW_M 0x30000000
+#define DQS1_GATING_WINDOW_S 26
+#define DQS1_GATING_WINDOW_M 0xc000000
+#define PD 0x1000
+#define WR_S 9
+#define WR_M 0xe00
+#define DLLRESET 0x100
+#define TESTMODE 0x80
+#define CAS_LATENCY_S 4
+#define CAS_LATENCY_M 0x70
+#define BURST_TYPE 0x08
+#define BURST_LENGTH_S 0
+#define BURST_LENGTH_M 0x07
+
+#define MEMCTL_DDR_CFG3_REG 0x4c
+#define Q_OFF 0x1000
+#define RDOS 0x800
+#define DIS_DIFF_DQS 0x400
+#define OCD_S 7
+#define OCD_M 0x380
+#define RTT1 0x40
+#define ADDITIVE_LATENCY_S 3
+#define ADDITIVE_LATENCY_M 0x38
+#define RTT0 0x04
+#define DS 0x02
+#define DLL 0x01
+
+#define MEMCTL_DDR_CFG4_REG 0x50
+#define FAW_S 0
+#define FAW_M 0x0f
+
+#define MEMCTL_DDR_DQ_DLY_REG 0x60
+#define DQ1_DELAY_SEL_S 24
+#define DQ1_DELAY_SEL_M 0xff000000
+#define DQ0_DELAY_SEL_S 16
+#define DQ0_DELAY_SEL_M 0xff0000
+#define DQ1_DELAY_COARSE_TUNING_S 12
+#define DQ1_DELAY_COARSE_TUNING_M 0xf000
+#define DQ1_DELAY_FINE_TUNING_S 8
+#define DQ1_DELAY_FINE_TUNING_M 0xf00
+#define DQ0_DELAY_COARSE_TUNING_S 4
+#define DQ0_DELAY_COARSE_TUNING_M 0xf0
+#define DQ0_DELAY_FINE_TUNING_S 0
+#define DQ0_DELAY_FINE_TUNING_M 0x0f
+
+#define MEMCTL_DDR_DQS_DLY_REG 0x64
+#define DQS1_DELAY_SEL_S 24
+#define DQS1_DELAY_SEL_M 0xff000000
+#define DQS0_DELAY_SEL_S 16
+#define DQS0_DELAY_SEL_M 0xff0000
+#define DQS1_DELAY_COARSE_TUNING_S 12
+#define DQS1_DELAY_COARSE_TUNING_M 0xf000
+#define DQS1_DELAY_FINE_TUNING_S 8
+#define DQS1_DELAY_FINE_TUNING_M 0xf00
+#define DQS0_DELAY_COARSE_TUNING_S 4
+#define DQS0_DELAY_COARSE_TUNING_M 0xf0
+#define DQS0_DELAY_FINE_TUNING_S 0
+#define DQS0_DELAY_FINE_TUNING_M 0x0f
+
+#define MEMCTL_DDR_DLL_SLV_REG 0x68
+#define DLL_SLV_UPDATE_MODE 0x100
+#define DQS_DLY_SEL_EN 0x80
+#define DQ_DLY_SEL_EN 0x01
+
+#endif /* _MTMIPS_MC_H_ */
diff --git a/arch/mips/mach-mtmips/include/mach/serial.h b/arch/mips/mach-mtmips/include/mach/serial.h
new file mode 100644
index 00000000000..bfa246b428b
--- /dev/null
+++ b/arch/mips/mach-mtmips/include/mach/serial.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2020 MediaTek Inc.
+ *
+ * Author: Weijie Gao <weijie.gao@mediatek.com>
+ */
+
+#ifndef _MTMIPS_SERIAL_H_
+#define _MTMIPS_SERIAL_H_
+
+void mtmips_spl_serial_init(void);
+
+#endif /* _MTMIPS_SERIAL_H_ */
diff --git a/arch/mips/mach-mtmips/lowlevel_init.S b/arch/mips/mach-mtmips/lowlevel_init.S
deleted file mode 100644
index aa707e0de6c..00000000000
--- a/arch/mips/mach-mtmips/lowlevel_init.S
+++ /dev/null
@@ -1,328 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * (c) 2018 Stefan Roese <sr@denx.de>
- *
- * This code is mostly based on the code extracted from this MediaTek
- * github repository:
- *
- * https://github.com/MediaTek-Labs/linkit-smart-uboot.git
- *
- * I was not able to find a specific license or other developers
- * copyrights here, so I can't add them here.
- */
-
-#include <config.h>
-#include <asm/regdef.h>
-#include <asm/mipsregs.h>
-#include <asm/addrspace.h>
-#include <asm/asm.h>
-#include "mt76xx.h"
-
-#ifndef BIT
-#define BIT(nr) (1 << (nr))
-#endif
-
-#define DELAY_USEC(us) ((us) / 100)
-
-#define DDR_CFG1_CHIP_WIDTH_MASK (0x3 << 16)
-#define DDR_CFG1_BUS_WIDTH_MASK (0x3 << 12)
-
-#if defined(CONFIG_ONBOARD_DDR2_SIZE_256MBIT)
-#define DDR_CFG1_SIZE_VAL 0x222e2323
-#define DDR_CFG4_SIZE_VAL 7
-#endif
-#if defined(CONFIG_ONBOARD_DDR2_SIZE_512MBIT)
-#define DDR_CFG1_SIZE_VAL 0x22322323
-#define DDR_CFG4_SIZE_VAL 9
-#endif
-#if defined(CONFIG_ONBOARD_DDR2_SIZE_1024MBIT)
-#define DDR_CFG1_SIZE_VAL 0x22362323
-#define DDR_CFG4_SIZE_VAL 9
-#endif
-#if defined(CONFIG_ONBOARD_DDR2_SIZE_2048MBIT)
-#define DDR_CFG1_SIZE_VAL 0x223a2323
-#define DDR_CFG4_SIZE_VAL 9
-#endif
-
-#if defined(CONFIG_ONBOARD_DDR2_CHIP_WIDTH_8BIT)
-#define DDR_CFG1_CHIP_WIDTH_VAL (0x1 << 16)
-#endif
-#if defined(CONFIG_ONBOARD_DDR2_CHIP_WIDTH_16BIT)
-#define DDR_CFG1_CHIP_WIDTH_VAL (0x2 << 16)
-#endif
-
-#if defined(CONFIG_ONBOARD_DDR2_BUS_WIDTH_16BIT)
-#define DDR_CFG1_BUS_WIDTH_VAL (0x2 << 12)
-#endif
-#if defined(CONFIG_ONBOARD_DDR2_BUS_WIDTH_32BIT)
-#define DDR_CFG1_BUS_WIDTH_VAL (0x3 << 12)
-#endif
-
- .set noreorder
-
-LEAF(lowlevel_init)
-
- /* Load base addresses as physical addresses for later usage */
- li s0, CKSEG1ADDR(MT76XX_SYSCTL_BASE)
- li s1, CKSEG1ADDR(MT76XX_MEMCTRL_BASE)
- li s2, CKSEG1ADDR(MT76XX_RGCTRL_BASE)
-
- /* polling CPLL is ready */
- li t1, DELAY_USEC(1000000)
- la t5, MT76XX_ROM_STATUS_REG
-1:
- lw t2, 0(t5)
- andi t2, t2, 0x1
- bnez t2, CPLL_READY
- subu t1, t1, 1
- bgtz t1, 1b
- nop
- la t0, MT76XX_CLKCFG0_REG
- lw t3, 0(t0)
- ori t3, t3, 0x1
- sw t3, 0(t0)
- b CPLL_DONE
- nop
-CPLL_READY:
- la t0, MT76XX_CLKCFG0_REG
- lw t1, 0(t0)
- li t2, ~0x0c
- and t1, t1, t2
- ori t1, t1, 0xc
- sw t1, 0(t0)
- la t0, MT76XX_DYN_CFG0_REG
- lw t3, 0(t0)
- li t5, ~((0x0f << 8) | (0x0f << 0))
- and t3, t3, t5
- li t5, (10 << 8) | (1 << 0)
- or t3, t3, t5
- sw t3, 0(t0)
- la t0, MT76XX_CLKCFG0_REG
- lw t3, 0(t0)
- li t4, ~0x0F
- and t3, t3, t4
- ori t3, t3, 0xc
- sw t3, 0(t0)
- lw t3, 0(t0)
- ori t3, t3, 0x08
- sw t3, 0(t0)
-
-CPLL_DONE:
- /* Reset MC */
- lw t2, 0x34(s0)
- ori t2, BIT(10)
- sw t2, 0x34(s0)
- nop
-
- /*
- * SDR and DDR initialization: delay 200us
- */
- li t0, DELAY_USEC(200 + 40)
- li t1, 0x1
-1:
- sub t0, t0, t1
- bnez t0, 1b
- nop
-
- /* set DRAM IO PAD for MT7628IC */
- /* DDR LDO Enable */
- lw t4, 0x100(s2)
- li t2, BIT(31)
- or t4, t4, t2
- sw t4, 0x100(s2)
- lw t4, 0x10c(s2)
- j LDO_1P8V
- nop
-LDO_1P8V:
- li t2, ~BIT(6)
- and t4, t4, t2
- sw t4, 0x10c(s2)
- j DDRLDO_SOFT_START
-LDO_2P5V:
- /* suppose external DDR1 LDO 2.5V */
- li t2, BIT(6)
- or t4, t4, t2
- sw t4, 0x10c(s2)
-
-DDRLDO_SOFT_START:
- lw t2, 0x10c(s2)
- li t3, BIT(16)
- or t2, t2, t3
- sw t2, 0x10c(s2)
- li t3, DELAY_USEC(250*50)
-LDO_DELAY:
- subu t3, t3, 1
- bnez t3, LDO_DELAY
- nop
-
- lw t2, 0x10c(s2)
- li t3, BIT(18)
- or t2, t2, t3
- sw t2, 0x10c(s2)
-
-SET_RG_BUCK_FPWM:
- lw t2, 0x104(s2)
- ori t2, t2, BIT(10)
- sw t2, 0x104(s2)
-
-DDR_PAD_CFG:
- /* clean CLK PAD */
- lw t2, 0x704(s2)
- li t8, 0xfffff0f0
- and t2, t2, t8
- /* clean CMD PAD */
- lw t3, 0x70c(s2)
- li t8, 0xfffff0f0
- and t3, t3, t8
- /* clean DQ IPAD */
- lw t4, 0x710(s2)
- li t8, 0xfffff8ff
- and t4, t4, t8
- /* clean DQ OPAD */
- lw t5, 0x714(s2)
- li t8, 0xfffff0f0
- and t5, t5, t8
- /* clean DQS IPAD */
- lw t6, 0x718(s2)
- li t8, 0xfffff8ff
- and t6, t6, t8
- /* clean DQS OPAD */
- lw t7, 0x71c(s2)
- li t8, 0xfffff0f0
- and t7, t7, t8
-
- lw t9, 0xc(s0)
- srl t9, t9, 16
- andi t9, t9, 0x1
- bnez t9, MT7628_AN_DDR1_PAD
-MT7628_KN_PAD:
- li t8, 0x00000303
- or t2, t2, t8
- or t3, t3, t8
- or t5, t5, t8
- or t7, t7, t8
- li t8, 0x00000000
- or t4, t4, t8
- or t6, t6, t8
- j SET_PAD_CFG
-MT7628_AN_DDR1_PAD:
- lw t1, 0x10(s0)
- andi t1, t1, 0x1
- beqz t1, MT7628_AN_DDR2_PAD
- li t8, 0x00000c0c
- or t2, t2, t8
- li t8, 0x00000202
- or t3, t3, t8
- li t8, 0x00000707
- or t5, t5, t8
- li t8, 0x00000c0c
- or t7, t7, t8
- li t8, 0x00000000
- or t4, t4, t8
- or t6, t6, t8
- j SET_PAD_CFG
-MT7628_AN_DDR2_PAD:
- li t8, 0x00000c0c
- or t2, t2, t8
- li t8, 0x00000202
- or t3, t3, t8
- li t8, 0x00000404
- or t5, t5, t8
- li t8, 0x00000c0c
- or t7, t7, t8
- li t8, 0x00000000 /* ODT off */
- or t4, t4, t8
- or t6, t6, t8
-
-SET_PAD_CFG:
- sw t2, 0x704(s2)
- sw t3, 0x70c(s2)
- sw t4, 0x710(s2)
- sw t5, 0x714(s2)
- sw t6, 0x718(s2)
- sw t7, 0x71c(s2)
-
- /*
- * DDR initialization: reset pin to 0
- */
- lw t2, 0x34(s0)
- and t2, ~BIT(10)
- sw t2, 0x34(s0)
- nop
-
- /*
- * DDR initialization: wait til reg DDR_CFG1 bit 21 equal to 1 (ready)
- */
-DDR_READY:
- li t1, DDR_CFG1_REG
- lw t0, 0(t1)
- nop
- and t2, t0, BIT(21)
- beqz t2, DDR_READY
- nop
-
- /*
- * DDR initialization
- *
- * Only DDR2 supported right now. DDR2 support can be added, once
- * boards using it will get added to mainline U-Boot.
- */
- li t1, DDR_CFG2_REG
- lw t0, 0(t1)
- nop
- and t0, ~BIT(30)
- and t0, ~(7 << 4)
- or t0, (4 << 4)
- or t0, BIT(30)
- or t0, BIT(11)
- sw t0, 0(t1)
- nop
-
- li t1, DDR_CFG3_REG
- lw t2, 0(t1)
- /* Disable ODT; reference board ok, ev board fail */
- and t2, ~BIT(6)
- or t2, BIT(2)
- li t0, DDR_CFG4_REG
- lw t1, 0(t0)
- li t2, ~(0x01f | 0x0f0)
- and t1, t1, t2
- ori t1, t1, DDR_CFG4_SIZE_VAL
- sw t1, 0(t0)
- nop
-
- /*
- * DDR initialization: config size and width on reg DDR_CFG1
- */
- li t6, DDR_CFG1_SIZE_VAL
-
- and t6, ~DDR_CFG1_CHIP_WIDTH_MASK
- or t6, DDR_CFG1_CHIP_WIDTH_VAL
-
- /* CONFIG DDR_CFG1[13:12] about TOTAL WIDTH */
- and t6, ~DDR_CFG1_BUS_WIDTH_MASK
- or t6, DDR_CFG1_BUS_WIDTH_VAL
-
- li t5, DDR_CFG1_REG
- sw t6, 0(t5)
- nop
-
- /*
- * DDR: enable self auto refresh for power saving
- * enable it by default for both RAM and ROM version (for CoC)
- */
- lw t1, 0x14(s1)
- nop
- and t1, 0xff000000
- or t1, 0x01
- sw t1, 0x14(s1)
- nop
- lw t1, 0x10(s1)
- nop
- or t1, 0x10
- sw t1, 0x10(s1)
- nop
-
- jr ra
- nop
- END(lowlevel_init)
diff --git a/arch/mips/mach-mtmips/mt7628/Makefile b/arch/mips/mach-mtmips/mt7628/Makefile
new file mode 100644
index 00000000000..7e139d5adfd
--- /dev/null
+++ b/arch/mips/mach-mtmips/mt7628/Makefile
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-y += lowlevel_init.o
+obj-y += init.o
+obj-y += ddr.o
+obj-$(CONFIG_SPL_BUILD) += serial.o
diff --git a/arch/mips/mach-mtmips/mt7628/ddr.c b/arch/mips/mach-mtmips/mt7628/ddr.c
new file mode 100644
index 00000000000..06c0ca68541
--- /dev/null
+++ b/arch/mips/mach-mtmips/mt7628/ddr.c
@@ -0,0 +1,173 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 MediaTek Inc.
+ *
+ * Author: Weijie Gao <weijie.gao@mediatek.com>
+ */
+
+#include <common.h>
+#include <asm/addrspace.h>
+#include <linux/bitops.h>
+#include <linux/sizes.h>
+#include <linux/io.h>
+#include <mach/ddr.h>
+#include <mach/mc.h>
+#include "mt7628.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* DDR2 DQ_DLY */
+#define DDR2_DQ_DLY \
+ ((0x8 << DQ1_DELAY_COARSE_TUNING_S) | \
+ (0x2 << DQ1_DELAY_FINE_TUNING_S) | \
+ (0x8 << DQ0_DELAY_COARSE_TUNING_S) | \
+ (0x2 << DQ0_DELAY_FINE_TUNING_S))
+
+/* DDR2 DQS_DLY */
+#define DDR2_DQS_DLY \
+ ((0x8 << DQS1_DELAY_COARSE_TUNING_S) | \
+ (0x3 << DQS1_DELAY_FINE_TUNING_S) | \
+ (0x8 << DQS0_DELAY_COARSE_TUNING_S) | \
+ (0x3 << DQS0_DELAY_FINE_TUNING_S))
+
+const struct mc_ddr_cfg ddr1_cfgs_200mhz[] = {
+ [DRAM_8MB] = { 0x34A1EB94, 0x20262324, 0x28000033, 0x00000002, 0x00000000 },
+ [DRAM_16MB] = { 0x34A1EB94, 0x202A2324, 0x28000033, 0x00000002, 0x00000000 },
+ [DRAM_32MB] = { 0x34A1E5CA, 0x202E2324, 0x28000033, 0x00000002, 0x00000000 },
+ [DRAM_64MB] = { 0x3421E5CA, 0x20322324, 0x28000033, 0x00000002, 0x00000000 },
+ [DRAM_128MB] = { 0x241B05CA, 0x20362334, 0x28000033, 0x00000002, 0x00000000 },
+};
+
+const struct mc_ddr_cfg ddr1_cfgs_160mhz[] = {
+ [DRAM_8MB] = { 0x239964A1, 0x20262323, 0x00000033, 0x00000002, 0x00000000 },
+ [DRAM_16MB] = { 0x239964A1, 0x202A2323, 0x00000033, 0x00000002, 0x00000000 },
+ [DRAM_32MB] = { 0x239964A1, 0x202E2323, 0x00000033, 0x00000002, 0x00000000 },
+ [DRAM_64MB] = { 0x239984A1, 0x20322323, 0x00000033, 0x00000002, 0x00000000 },
+ [DRAM_128MB] = { 0x239AB4A1, 0x20362333, 0x00000033, 0x00000002, 0x00000000 },
+};
+
+const struct mc_ddr_cfg ddr2_cfgs_200mhz[] = {
+ [DRAM_32MB] = { 0x2519E2E5, 0x222E2323, 0x68000C43, 0x00000452, 0x0000000A },
+ [DRAM_64MB] = { 0x249AA2E5, 0x22322323, 0x68000C43, 0x00000452, 0x0000000A },
+ [DRAM_128MB] = { 0x249B42E5, 0x22362323, 0x68000C43, 0x00000452, 0x0000000A },
+ [DRAM_256MB] = { 0x249CE2E5, 0x223A2323, 0x68000C43, 0x00000452, 0x0000000A },
+};
+
+const struct mc_ddr_cfg ddr2_cfgs_160mhz[] = {
+ [DRAM_32MB] = { 0x23918250, 0x222E2322, 0x40000A43, 0x00000452, 0x00000006 },
+ [DRAM_64MB] = { 0x239A2250, 0x22322322, 0x40000A43, 0x00000452, 0x00000008 },
+ [DRAM_128MB] = { 0x2392A250, 0x22362322, 0x40000A43, 0x00000452, 0x00000008 },
+ [DRAM_256MB] = { 0x24140250, 0x223A2322, 0x40000A43, 0x00000452, 0x00000008 },
+};
+
+static void mt7628_memc_reset(int assert)
+{
+ void __iomem *sysc = ioremap_nocache(SYSCTL_BASE, SYSCTL_SIZE);
+
+ if (assert)
+ setbits_32(sysc + SYSCTL_RSTCTL_REG, MC_RST);
+ else
+ clrbits_32(sysc + SYSCTL_RSTCTL_REG, MC_RST);
+}
+
+static void mt7628_ddr_pad_ldo_config(int ddr_type, int pkg_type)
+{
+ void __iomem *rgc = ioremap_nocache(RGCTL_BASE, RGCTL_SIZE);
+ u32 ck_pad1, cmd_pad1, dq_pad0, dq_pad1, dqs_pad0, dqs_pad1;
+
+ setbits_32(rgc + RGCTL_PMU_G0_REG, PMU_CFG_EN);
+
+ if (ddr_type == DRAM_DDR1)
+ setbits_32(rgc + RGCTL_PMU_G3_REG, RG_DDRLDO_VOSEL);
+ else
+ clrbits_32(rgc + RGCTL_PMU_G3_REG, RG_DDRLDO_VOSEL);
+
+ setbits_32(rgc + RGCTL_PMU_G3_REG, NI_DDRLDO_EN);
+
+ __udelay(250 * 50);
+
+ setbits_32(rgc + RGCTL_PMU_G3_REG, NI_DDRLDO_STB);
+ setbits_32(rgc + RGCTL_PMU_G1_REG, RG_BUCK_FPWM);
+
+ ck_pad1 = readl(rgc + RGCTL_DDR_PAD_CK_G1_REG);
+ cmd_pad1 = readl(rgc + RGCTL_DDR_PAD_CMD_G1_REG);
+ dq_pad0 = readl(rgc + RGCTL_DDR_PAD_DQ_G0_REG);
+ dq_pad1 = readl(rgc + RGCTL_DDR_PAD_DQ_G1_REG);
+ dqs_pad0 = readl(rgc + RGCTL_DDR_PAD_DQS_G0_REG);
+ dqs_pad1 = readl(rgc + RGCTL_DDR_PAD_DQS_G1_REG);
+
+ ck_pad1 &= ~(DRVP_M | DRVN_M);
+ cmd_pad1 &= ~(DRVP_M | DRVN_M);
+ dq_pad0 &= ~RTT_M;
+ dq_pad1 &= ~(DRVP_M | DRVN_M);
+ dqs_pad0 &= ~RTT_M;
+ dqs_pad1 &= ~(DRVP_M | DRVN_M);
+
+ if (pkg_type == PKG_ID_KN) {
+ ck_pad1 |= (3 << DRVP_S) | (3 << DRVN_S);
+ cmd_pad1 |= (3 << DRVP_S) | (3 << DRVN_S);
+ dq_pad1 |= (3 << DRVP_S) | (3 << DRVN_S);
+ dqs_pad1 |= (3 << DRVP_S) | (3 << DRVN_S);
+ } else {
+ ck_pad1 |= (12 << DRVP_S) | (12 << DRVN_S);
+ cmd_pad1 |= (2 << DRVP_S) | (2 << DRVN_S);
+ dqs_pad1 |= (12 << DRVP_S) | (12 << DRVN_S);
+ if (ddr_type == DRAM_DDR1)
+ dq_pad1 |= (7 << DRVP_S) | (7 << DRVN_S);
+ else
+ dq_pad1 |= (4 << DRVP_S) | (4 << DRVN_S);
+ }
+
+ writel(ck_pad1, rgc + RGCTL_DDR_PAD_CK_G1_REG);
+ writel(cmd_pad1, rgc + RGCTL_DDR_PAD_CMD_G1_REG);
+ writel(dq_pad0, rgc + RGCTL_DDR_PAD_DQ_G0_REG);
+ writel(dq_pad1, rgc + RGCTL_DDR_PAD_DQ_G1_REG);
+ writel(dqs_pad0, rgc + RGCTL_DDR_PAD_DQS_G0_REG);
+ writel(dqs_pad1, rgc + RGCTL_DDR_PAD_DQS_G1_REG);
+}
+
+void mt7628_ddr_init(void)
+{
+ void __iomem *sysc;
+ int ddr_type, pkg_type, lspd;
+ struct mc_ddr_init_param param;
+
+ sysc = ioremap_nocache(SYSCTL_BASE, SYSCTL_SIZE);
+ ddr_type = readl(sysc + SYSCTL_SYSCFG0_REG) & DRAM_TYPE;
+ pkg_type = !!(readl(sysc + SYSCTL_CHIP_REV_ID_REG) & PKG_ID);
+ lspd = readl(sysc + SYSCTL_CLKCFG0_REG) &
+ (CPU_PLL_FROM_BBP | CPU_PLL_FROM_XTAL);
+
+ mt7628_memc_reset(1);
+ __udelay(200);
+
+ mt7628_ddr_pad_ldo_config(ddr_type, pkg_type);
+
+ param.memc = ioremap_nocache(MEMCTL_BASE, MEMCTL_SIZE);
+ param.dq_dly = DDR2_DQ_DLY;
+ param.dqs_dly = DDR2_DQS_DLY;
+ param.mc_reset = mt7628_memc_reset;
+ param.memsize = 0;
+ param.bus_width = 0;
+
+ if (pkg_type == PKG_ID_KN)
+ ddr_type = DRAM_DDR1;
+
+ if (ddr_type == DRAM_DDR1) {
+ if (lspd)
+ param.cfgs = ddr1_cfgs_160mhz;
+ else
+ param.cfgs = ddr1_cfgs_200mhz;
+ ddr1_init(&param);
+ } else {
+ if (lspd)
+ param.cfgs = ddr2_cfgs_160mhz;
+ else
+ param.cfgs = ddr2_cfgs_200mhz;
+ ddr2_init(&param);
+ }
+
+ ddr_calibrate(param.memc, param.memsize, param.bus_width);
+
+ gd->ram_size = param.memsize;
+}
diff --git a/arch/mips/mach-mtmips/mt7628/init.c b/arch/mips/mach-mtmips/mt7628/init.c
new file mode 100644
index 00000000000..77d1f2ea0dc
--- /dev/null
+++ b/arch/mips/mach-mtmips/mt7628/init.c
@@ -0,0 +1,109 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 MediaTek Inc.
+ *
+ * Author: Weijie Gao <weijie.gao@mediatek.com>
+ */
+
+#include <common.h>
+#include <clk.h>
+#include <dm.h>
+#include <dm/uclass.h>
+#include <dt-bindings/clock/mt7628-clk.h>
+#include <linux/io.h>
+#include "mt7628.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static void set_init_timer_freq(void)
+{
+ void __iomem *sysc;
+ u32 bs, val, timer_freq_post;
+
+ sysc = ioremap_nocache(SYSCTL_BASE, SYSCTL_SIZE);
+
+ /* We can't use the clk driver as the DM has not been initialized yet */
+ bs = readl(sysc + SYSCTL_SYSCFG0_REG);
+ if ((bs & XTAL_FREQ_SEL) == XTAL_25MHZ) {
+ gd->arch.timer_freq = 25000000;
+ timer_freq_post = 575000000;
+ } else {
+ gd->arch.timer_freq = 40000000;
+ timer_freq_post = 580000000;
+ }
+
+ val = readl(sysc + SYSCTL_CLKCFG0_REG);
+ if (!(val & (CPU_PLL_FROM_BBP | CPU_PLL_FROM_XTAL)))
+ gd->arch.timer_freq = timer_freq_post;
+}
+
+void mt7628_init(void)
+{
+ set_init_timer_freq();
+
+ mt7628_ddr_init();
+}
+
+int print_cpuinfo(void)
+{
+ void __iomem *sysc;
+ struct udevice *clkdev;
+ u32 val, ver, eco, pkg, ddr, chipmode, ee;
+ ulong cpu_clk, bus_clk, xtal_clk, timer_freq;
+ struct clk clk;
+ int ret;
+
+ sysc = ioremap_nocache(SYSCTL_BASE, SYSCTL_SIZE);
+
+ val = readl(sysc + SYSCTL_CHIP_REV_ID_REG);
+ ver = (val & VER_M) >> VER_S;
+ eco = (val & ECO_M) >> ECO_S;
+ pkg = !!(val & PKG_ID);
+
+ val = readl(sysc + SYSCTL_SYSCFG0_REG);
+ ddr = val & DRAM_TYPE;
+ chipmode = (val & CHIP_MODE_M) >> CHIP_MODE_S;
+
+ val = readl(sysc + SYSCTL_EFUSE_CFG_REG);
+ ee = val & EFUSE_MT7688;
+
+ printf("CPU: MediaTek MT%u%c ver:%u eco:%u\n",
+ ee ? 7688 : 7628, pkg ? 'A' : 'K', ver, eco);
+
+ printf("Boot: DDR%s, SPI-NOR %u-Byte Addr, CPU clock from %s\n",
+ ddr ? "" : "2", chipmode & 0x01 ? 4 : 3,
+ chipmode & 0x02 ? "XTAL" : "CPLL");
+
+ ret = uclass_get_device_by_driver(UCLASS_CLK, DM_GET_DRIVER(mt7628_clk),
+ &clkdev);
+ if (ret)
+ return ret;
+
+ clk.dev = clkdev;
+
+ clk.id = CLK_CPU;
+ cpu_clk = clk_get_rate(&clk);
+
+ clk.id = CLK_SYS;
+ bus_clk = clk_get_rate(&clk);
+
+ clk.id = CLK_XTAL;
+ xtal_clk = clk_get_rate(&clk);
+
+ clk.id = CLK_MIPS_CNT;
+ timer_freq = clk_get_rate(&clk);
+
+ /* Set final timer frequency */
+ if (timer_freq)
+ gd->arch.timer_freq = timer_freq;
+
+ printf("Clock: CPU: %luMHz, Bus: %luMHz, XTAL: %luMHz\n",
+ cpu_clk / 1000000, bus_clk / 1000000, xtal_clk / 1000000);
+
+ return 0;
+}
+
+ulong notrace get_tbclk(void)
+{
+ return gd->arch.timer_freq;
+}
diff --git a/arch/mips/mach-mtmips/mt7628/lowlevel_init.S b/arch/mips/mach-mtmips/mt7628/lowlevel_init.S
new file mode 100644
index 00000000000..e4a6c035808
--- /dev/null
+++ b/arch/mips/mach-mtmips/mt7628/lowlevel_init.S
@@ -0,0 +1,161 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2020 MediaTek Inc.
+ *
+ * Author: Weijie Gao <weijie.gao@mediatek.com>
+ */
+
+#include <config.h>
+#include <asm-offsets.h>
+#include <asm/cacheops.h>
+#include <asm/regdef.h>
+#include <asm/mipsregs.h>
+#include <asm/addrspace.h>
+#include <asm/asm.h>
+#include "mt7628.h"
+
+/* Set temporary stack address range */
+#ifndef CONFIG_SYS_INIT_SP_ADDR
+#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_SDRAM_BASE + \
+ CONFIG_SYS_INIT_SP_OFFSET)
+#endif
+
+#define CACHE_STACK_SIZE 0x4000
+#define CACHE_STACK_BASE (CONFIG_SYS_INIT_SP_ADDR - CACHE_STACK_SIZE)
+
+#define DELAY_USEC(us) ((58 * (us)) / 3)
+
+ .set noreorder
+
+LEAF(mips_sram_init)
+#ifndef CONFIG_SKIP_LOWLEVEL_INIT
+ /* Setup CPU PLL */
+ li t0, DELAY_USEC(1000000)
+ li t1, KSEG1ADDR(SYSCTL_BASE + SYSCTL_ROM_STATUS_REG)
+ li t2, KSEG1ADDR(SYSCTL_BASE + SYSCTL_CLKCFG0_REG)
+
+_check_rom_status:
+ lw t3, 0(t1)
+ andi t3, t3, 1
+ bnez t3, _rom_normal
+ subu t0, t0, 1
+ bnez t0, _check_rom_status
+ nop
+
+ lw t3, 0(t2)
+ ori t3, (CPU_PLL_FROM_BBP | CPU_PLL_FROM_XTAL)
+ xori t3, CPU_PLL_FROM_BBP
+ b _cpu_pll_done
+ nop
+
+_rom_normal:
+ lw t3, 0(t2)
+ ori t3, (CPU_PLL_FROM_BBP | CPU_PLL_FROM_XTAL | \
+ DIS_BBP_SLEEP | EN_BBP_CLK)
+ xori t3, (CPU_PLL_FROM_BBP | CPU_PLL_FROM_XTAL)
+
+_cpu_pll_done:
+ sw t3, 0(t2)
+
+ li t2, KSEG1ADDR(RBUSCTL_BASE + RBUSCTL_DYN_CFG0_REG)
+ lw t3, 0(t2)
+ ori t3, t3, (CPU_FDIV_M | CPU_FFRAC_M)
+ xori t3, t3, (CPU_FDIV_M | CPU_FFRAC_M)
+ ori t3, t3, ((1 << CPU_FDIV_S) | (1 << CPU_FFRAC_S))
+ sw t3, 0(t2)
+
+ /* Clear WST & SPR bits in ErrCtl */
+ mfc0 t0, CP0_ECC
+ ins t0, zero, 30, 2
+ mtc0 t0, CP0_ECC
+ ehb
+
+ /* Simply initialize I-Cache */
+ li a0, 0
+ li a1, CONFIG_SYS_ICACHE_SIZE
+
+ mtc0 zero, CP0_TAGLO /* Zero to DDataLo */
+
+1: cache INDEX_STORE_TAG_I, 0(a0)
+ addiu a0, CONFIG_SYS_ICACHE_LINE_SIZE
+ bne a0, a1, 1b
+ nop
+
+ /* Simply initialize D-Cache */
+ li a0, 0
+ li a1, CONFIG_SYS_DCACHE_SIZE
+
+ mtc0 zero, CP0_TAGLO, 2
+
+2: cache INDEX_STORE_TAG_D, 0(a0)
+ addiu a0, CONFIG_SYS_DCACHE_LINE_SIZE
+ bne a0, a1, 2b
+ nop
+
+ /* Set KSEG0 Cachable */
+ mfc0 t0, CP0_CONFIG
+ and t0, t0, MIPS_CONF_IMPL
+ or t0, t0, CONF_CM_CACHABLE_NONCOHERENT
+ mtc0 t0, CP0_CONFIG
+ ehb
+
+ /* Lock D-Cache */
+ PTR_LI a0, CACHE_STACK_BASE /* D-Cache lock base */
+ li a1, CACHE_STACK_SIZE /* D-Cache lock size */
+ li a2, 0x1ffff800 /* Mask of DTagLo[PTagLo] */
+
+3:
+ /* Lock one cacheline */
+ and t0, a0, a2
+ ori t0, 0xe0 /* Valid & Dirty & Lock bits */
+ mtc0 t0, CP0_TAGLO, 2 /* Write to DTagLo */
+ ehb
+ cache INDEX_STORE_TAG_D, 0(a0)
+
+ addiu a0, CONFIG_SYS_DCACHE_LINE_SIZE
+ sub a1, CONFIG_SYS_DCACHE_LINE_SIZE
+ bnez a1, 3b
+ nop
+#endif /* CONFIG_SKIP_LOWLEVEL_INIT */
+
+ jr ra
+ nop
+ END(mips_sram_init)
+
+NESTED(lowlevel_init, 0, ra)
+ /* Save ra and do real lowlevel initialization */
+ move s0, ra
+
+ PTR_LA t9, mt7628_init
+ jalr t9
+ nop
+
+ move ra, s0
+
+#if CONFIG_IS_ENABLED(INIT_STACK_WITHOUT_MALLOC_F)
+ /* Set malloc base */
+ li t0, (CONFIG_SYS_INIT_SP_ADDR + 15) & (~15)
+ PTR_S t0, GD_MALLOC_BASE(k0) # gd->malloc_base offset
+#endif
+
+ /* Write back data in locked cache to DRAM */
+ PTR_LI a0, CACHE_STACK_BASE /* D-Cache unlock base */
+ li a1, CACHE_STACK_SIZE /* D-Cache unlock size */
+
+1:
+ cache HIT_WRITEBACK_INV_D, 0(a0)
+ addiu a0, CONFIG_SYS_DCACHE_LINE_SIZE
+ sub a1, CONFIG_SYS_DCACHE_LINE_SIZE
+ bnez a1, 1b
+ nop
+
+ /* Set KSEG0 Uncached */
+ mfc0 t0, CP0_CONFIG
+ and t0, t0, MIPS_CONF_IMPL
+ or t0, t0, CONF_CM_UNCACHED
+ mtc0 t0, CP0_CONFIG
+ ehb
+
+ jr ra
+ nop
+ END(lowlevel_init)
diff --git a/arch/mips/mach-mtmips/mt7628/mt7628.h b/arch/mips/mach-mtmips/mt7628/mt7628.h
new file mode 100644
index 00000000000..391880b014e
--- /dev/null
+++ b/arch/mips/mach-mtmips/mt7628/mt7628.h
@@ -0,0 +1,104 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2020 MediaTek Inc.
+ *
+ * Author: Weijie Gao <weijie.gao@mediatek.com>
+ */
+
+#ifndef _MT7628_H_
+#define _MT7628_H_
+
+#define SYSCTL_BASE 0x10000000
+#define SYSCTL_SIZE 0x100
+#define MEMCTL_BASE 0x10000300
+#define MEMCTL_SIZE 0x100
+#define RBUSCTL_BASE 0x10000400
+#define RBUSCTL_SIZE 0x100
+#define RGCTL_BASE 0x10001000
+#define RGCTL_SIZE 0x800
+
+#define SYSCTL_EFUSE_CFG_REG 0x08
+#define EFUSE_MT7688 0x100000
+
+#define SYSCTL_CHIP_REV_ID_REG 0x0c
+#define PKG_ID 0x10000
+#define PKG_ID_AN 1
+#define PKG_ID_KN 0
+#define VER_S 8
+#define VER_M 0xf00
+#define ECO_S 0
+#define ECO_M 0x0f
+
+#define SYSCTL_SYSCFG0_REG 0x10
+#define XTAL_FREQ_SEL 0x40
+#define XTAL_40MHZ 1
+#define XTAL_25MHZ 0
+#define CHIP_MODE_S 1
+#define CHIP_MODE_M 0x0e
+#define DRAM_TYPE 0x01
+#define DRAM_DDR1 1
+#define DRAM_DDR2 0
+
+#define SYSCTL_ROM_STATUS_REG 0x28
+
+#define SYSCTL_CLKCFG0_REG 0x2c
+#define DIS_BBP_SLEEP 0x08
+#define EN_BBP_CLK 0x04
+#define CPU_PLL_FROM_BBP 0x02
+#define CPU_PLL_FROM_XTAL 0x01
+
+#define SYSCTL_RSTCTL_REG 0x34
+#define MC_RST 0x400
+
+#define SYSCTL_AGPIO_CFG_REG 0x3c
+#define EPHY_GPIO_AIO_EN_S 17
+#define EPHY_GPIO_AIO_EN_M 0x1e0000
+
+#define SYSCTL_GPIO_MODE1_REG 0x60
+#define UART2_MODE_S 26
+#define UART2_MODE_M 0xc000000
+#define UART1_MODE_S 24
+#define UART1_MODE_M 0x3000000
+#define UART0_MODE_S 8
+#define UART0_MODE_M 0x300
+#define SPIS_MODE_S 2
+#define SPIS_MODE_M 0x0c
+
+#define RBUSCTL_DYN_CFG0_REG 0x40
+#define CPU_FDIV_S 8
+#define CPU_FDIV_M 0xf00
+#define CPU_FFRAC_S 0
+#define CPU_FFRAC_M 0x0f
+
+#define RGCTL_PMU_G0_REG 0x100
+#define PMU_CFG_EN 0x80000000
+
+#define RGCTL_PMU_G1_REG 0x104
+#define RG_BUCK_FPWM 0x02
+
+#define RGCTL_PMU_G3_REG 0x10c
+#define NI_DDRLDO_STB 0x40000
+#define NI_DDRLDO_EN 0x10000
+#define RG_DDRLDO_VOSEL 0x40
+
+#define RGCTL_DDR_PAD_CK_G0_REG 0x700
+#define RGCTL_DDR_PAD_CMD_G0_REG 0x708
+#define RGCTL_DDR_PAD_DQ_G0_REG 0x710
+#define RGCTL_DDR_PAD_DQS_G0_REG 0x718
+#define RTT_S 8
+#define RTT_M 0x700
+
+#define RGCTL_DDR_PAD_CK_G1_REG 0x704
+#define RGCTL_DDR_PAD_CMD_G1_REG 0x70c
+#define RGCTL_DDR_PAD_DQ_G1_REG 0x714
+#define RGCTL_DDR_PAD_DQS_G1_REG 0x71c
+#define DRVP_S 0
+#define DRVP_M 0x0f
+#define DRVN_S 8
+#define DRVN_M 0xf00
+
+#ifndef __ASSEMBLY__
+void mt7628_ddr_init(void);
+#endif
+
+#endif /* _MT7628_H_ */
diff --git a/arch/mips/mach-mtmips/mt7628/serial.c b/arch/mips/mach-mtmips/mt7628/serial.c
new file mode 100644
index 00000000000..a7d324792d7
--- /dev/null
+++ b/arch/mips/mach-mtmips/mt7628/serial.c
@@ -0,0 +1,34 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 MediaTek Inc.
+ *
+ * Author: Weijie Gao <weijie.gao@mediatek.com>
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include "mt7628.h"
+
+void mtmips_spl_serial_init(void)
+{
+#ifdef CONFIG_SPL_SERIAL_SUPPORT
+ void __iomem *base = ioremap_nocache(SYSCTL_BASE, SYSCTL_SIZE);
+
+#if CONFIG_CONS_INDEX == 1
+ clrbits_32(base + SYSCTL_GPIO_MODE1_REG, UART0_MODE_M);
+#elif CONFIG_CONS_INDEX == 2
+ clrbits_32(base + SYSCTL_GPIO_MODE1_REG, UART1_MODE_M);
+#elif CONFIG_CONS_INDEX == 3
+ setbits_32(base + SYSCTL_AGPIO_CFG_REG, EPHY_GPIO_AIO_EN_M);
+#ifdef CONFIG_SPL_UART2_SPIS_PINMUX
+ setbits_32(base + SYSCTL_GPIO_MODE1_REG, SPIS_MODE_M);
+ clrsetbits_32(base + SYSCTL_GPIO_MODE1_REG, UART2_MODE_M,
+ 1 << UART2_MODE_S);
+#else
+ clrbits_32(base + SYSCTL_GPIO_MODE1_REG, UART2_MODE_M);
+ clrsetbits_32(base + SYSCTL_GPIO_MODE1_REG, SPIS_MODE_M,
+ 1 << SPIS_MODE_S);
+#endif /* CONFIG_SPL_UART2_SPIS_PINMUX */
+#endif /* CONFIG_CONS_INDEX */
+#endif /* CONFIG_SPL_SERIAL_SUPPORT */
+}
diff --git a/arch/mips/mach-mtmips/mt76xx.h b/arch/mips/mach-mtmips/mt76xx.h
deleted file mode 100644
index 17473ea8f18..00000000000
--- a/arch/mips/mach-mtmips/mt76xx.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * Copyright (C) 2018 Stefan Roese <sr@denx.de>
- */
-
-#ifndef __MT76XX_H
-#define __MT76XX_H
-
-#define MT76XX_SYSCTL_BASE 0x10000000
-
-#define MT76XX_CHIPID_OFFS 0x00
-#define MT76XX_CHIP_REV_ID_OFFS 0x0c
-#define MT76XX_SYSCFG0_OFFS 0x10
-
-#define MT76XX_MEMCTRL_BASE (MT76XX_SYSCTL_BASE + 0x0300)
-#define MT76XX_RGCTRL_BASE (MT76XX_SYSCTL_BASE + 0x1000)
-
-#define MT76XX_ROM_STATUS_REG (MT76XX_SYSCTL_BASE + 0x0028)
-#define MT76XX_CLKCFG0_REG (MT76XX_SYSCTL_BASE + 0x002c)
-#define MT76XX_DYN_CFG0_REG (MT76XX_SYSCTL_BASE + 0x0440)
-
-#define DDR_CFG1_REG (MT76XX_MEMCTRL_BASE + 0x44)
-#define DDR_CFG2_REG (MT76XX_MEMCTRL_BASE + 0x48)
-#define DDR_CFG3_REG (MT76XX_MEMCTRL_BASE + 0x4c)
-#define DDR_CFG4_REG (MT76XX_MEMCTRL_BASE + 0x50)
-
-#ifndef __ASSEMBLY__
-/* Prototypes */
-void ddr_calibrate(void);
-#endif
-
-#endif
diff --git a/arch/mips/mach-mtmips/spl.c b/arch/mips/mach-mtmips/spl.c
new file mode 100644
index 00000000000..2a24af70c3a
--- /dev/null
+++ b/arch/mips/mach-mtmips/spl.c
@@ -0,0 +1,44 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 MediaTek Inc. All Rights Reserved.
+ *
+ * Author: Weijie Gao <weijie.gao@mediatek.com>
+ */
+
+#include <common.h>
+#include <fdt.h>
+#include <spl.h>
+#include <asm/sections.h>
+#include <linux/sizes.h>
+#include <mach/serial.h>
+
+void __noreturn board_init_f(ulong dummy)
+{
+ spl_init();
+
+#ifdef CONFIG_SPL_SERIAL_SUPPORT
+ /*
+ * mtmips_spl_serial_init() is useful if debug uart is enabled,
+ * or DM based serial is not enabled.
+ */
+ mtmips_spl_serial_init();
+ preloader_console_init();
+#endif
+
+ board_init_r(NULL, 0);
+}
+
+void board_boot_order(u32 *spl_boot_list)
+{
+ spl_boot_list[0] = BOOT_DEVICE_NOR;
+}
+
+unsigned long spl_nor_get_uboot_base(void)
+{
+ void *uboot_base = __image_copy_end;
+
+ if (fdt_magic(uboot_base) == FDT_MAGIC)
+ return (unsigned long)uboot_base + fdt_totalsize(uboot_base);
+
+ return (unsigned long)uboot_base;
+}
diff --git a/board/gardena/smart-gateway-mt7688/board.c b/board/gardena/smart-gateway-mt7688/board.c
index 48cf3091e99..776afa43a66 100644
--- a/board/gardena/smart-gateway-mt7688/board.c
+++ b/board/gardena/smart-gateway-mt7688/board.c
@@ -295,8 +295,10 @@ err_free:
return ret;
}
+#ifndef CONFIG_SPL_BUILD
U_BOOT_CMD(
fd_write, 1, 0, do_fd_write,
"Write test factory-data values to SPI NOR",
"\n"
);
+#endif
diff --git a/board/mediatek/mt7628/Kconfig b/board/mediatek/mt7628/Kconfig
new file mode 100644
index 00000000000..d6b6f9d632f
--- /dev/null
+++ b/board/mediatek/mt7628/Kconfig
@@ -0,0 +1,12 @@
+if BOARD_MT7628_RFB
+
+config SYS_BOARD
+ default "mt7628"
+
+config SYS_VENDOR
+ default "mediatek"
+
+config SYS_CONFIG_NAME
+ default "mt7628"
+
+endif
diff --git a/board/mediatek/mt7628/MAINTAINERS b/board/mediatek/mt7628/MAINTAINERS
new file mode 100644
index 00000000000..032fd0e2f72
--- /dev/null
+++ b/board/mediatek/mt7628/MAINTAINERS
@@ -0,0 +1,7 @@
+MT7628_RFB BOARD
+M: Weijie Gao <weijie.gao@mediatek.com>
+S: Maintained
+F: board/mediatek/mt7628
+F: include/configs/mt7628.h
+F: configs/mt7628_rfb_defconfig
+F: arch/mips/dts/mediatek,mt7628-rfb.dts
diff --git a/board/mediatek/mt7628/Makefile b/board/mediatek/mt7628/Makefile
new file mode 100644
index 00000000000..db129c5abae
--- /dev/null
+++ b/board/mediatek/mt7628/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-y += board.o
diff --git a/board/mediatek/mt7628/board.c b/board/mediatek/mt7628/board.c
new file mode 100644
index 00000000000..f837a06fbbf
--- /dev/null
+++ b/board/mediatek/mt7628/board.c
@@ -0,0 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 MediaTek Inc. All Rights Reserved.
+ *
+ * Author: Weijie Gao <weijie.gao@mediatek.com>
+ */
+
+#include <common.h>
diff --git a/board/vocore/vocore2/Kconfig b/board/vocore/vocore2/Kconfig
new file mode 100644
index 00000000000..baeff31b692
--- /dev/null
+++ b/board/vocore/vocore2/Kconfig
@@ -0,0 +1,12 @@
+if BOARD_VOCORE2
+
+config SYS_BOARD
+ default "vocore2"
+
+config SYS_VENDOR
+ default "vocore"
+
+config SYS_CONFIG_NAME
+ default "vocore2"
+
+endif
diff --git a/board/vocore/vocore2/MAINTAINERS b/board/vocore/vocore2/MAINTAINERS
new file mode 100644
index 00000000000..8472351fe25
--- /dev/null
+++ b/board/vocore/vocore2/MAINTAINERS
@@ -0,0 +1,7 @@
+VOCORE_VOCORE2 BOARD
+M: Mauro Condarelli <mc5686@mclink.it>
+S: Maintained
+F: board/vocore/vocore2
+F: include/configs/vocore2.h
+F: configs/vocore2_defconfig
+F: arch/mips/dts/vocore_vocore2.dts
diff --git a/board/vocore/vocore2/Makefile b/board/vocore/vocore2/Makefile
new file mode 100644
index 00000000000..70cd7a8e568
--- /dev/null
+++ b/board/vocore/vocore2/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0+
+
+obj-y += board.o
diff --git a/board/vocore/vocore2/board.c b/board/vocore/vocore2/board.c
new file mode 100644
index 00000000000..27e42d14141
--- /dev/null
+++ b/board/vocore/vocore2/board.c
@@ -0,0 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2019 Mauro Condarelli <mc5686@mclink.it>
+ *
+ * Nothing actually needed here
+ */
diff --git a/common/spl/Makefile b/common/spl/Makefile
index eaa57f5ce5e..c576a781268 100644
--- a/common/spl/Makefile
+++ b/common/spl/Makefile
@@ -10,6 +10,7 @@ ifdef CONFIG_SPL_BUILD
obj-$(CONFIG_$(SPL_TPL_)FRAMEWORK) += spl.o
obj-$(CONFIG_$(SPL_TPL_)BOOTROM_SUPPORT) += spl_bootrom.o
obj-$(CONFIG_$(SPL_TPL_)LOAD_FIT) += spl_fit.o
+obj-$(CONFIG_$(SPL_TPL_)LEGACY_IMAGE_SUPPORT) += spl_legacy.o
obj-$(CONFIG_$(SPL_TPL_)NOR_SUPPORT) += spl_nor.o
obj-$(CONFIG_$(SPL_TPL_)XIP_SUPPORT) += spl_xip.o
obj-$(CONFIG_$(SPL_TPL_)YMODEM_SUPPORT) += spl_ymodem.o
diff --git a/common/spl/spl.c b/common/spl/spl.c
index 932e6ab98ac..b0f0e1557b9 100644
--- a/common/spl/spl.c
+++ b/common/spl/spl.c
@@ -254,6 +254,14 @@ static int spl_load_fit_image(struct spl_image_info *spl_image,
}
#endif
+__weak int spl_parse_legacy_header(struct spl_image_info *spl_image,
+ const struct image_header *header)
+{
+ /* LEGACY image not supported */
+ debug("Legacy boot image support not enabled, proceeding to other boot methods\n");
+ return -EINVAL;
+}
+
int spl_parse_image_header(struct spl_image_info *spl_image,
const struct image_header *header)
{
@@ -264,51 +272,11 @@ int spl_parse_image_header(struct spl_image_info *spl_image,
return ret;
#endif
if (image_get_magic(header) == IH_MAGIC) {
-#ifdef CONFIG_SPL_LEGACY_IMAGE_SUPPORT
- u32 header_size = sizeof(struct image_header);
-
-#ifdef CONFIG_SPL_LEGACY_IMAGE_CRC_CHECK
- /* check uImage header CRC */
- if (!image_check_hcrc(header)) {
- puts("SPL: Image header CRC check failed!\n");
- return -EINVAL;
- }
-#endif
-
- if (spl_image->flags & SPL_COPY_PAYLOAD_ONLY) {
- /*
- * On some system (e.g. powerpc), the load-address and
- * entry-point is located at address 0. We can't load
- * to 0-0x40. So skip header in this case.
- */
- spl_image->load_addr = image_get_load(header);
- spl_image->entry_point = image_get_ep(header);
- spl_image->size = image_get_data_size(header);
- } else {
- spl_image->entry_point = image_get_ep(header);
- /* Load including the header */
- spl_image->load_addr = image_get_load(header) -
- header_size;
- spl_image->size = image_get_data_size(header) +
- header_size;
- }
-#ifdef CONFIG_SPL_LEGACY_IMAGE_CRC_CHECK
- /* store uImage data length and CRC to check later */
- spl_image->dcrc_data = image_get_load(header);
- spl_image->dcrc_length = image_get_data_size(header);
- spl_image->dcrc = image_get_dcrc(header);
-#endif
+ int ret;
- spl_image->os = image_get_os(header);
- spl_image->name = image_get_name(header);
- debug(SPL_TPL_PROMPT
- "payload image: %32s load addr: 0x%lx size: %d\n",
- spl_image->name, spl_image->load_addr, spl_image->size);
-#else
- /* LEGACY image not supported */
- debug("Legacy boot image support not enabled, proceeding to other boot methods\n");
- return -EINVAL;
-#endif
+ ret = spl_parse_legacy_header(spl_image, header);
+ if (ret)
+ return ret;
} else {
#ifdef CONFIG_SPL_PANIC_ON_RAW_IMAGE
/*
diff --git a/common/spl/spl_legacy.c b/common/spl/spl_legacy.c
new file mode 100644
index 00000000000..29d3ec70734
--- /dev/null
+++ b/common/spl/spl_legacy.c
@@ -0,0 +1,131 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2020 Stefan Roese <sr@denx.de>
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <spl.h>
+
+#include <lzma/LzmaTypes.h>
+#include <lzma/LzmaDec.h>
+#include <lzma/LzmaTools.h>
+
+#define LZMA_LEN (1 << 20)
+
+int spl_parse_legacy_header(struct spl_image_info *spl_image,
+ const struct image_header *header)
+{
+ u32 header_size = sizeof(struct image_header);
+
+ /* check uImage header CRC */
+ if (IS_ENABLED(CONFIG_SPL_LEGACY_IMAGE_CRC_CHECK) &&
+ !image_check_hcrc(header)) {
+ puts("SPL: Image header CRC check failed!\n");
+ return -EINVAL;
+ }
+
+ if (spl_image->flags & SPL_COPY_PAYLOAD_ONLY) {
+ /*
+ * On some system (e.g. powerpc), the load-address and
+ * entry-point is located at address 0. We can't load
+ * to 0-0x40. So skip header in this case.
+ */
+ spl_image->load_addr = image_get_load(header);
+ spl_image->entry_point = image_get_ep(header);
+ spl_image->size = image_get_data_size(header);
+ } else {
+ spl_image->entry_point = image_get_ep(header);
+ /* Load including the header */
+ spl_image->load_addr = image_get_load(header) -
+ header_size;
+ spl_image->size = image_get_data_size(header) +
+ header_size;
+ }
+
+#ifdef CONFIG_SPL_LEGACY_IMAGE_CRC_CHECK
+ /* store uImage data length and CRC to check later */
+ spl_image->dcrc_data = image_get_load(header);
+ spl_image->dcrc_length = image_get_data_size(header);
+ spl_image->dcrc = image_get_dcrc(header);
+#endif
+
+ spl_image->os = image_get_os(header);
+ spl_image->name = image_get_name(header);
+ debug(SPL_TPL_PROMPT
+ "payload image: %32s load addr: 0x%lx size: %d\n",
+ spl_image->name, spl_image->load_addr, spl_image->size);
+
+ return 0;
+}
+
+/*
+ * This function is added explicitly to avoid code size increase, when
+ * no compression method is enabled. The compiler will optimize the
+ * following switch/case statement in spl_load_legacy_img() away due to
+ * Dead Code Elimination.
+ */
+static inline int spl_image_get_comp(const struct image_header *hdr)
+{
+ if (IS_ENABLED(CONFIG_SPL_LZMA))
+ return image_get_comp(hdr);
+
+ return IH_COMP_NONE;
+}
+
+int spl_load_legacy_img(struct spl_image_info *spl_image,
+ struct spl_load_info *load, ulong header)
+{
+ __maybe_unused SizeT lzma_len;
+ __maybe_unused void *src;
+ struct image_header hdr;
+ ulong dataptr;
+ int ret;
+
+ /* Read header into local struct */
+ load->read(load, header, sizeof(hdr), &hdr);
+
+ ret = spl_parse_image_header(spl_image, &hdr);
+ if (ret)
+ return ret;
+
+ dataptr = header + sizeof(hdr);
+
+ /* Read image */
+ switch (spl_image_get_comp(&hdr)) {
+ case IH_COMP_NONE:
+ load->read(load, dataptr, spl_image->size,
+ (void *)(unsigned long)spl_image->load_addr);
+ break;
+
+ case IH_COMP_LZMA:
+ lzma_len = LZMA_LEN;
+
+ debug("LZMA: Decompressing %08lx to %08lx\n",
+ dataptr, spl_image->load_addr);
+ src = malloc(spl_image->size);
+ if (!src) {
+ printf("Unable to allocate %d bytes for LZMA\n",
+ spl_image->size);
+ return -ENOMEM;
+ }
+
+ load->read(load, dataptr, spl_image->size, src);
+ ret = lzmaBuffToBuffDecompress((void *)spl_image->load_addr,
+ &lzma_len, src, spl_image->size);
+ if (ret) {
+ printf("LZMA decompression error: %d\n", ret);
+ return ret;
+ }
+
+ spl_image->size = lzma_len;
+ break;
+
+ default:
+ debug("Compression method %s is not supported\n",
+ genimg_get_comp_short_name(image_get_comp(&hdr)));
+ return -EINVAL;
+ }
+
+ return 0;
+}
diff --git a/common/spl/spl_nor.c b/common/spl/spl_nor.c
index b1e79b9ded6..3f03ffe6a33 100644
--- a/common/spl/spl_nor.c
+++ b/common/spl/spl_nor.c
@@ -24,7 +24,6 @@ unsigned long __weak spl_nor_get_uboot_base(void)
static int spl_nor_load_image(struct spl_image_info *spl_image,
struct spl_boot_device *bootdev)
{
- int ret;
__maybe_unused const struct image_header *header;
__maybe_unused struct spl_load_info load;
@@ -43,6 +42,8 @@ static int spl_nor_load_image(struct spl_image_info *spl_image,
header = (const struct image_header *)CONFIG_SYS_OS_BASE;
#ifdef CONFIG_SPL_LOAD_FIT
if (image_get_magic(header) == FDT_MAGIC) {
+ int ret;
+
debug("Found FIT\n");
load.bl_len = 1;
load.read = spl_nor_load_read;
@@ -61,6 +62,7 @@ static int spl_nor_load_image(struct spl_image_info *spl_image,
#endif
if (image_get_os(header) == IH_OS_LINUX) {
/* happy - was a Linux */
+ int ret;
ret = spl_parse_image_header(spl_image, header);
if (ret)
@@ -93,11 +95,9 @@ static int spl_nor_load_image(struct spl_image_info *spl_image,
debug("Found FIT format U-Boot\n");
load.bl_len = 1;
load.read = spl_nor_load_read;
- ret = spl_load_simple_fit(spl_image, &load,
- spl_nor_get_uboot_base(),
- (void *)header);
-
- return ret;
+ return spl_load_simple_fit(spl_image, &load,
+ spl_nor_get_uboot_base(),
+ (void *)header);
}
#endif
if (IS_ENABLED(CONFIG_SPL_LOAD_IMX_CONTAINER)) {
@@ -107,14 +107,13 @@ static int spl_nor_load_image(struct spl_image_info *spl_image,
spl_nor_get_uboot_base());
}
- ret = spl_parse_image_header(spl_image,
- (const struct image_header *)spl_nor_get_uboot_base());
- if (ret)
- return ret;
-
- memcpy((void *)(unsigned long)spl_image->load_addr,
- (void *)(spl_nor_get_uboot_base() + sizeof(struct image_header)),
- spl_image->size);
+ /* Legacy image handling */
+ if (IS_ENABLED(CONFIG_SPL_LEGACY_IMAGE_SUPPORT)) {
+ load.bl_len = 1;
+ load.read = spl_nor_load_read;
+ return spl_load_legacy_img(spl_image, &load,
+ spl_nor_get_uboot_base());
+ }
return 0;
}
diff --git a/configs/gardena-smart-gateway-mt7688-ram_defconfig b/configs/gardena-smart-gateway-mt7688-ram_defconfig
deleted file mode 100644
index dbc94b41063..00000000000
--- a/configs/gardena-smart-gateway-mt7688-ram_defconfig
+++ /dev/null
@@ -1,74 +0,0 @@
-CONFIG_MIPS=y
-CONFIG_SYS_TEXT_BASE=0x80010000
-CONFIG_ENV_SIZE=0x10000
-CONFIG_ENV_SECT_SIZE=0x10000
-CONFIG_ENV_OFFSET=0xA0000
-CONFIG_SYS_BOOTCOUNT_ADDR=0xb000006c
-CONFIG_NR_DRAM_BANKS=1
-CONFIG_SYS_BOOTCOUNT_SINGLEWORD=y
-CONFIG_ENV_OFFSET_REDUND=0xB0000
-CONFIG_ARCH_MTMIPS=y
-# CONFIG_MIPS_BOOT_ENV_LEGACY is not set
-CONFIG_MIPS_BOOT_FDT=y
-CONFIG_ENV_VARS_UBOOT_CONFIG=y
-CONFIG_FIT=y
-CONFIG_FIT_SIGNATURE=y
-CONFIG_LEGACY_IMAGE_FORMAT=y
-CONFIG_OF_STDOUT_VIA_ALIAS=y
-CONFIG_USE_BOOTCOMMAND=y
-CONFIG_BOOTCOMMAND="cp.b 83000000 84000000 10000 && dhcp uEnv.txt && env import -t ${fileaddr} ${filesize} && run do_u_boot_init; reset"
-CONFIG_USE_PREBOOT=y
-CONFIG_SYS_CONSOLE_INFO_QUIET=y
-CONFIG_VERSION_VARIABLE=y
-CONFIG_BOARD_EARLY_INIT_F=y
-CONFIG_HUSH_PARSER=y
-CONFIG_CMD_LICENSE=y
-# CONFIG_CMD_ELF is not set
-# CONFIG_CMD_XIMG is not set
-CONFIG_CMD_MEMINFO=y
-# CONFIG_CMD_FLASH is not set
-CONFIG_CMD_GPIO=y
-# CONFIG_CMD_LOADS is not set
-CONFIG_CMD_MTD=y
-CONFIG_CMD_SPI=y
-CONFIG_CMD_WDT=y
-CONFIG_CMD_DHCP=y
-CONFIG_CMD_MII=y
-CONFIG_CMD_PING=y
-CONFIG_CMD_BOOTCOUNT=y
-CONFIG_CMD_TIME=y
-CONFIG_CMD_UUID=y
-CONFIG_CMD_MTDPARTS=y
-CONFIG_MTDIDS_DEFAULT="spi-nand0=spi0.1,nor0=spi0.0"
-CONFIG_MTDPARTS_DEFAULT="spi0.0:640k(uboot),64k(uboot_env0),64k(uboot_env1),64k(factory),-(unused);spi0.1:-(nand)"
-CONFIG_CMD_UBI=y
-CONFIG_DEFAULT_DEVICE_TREE="gardena-smart-gateway-mt7688"
-CONFIG_ENV_IS_IN_SPI_FLASH=y
-CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
-CONFIG_SYS_RELOC_GD_ENV_ADDR=y
-CONFIG_NET_RANDOM_ETHADDR=y
-# CONFIG_DM_DEVICE_REMOVE is not set
-CONFIG_HAVE_BLOCK_DEVICE=y
-CONFIG_BOOTCOUNT_LIMIT=y
-CONFIG_LED=y
-CONFIG_LED_BLINK=y
-CONFIG_LED_GPIO=y
-CONFIG_MTD=y
-CONFIG_DM_MTD=y
-CONFIG_MTD_SPI_NAND=y
-CONFIG_SPI_FLASH_GIGADEVICE=y
-CONFIG_SPI_FLASH_MACRONIX=y
-CONFIG_SPI_FLASH_SPANSION=y
-CONFIG_SPI_FLASH_STMICRO=y
-CONFIG_SPI_FLASH_WINBOND=y
-CONFIG_SPI_FLASH_XMC=y
-CONFIG_SPI_FLASH_MTD=y
-CONFIG_MTD_UBI_BEB_LIMIT=22
-CONFIG_MT7628_ETH=y
-CONFIG_PHY=y
-CONFIG_SPI=y
-CONFIG_MT7621_SPI=y
-CONFIG_SYSRESET_SYSCON=y
-CONFIG_WDT=y
-CONFIG_WDT_MT7621=y
-CONFIG_LZMA=y
diff --git a/configs/gardena-smart-gateway-mt7688_defconfig b/configs/gardena-smart-gateway-mt7688_defconfig
index 23d8ddb128b..41496f739bd 100644
--- a/configs/gardena-smart-gateway-mt7688_defconfig
+++ b/configs/gardena-smart-gateway-mt7688_defconfig
@@ -1,16 +1,18 @@
CONFIG_MIPS=y
-CONFIG_SYS_TEXT_BASE=0x9c000000
+CONFIG_SPL_LIBCOMMON_SUPPORT=y
+CONFIG_SPL_LIBGENERIC_SUPPORT=y
CONFIG_ENV_SIZE=0x10000
-CONFIG_ENV_SECT_SIZE=0x10000
CONFIG_ENV_OFFSET=0xA0000
+CONFIG_ENV_SECT_SIZE=0x10000
+CONFIG_SPL_SERIAL_SUPPORT=y
CONFIG_SYS_BOOTCOUNT_ADDR=0xb000006c
+CONFIG_SPL_SYS_MALLOC_F_LEN=0x40000
CONFIG_NR_DRAM_BANKS=1
+CONFIG_SPL=y
CONFIG_SYS_BOOTCOUNT_SINGLEWORD=y
CONFIG_ENV_OFFSET_REDUND=0xB0000
CONFIG_ARCH_MTMIPS=y
-CONFIG_BOOT_ROM=y
-CONFIG_ONBOARD_DDR2_SIZE_1024MBIT=y
-CONFIG_ONBOARD_DDR2_CHIP_WIDTH_16BIT=y
+CONFIG_RESTORE_EXCEPTION_VECTOR_BASE=y
# CONFIG_MIPS_BOOT_ENV_LEGACY is not set
CONFIG_MIPS_BOOT_FDT=y
CONFIG_ENV_VARS_UBOOT_CONFIG=y
@@ -24,6 +26,8 @@ CONFIG_USE_PREBOOT=y
CONFIG_SYS_CONSOLE_INFO_QUIET=y
CONFIG_VERSION_VARIABLE=y
CONFIG_BOARD_EARLY_INIT_F=y
+CONFIG_SPL_SYS_MALLOC_SIMPLE=y
+CONFIG_SPL_NOR_SUPPORT=y
CONFIG_HUSH_PARSER=y
CONFIG_CMD_LICENSE=y
# CONFIG_CMD_ELF is not set
@@ -50,6 +54,7 @@ CONFIG_ENV_IS_IN_SPI_FLASH=y
CONFIG_SYS_REDUNDAND_ENVIRONMENT=y
CONFIG_SYS_RELOC_GD_ENV_ADDR=y
CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_SPL_DM=y
# CONFIG_DM_DEVICE_REMOVE is not set
CONFIG_HAVE_BLOCK_DEVICE=y
CONFIG_BOOTCOUNT_LIMIT=y
@@ -71,7 +76,7 @@ CONFIG_MT7628_ETH=y
CONFIG_PHY=y
CONFIG_SPI=y
CONFIG_MT7621_SPI=y
-CONFIG_SYSRESET_SYSCON=y
CONFIG_WDT=y
CONFIG_WDT_MT7621=y
CONFIG_LZMA=y
+CONFIG_SPL_LZMA=y
diff --git a/configs/linkit-smart-7688-ram_defconfig b/configs/linkit-smart-7688-ram_defconfig
deleted file mode 100644
index d1691abfdaf..00000000000
--- a/configs/linkit-smart-7688-ram_defconfig
+++ /dev/null
@@ -1,65 +0,0 @@
-CONFIG_MIPS=y
-CONFIG_SYS_TEXT_BASE=0x80010000
-CONFIG_ENV_SIZE=0x4000
-CONFIG_ENV_SECT_SIZE=0x10000
-CONFIG_ENV_OFFSET=0x80000
-CONFIG_NR_DRAM_BANKS=1
-CONFIG_ARCH_MTMIPS=y
-CONFIG_BOARD_LINKIT_SMART_7688=y
-# CONFIG_MIPS_BOOT_ENV_LEGACY is not set
-CONFIG_MIPS_BOOT_FDT=y
-CONFIG_FIT=y
-CONFIG_FIT_SIGNATURE=y
-CONFIG_LEGACY_IMAGE_FORMAT=y
-CONFIG_OF_STDOUT_VIA_ALIAS=y
-CONFIG_SYS_CONSOLE_INFO_QUIET=y
-CONFIG_BOARD_EARLY_INIT_F=y
-CONFIG_HUSH_PARSER=y
-CONFIG_CMD_LICENSE=y
-# CONFIG_CMD_ELF is not set
-# CONFIG_CMD_XIMG is not set
-CONFIG_CMD_MEMINFO=y
-# CONFIG_CMD_FLASH is not set
-CONFIG_CMD_GPIO=y
-# CONFIG_CMD_LOADS is not set
-CONFIG_CMD_MTD=y
-CONFIG_CMD_PART=y
-CONFIG_CMD_SPI=y
-CONFIG_CMD_USB=y
-CONFIG_CMD_DHCP=y
-CONFIG_CMD_MII=y
-CONFIG_CMD_PING=y
-CONFIG_CMD_TIME=y
-CONFIG_CMD_FS_GENERIC=y
-# CONFIG_DOS_PARTITION is not set
-CONFIG_DEFAULT_DEVICE_TREE="linkit-smart-7688"
-CONFIG_ENV_IS_IN_SPI_FLASH=y
-CONFIG_SYS_RELOC_GD_ENV_ADDR=y
-CONFIG_NET_RANDOM_ETHADDR=y
-# CONFIG_DM_DEVICE_REMOVE is not set
-CONFIG_BLK=y
-CONFIG_LED=y
-CONFIG_LED_BLINK=y
-CONFIG_LED_GPIO=y
-CONFIG_MTD=y
-CONFIG_SPI_FLASH_GIGADEVICE=y
-CONFIG_SPI_FLASH_MACRONIX=y
-CONFIG_SPI_FLASH_SPANSION=y
-CONFIG_SPI_FLASH_STMICRO=y
-CONFIG_SPI_FLASH_WINBOND=y
-CONFIG_SPI_FLASH_MTD=y
-CONFIG_MT7628_ETH=y
-CONFIG_PHY=y
-CONFIG_MT76X8_USB_PHY=y
-CONFIG_SPI=y
-CONFIG_MT7621_SPI=y
-CONFIG_SYSRESET_SYSCON=y
-CONFIG_USB=y
-CONFIG_DM_USB=y
-CONFIG_USB_EHCI_HCD=y
-CONFIG_USB_EHCI_GENERIC=y
-CONFIG_USB_STORAGE=y
-CONFIG_FS_EXT4=y
-CONFIG_FS_FAT=y
-CONFIG_LZMA=y
-CONFIG_LZO=y
diff --git a/configs/linkit-smart-7688_defconfig b/configs/linkit-smart-7688_defconfig
index a567c0c507e..8ec66938cdc 100644
--- a/configs/linkit-smart-7688_defconfig
+++ b/configs/linkit-smart-7688_defconfig
@@ -1,14 +1,16 @@
CONFIG_MIPS=y
-CONFIG_SYS_TEXT_BASE=0x9c000000
+CONFIG_SPL_LIBCOMMON_SUPPORT=y
+CONFIG_SPL_LIBGENERIC_SUPPORT=y
CONFIG_ENV_SIZE=0x4000
-CONFIG_ENV_SECT_SIZE=0x10000
CONFIG_ENV_OFFSET=0x80000
+CONFIG_ENV_SECT_SIZE=0x10000
+CONFIG_SPL_SERIAL_SUPPORT=y
+CONFIG_SPL_SYS_MALLOC_F_LEN=0x40000
CONFIG_NR_DRAM_BANKS=1
+CONFIG_SPL=y
CONFIG_ARCH_MTMIPS=y
CONFIG_BOARD_LINKIT_SMART_7688=y
-CONFIG_BOOT_ROM=y
-CONFIG_ONBOARD_DDR2_SIZE_1024MBIT=y
-CONFIG_ONBOARD_DDR2_CHIP_WIDTH_16BIT=y
+CONFIG_RESTORE_EXCEPTION_VECTOR_BASE=y
# CONFIG_MIPS_BOOT_ENV_LEGACY is not set
CONFIG_MIPS_BOOT_FDT=y
CONFIG_FIT=y
@@ -17,6 +19,8 @@ CONFIG_LEGACY_IMAGE_FORMAT=y
CONFIG_OF_STDOUT_VIA_ALIAS=y
CONFIG_SYS_CONSOLE_INFO_QUIET=y
CONFIG_BOARD_EARLY_INIT_F=y
+CONFIG_SPL_SYS_MALLOC_SIMPLE=y
+CONFIG_SPL_NOR_SUPPORT=y
CONFIG_HUSH_PARSER=y
CONFIG_CMD_LICENSE=y
# CONFIG_CMD_ELF is not set
@@ -40,6 +44,7 @@ CONFIG_DEFAULT_DEVICE_TREE="linkit-smart-7688"
CONFIG_ENV_IS_IN_SPI_FLASH=y
CONFIG_SYS_RELOC_GD_ENV_ADDR=y
CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_SPL_DM=y
# CONFIG_DM_DEVICE_REMOVE is not set
CONFIG_BLK=y
CONFIG_LED=y
@@ -57,7 +62,6 @@ CONFIG_PHY=y
CONFIG_MT76X8_USB_PHY=y
CONFIG_SPI=y
CONFIG_MT7621_SPI=y
-CONFIG_SYSRESET_SYSCON=y
CONFIG_USB=y
CONFIG_DM_USB=y
CONFIG_USB_EHCI_HCD=y
@@ -67,3 +71,4 @@ CONFIG_FS_EXT4=y
CONFIG_FS_FAT=y
CONFIG_LZMA=y
CONFIG_LZO=y
+CONFIG_SPL_LZMA=y
diff --git a/configs/mt7628_rfb_defconfig b/configs/mt7628_rfb_defconfig
new file mode 100644
index 00000000000..f444cf98c6c
--- /dev/null
+++ b/configs/mt7628_rfb_defconfig
@@ -0,0 +1,47 @@
+CONFIG_MIPS=y
+CONFIG_SPL_LIBCOMMON_SUPPORT=y
+CONFIG_SPL_LIBGENERIC_SUPPORT=y
+CONFIG_ENV_SIZE=0x1000
+CONFIG_ENV_OFFSET=0x30000
+CONFIG_ENV_SECT_SIZE=0x10000
+CONFIG_SPL_SERIAL_SUPPORT=y
+CONFIG_SPL_SYS_MALLOC_F_LEN=0x40000
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_SPL=y
+CONFIG_ARCH_MTMIPS=y
+CONFIG_BOARD_MT7628_RFB=y
+CONFIG_RESTORE_EXCEPTION_VECTOR_BASE=y
+CONFIG_MIPS_BOOT_FDT=y
+CONFIG_FIT=y
+# CONFIG_ARCH_FIXUP_FDT_MEMORY is not set
+CONFIG_SYS_CONSOLE_INFO_QUIET=y
+CONFIG_SPL_SYS_MALLOC_SIMPLE=y
+CONFIG_SPL_NOR_SUPPORT=y
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_XIMG is not set
+# CONFIG_CMD_CRC32 is not set
+# CONFIG_CMD_DM is not set
+CONFIG_CMD_GPIO=y
+# CONFIG_CMD_LOADS is not set
+CONFIG_CMD_SPI=y
+# CONFIG_CMD_NFS is not set
+# CONFIG_PARTITIONS is not set
+CONFIG_DEFAULT_DEVICE_TREE="mediatek,mt7628-rfb"
+CONFIG_ENV_IS_IN_SPI_FLASH=y
+CONFIG_SYS_RELOC_GD_ENV_ADDR=y
+CONFIG_NET_RANDOM_ETHADDR=y
+# CONFIG_INPUT is not set
+CONFIG_SPI_FLASH_EON=y
+CONFIG_SPI_FLASH_GIGADEVICE=y
+CONFIG_SPI_FLASH_ISSI=y
+CONFIG_SPI_FLASH_MACRONIX=y
+CONFIG_SPI_FLASH_SPANSION=y
+CONFIG_SPI_FLASH_STMICRO=y
+CONFIG_SPI_FLASH_WINBOND=y
+CONFIG_SPI_FLASH_XMC=y
+CONFIG_MT7628_ETH=y
+# CONFIG_SPECIFY_CONSOLE_INDEX is not set
+CONFIG_SPI=y
+CONFIG_MT7621_SPI=y
+CONFIG_LZMA=y
+CONFIG_SPL_LZMA=y
diff --git a/configs/vocore2_defconfig b/configs/vocore2_defconfig
new file mode 100644
index 00000000000..6cacec01838
--- /dev/null
+++ b/configs/vocore2_defconfig
@@ -0,0 +1,101 @@
+CONFIG_MIPS=y
+CONFIG_SPL_LIBCOMMON_SUPPORT=y
+CONFIG_SPL_LIBGENERIC_SUPPORT=y
+CONFIG_ENV_SIZE=0x1000
+CONFIG_ENV_OFFSET=0x04e000
+CONFIG_ENV_SECT_SIZE=0x1000
+CONFIG_SYS_BOOTCOUNT_ADDR=0xb000006c
+CONFIG_SPL_SYS_MALLOC_F_LEN=0x20000
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_SPL=y
+CONFIG_SYS_BOOTCOUNT_SINGLEWORD=y
+CONFIG_ARCH_MTMIPS=y
+CONFIG_BOARD_VOCORE2=y
+CONFIG_RESTORE_EXCEPTION_VECTOR_BASE=y
+CONFIG_MIPS_BOOT_FDT=y
+CONFIG_ENV_VARS_UBOOT_CONFIG=y
+CONFIG_SYS_BOOT_GET_CMDLINE=y
+CONFIG_SYS_BOOT_GET_KBD=y
+CONFIG_FIT=y
+CONFIG_FIT_SIGNATURE=y
+CONFIG_LEGACY_IMAGE_FORMAT=y
+CONFIG_OF_STDOUT_VIA_ALIAS=y
+CONFIG_LOGLEVEL=8
+CONFIG_VERSION_VARIABLE=y
+# CONFIG_DISPLAY_BOARDINFO is not set
+CONFIG_DISPLAY_BOARDINFO_LATE=y
+CONFIG_SPL_SYS_MALLOC_SIMPLE=y
+CONFIG_SPL_NOR_SUPPORT=y
+CONFIG_HUSH_PARSER=y
+CONFIG_CMD_LICENSE=y
+# CONFIG_BOOTM_NETBSD is not set
+# CONFIG_BOOTM_PLAN9 is not set
+# CONFIG_BOOTM_RTEMS is not set
+# CONFIG_BOOTM_VXWORKS is not set
+# CONFIG_CMD_ELF is not set
+# CONFIG_CMD_XIMG is not set
+# CONFIG_CMD_CRC32 is not set
+CONFIG_CMD_MEMINFO=y
+# CONFIG_CMD_FLASH is not set
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_GPT=y
+CONFIG_CMD_GPT_RENAME=y
+# CONFIG_CMD_LOADS is not set
+CONFIG_CMD_MMC=y
+CONFIG_CMD_MTD=y
+CONFIG_CMD_PART=y
+CONFIG_CMD_SPI=y
+CONFIG_CMD_USB=y
+CONFIG_CMD_WDT=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_MII=y
+CONFIG_CMD_PING=y
+CONFIG_CMD_BOOTCOUNT=y
+CONFIG_CMD_TIME=y
+CONFIG_CMD_FAT=y
+CONFIG_CMD_FS_GENERIC=y
+CONFIG_CMD_MTDPARTS=y
+CONFIG_MTDIDS_DEFAULT="nor0=spi0.0"
+CONFIG_MTDPARTS_DEFAULT="spi0.0:312k(u-boot),4k(env),4k(factory),2368k(kernel),-(filesystem)"
+CONFIG_DEFAULT_DEVICE_TREE="vocore_vocore2"
+CONFIG_ENV_IS_IN_SPI_FLASH=y
+CONFIG_SYS_RELOC_GD_ENV_ADDR=y
+CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
+CONFIG_NET_RANDOM_ETHADDR=y
+CONFIG_SPL_DM=y
+# CONFIG_DM_DEVICE_REMOVE is not set
+CONFIG_BOOTCOUNT_LIMIT=y
+CONFIG_LED=y
+CONFIG_LED_BLINK=y
+CONFIG_LED_GPIO=y
+CONFIG_MMC=y
+CONFIG_DM_MMC=y
+# CONFIG_MMC_HW_PARTITIONING is not set
+CONFIG_MMC_MTK=y
+CONFIG_MTD=y
+CONFIG_SPI_FLASH_SFDP_SUPPORT=y
+CONFIG_SPI_FLASH_GIGADEVICE=y
+CONFIG_SPI_FLASH_MACRONIX=y
+CONFIG_SPI_FLASH_SPANSION=y
+CONFIG_SPI_FLASH_STMICRO=y
+CONFIG_SPI_FLASH_WINBOND=y
+CONFIG_SPI_FLASH_MTD=y
+CONFIG_MT7628_ETH=y
+CONFIG_PHY=y
+CONFIG_MT76X8_USB_PHY=y
+CONFIG_SPECIFY_CONSOLE_INDEX=y
+CONFIG_CONS_INDEX=3
+CONFIG_SPI=y
+CONFIG_MT7621_SPI=y
+CONFIG_USB=y
+CONFIG_DM_USB=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_GENERIC=y
+CONFIG_USB_STORAGE=y
+CONFIG_WDT=y
+CONFIG_WDT_MT7621=y
+CONFIG_FS_EXT4=y
+CONFIG_FAT_WRITE=y
+CONFIG_LZMA=y
+CONFIG_LZO=y
+CONFIG_SPL_LZMA=y
diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
index 5232328e1e4..7bdebf58699 100644
--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
@@ -2714,6 +2714,14 @@ int brcmnand_probe(struct udevice *dev, struct brcmnand_soc *soc)
}
#endif /* __UBOOT__ */
+ /* No chip-selects could initialize properly */
+ if (list_empty(&ctrl->host_list)) {
+ ret = -ENODEV;
+ goto err;
+ }
+
+ return 0;
+
err:
#ifndef __UBOOT__
clk_disable_unprepare(ctrl->clk);
@@ -2722,7 +2730,6 @@ err:
clk_disable(ctrl->clk);
#endif /* __UBOOT__ */
return ret;
-
}
EXPORT_SYMBOL_GPL(brcmnand_probe);
diff --git a/drivers/sysreset/Kconfig b/drivers/sysreset/Kconfig
index f09e138bb8c..4be74334047 100644
--- a/drivers/sysreset/Kconfig
+++ b/drivers/sysreset/Kconfig
@@ -101,6 +101,12 @@ config SYSRESET_WATCHDOG
help
Reboot support for generic watchdog reset.
+config SYSRESET_RESETCTL
+ bool "Enable support for reset controller reboot driver"
+ select DM_RESET
+ help
+ Reboot support using generic reset controller.
+
config SYSRESET_X86
bool "Enable support for x86 processor reboot driver"
depends on X86
diff --git a/drivers/sysreset/Makefile b/drivers/sysreset/Makefile
index 51af68fad3b..3ed4bab9e37 100644
--- a/drivers/sysreset/Makefile
+++ b/drivers/sysreset/Makefile
@@ -16,5 +16,6 @@ obj-$(CONFIG_SYSRESET_SOCFPGA_S10) += sysreset_socfpga_s10.o
obj-$(CONFIG_SYSRESET_TI_SCI) += sysreset-ti-sci.o
obj-$(CONFIG_SYSRESET_SYSCON) += sysreset_syscon.o
obj-$(CONFIG_SYSRESET_WATCHDOG) += sysreset_watchdog.o
+obj-$(CONFIG_SYSRESET_RESETCTL) += sysreset_resetctl.o
obj-$(CONFIG_$(SPL_TPL_)SYSRESET_X86) += sysreset_x86.o
obj-$(CONFIG_TARGET_XTFPGA) += sysreset_xtfpga.o
diff --git a/drivers/sysreset/sysreset_resetctl.c b/drivers/sysreset/sysreset_resetctl.c
new file mode 100644
index 00000000000..b8203ba6059
--- /dev/null
+++ b/drivers/sysreset/sysreset_resetctl.c
@@ -0,0 +1,48 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 MediaTek Inc.
+ *
+ * Author: Weijie Gao <weijie.gao@mediatek.com>
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <sysreset.h>
+#include <reset.h>
+
+struct resetctl_reboot_priv {
+ struct reset_ctl_bulk resets;
+};
+
+static int resetctl_reboot_request(struct udevice *dev, enum sysreset_t type)
+{
+ struct resetctl_reboot_priv *priv = dev_get_priv(dev);
+
+ return reset_assert_bulk(&priv->resets);
+}
+
+static struct sysreset_ops resetctl_reboot_ops = {
+ .request = resetctl_reboot_request,
+};
+
+int resetctl_reboot_probe(struct udevice *dev)
+{
+ struct resetctl_reboot_priv *priv = dev_get_priv(dev);
+
+ return reset_get_bulk(dev, &priv->resets);
+}
+
+static const struct udevice_id resetctl_reboot_ids[] = {
+ { .compatible = "resetctl-reboot" },
+ { }
+};
+
+U_BOOT_DRIVER(resetctl_reboot) = {
+ .id = UCLASS_SYSRESET,
+ .name = "resetctl_reboot",
+ .of_match = resetctl_reboot_ids,
+ .ops = &resetctl_reboot_ops,
+ .priv_auto_alloc_size = sizeof(struct resetctl_reboot_priv),
+ .probe = resetctl_reboot_probe,
+};
diff --git a/include/configs/bmips_bcm6318.h b/include/configs/bmips_bcm6318.h
index c7e7119aafd..45eb931c257 100644
--- a/include/configs/bmips_bcm6318.h
+++ b/include/configs/bmips_bcm6318.h
@@ -19,7 +19,9 @@
#define CONFIG_EHCI_MMIO_BIG_ENDIAN
#define CONFIG_SYS_OHCI_SWAP_REG_ACCESS
#define CONFIG_SYS_USB_OHCI_MAX_ROOT_PORTS 2
+#if defined(CONFIG_USB_OHCI_HCD)
#define CONFIG_USB_OHCI_NEW
+#endif /* CONFIG_USB_OHCI_HCD */
/* U-Boot */
#define CONFIG_SYS_LOAD_ADDR CONFIG_SYS_SDRAM_BASE + SZ_1M
diff --git a/include/configs/bmips_bcm63268.h b/include/configs/bmips_bcm63268.h
index 45f26bb3097..eed321eb6fc 100644
--- a/include/configs/bmips_bcm63268.h
+++ b/include/configs/bmips_bcm63268.h
@@ -19,7 +19,9 @@
#define CONFIG_EHCI_MMIO_BIG_ENDIAN
#define CONFIG_SYS_OHCI_SWAP_REG_ACCESS
#define CONFIG_SYS_USB_OHCI_MAX_ROOT_PORTS 2
+#if defined(CONFIG_USB_OHCI_HCD)
#define CONFIG_USB_OHCI_NEW
+#endif /* CONFIG_USB_OHCI_HCD */
/* U-Boot */
#define CONFIG_SYS_LOAD_ADDR CONFIG_SYS_SDRAM_BASE + SZ_1M
diff --git a/include/configs/bmips_bcm6328.h b/include/configs/bmips_bcm6328.h
index 8d594387853..c78099a49dc 100644
--- a/include/configs/bmips_bcm6328.h
+++ b/include/configs/bmips_bcm6328.h
@@ -19,7 +19,9 @@
#define CONFIG_EHCI_MMIO_BIG_ENDIAN
#define CONFIG_SYS_OHCI_SWAP_REG_ACCESS
#define CONFIG_SYS_USB_OHCI_MAX_ROOT_PORTS 2
+#if defined(CONFIG_USB_OHCI_HCD)
#define CONFIG_USB_OHCI_NEW
+#endif /* CONFIG_USB_OHCI_HCD */
/* U-Boot */
#define CONFIG_SYS_LOAD_ADDR CONFIG_SYS_SDRAM_BASE + SZ_1M
diff --git a/include/configs/bmips_bcm6348.h b/include/configs/bmips_bcm6348.h
index 061d6b25b71..547cf857ceb 100644
--- a/include/configs/bmips_bcm6348.h
+++ b/include/configs/bmips_bcm6348.h
@@ -17,7 +17,9 @@
/* USB */
#define CONFIG_SYS_OHCI_SWAP_REG_ACCESS
#define CONFIG_SYS_USB_OHCI_MAX_ROOT_PORTS 2
+#if defined(CONFIG_USB_OHCI_HCD)
#define CONFIG_USB_OHCI_NEW
+#endif /* CONFIG_USB_OHCI_HCD */
/* U-Boot */
#define CONFIG_SYS_LOAD_ADDR CONFIG_SYS_SDRAM_BASE + SZ_1M
diff --git a/include/configs/bmips_bcm6358.h b/include/configs/bmips_bcm6358.h
index 583217d2621..116e9705b6b 100644
--- a/include/configs/bmips_bcm6358.h
+++ b/include/configs/bmips_bcm6358.h
@@ -19,7 +19,9 @@
#define CONFIG_EHCI_MMIO_BIG_ENDIAN
#define CONFIG_SYS_OHCI_SWAP_REG_ACCESS
#define CONFIG_SYS_USB_OHCI_MAX_ROOT_PORTS 2
+#if defined(CONFIG_USB_OHCI_HCD)
#define CONFIG_USB_OHCI_NEW
+#endif /* CONFIG_USB_OHCI_HCD */
/* U-Boot */
#define CONFIG_SYS_LOAD_ADDR CONFIG_SYS_SDRAM_BASE + SZ_1M
diff --git a/include/configs/bmips_bcm6362.h b/include/configs/bmips_bcm6362.h
index 570bc3b33d3..e5e8b15e187 100644
--- a/include/configs/bmips_bcm6362.h
+++ b/include/configs/bmips_bcm6362.h
@@ -19,7 +19,9 @@
#define CONFIG_EHCI_MMIO_BIG_ENDIAN
#define CONFIG_SYS_OHCI_SWAP_REG_ACCESS
#define CONFIG_SYS_USB_OHCI_MAX_ROOT_PORTS 2
+#if defined(CONFIG_USB_OHCI_HCD)
#define CONFIG_USB_OHCI_NEW
+#endif /* CONFIG_USB_OHCI_HCD */
/* U-Boot */
#define CONFIG_SYS_LOAD_ADDR CONFIG_SYS_SDRAM_BASE + SZ_1M
diff --git a/include/configs/bmips_bcm6368.h b/include/configs/bmips_bcm6368.h
index ab5bdac7268..4d4403f8d21 100644
--- a/include/configs/bmips_bcm6368.h
+++ b/include/configs/bmips_bcm6368.h
@@ -19,7 +19,9 @@
#define CONFIG_EHCI_MMIO_BIG_ENDIAN
#define CONFIG_SYS_OHCI_SWAP_REG_ACCESS
#define CONFIG_SYS_USB_OHCI_MAX_ROOT_PORTS 2
+#if defined(CONFIG_USB_OHCI_HCD)
#define CONFIG_USB_OHCI_NEW
+#endif /* CONFIG_USB_OHCI_HCD */
/* U-Boot */
#define CONFIG_SYS_LOAD_ADDR CONFIG_SYS_SDRAM_BASE + SZ_1M
diff --git a/include/configs/gardena-smart-gateway-mt7688.h b/include/configs/gardena-smart-gateway-mt7688.h
index 59c60743d24..6412efcbf88 100644
--- a/include/configs/gardena-smart-gateway-mt7688.h
+++ b/include/configs/gardena-smart-gateway-mt7688.h
@@ -16,10 +16,29 @@
#define CONFIG_SYS_INIT_SP_OFFSET 0x400000
-#ifdef CONFIG_BOOT_RAM
+/* SPL */
+#if defined(CONFIG_SPL) && !defined(CONFIG_SPL_BUILD)
#define CONFIG_SKIP_LOWLEVEL_INIT
#endif
+#define CONFIG_SYS_UBOOT_START CONFIG_SYS_TEXT_BASE
+#define CONFIG_SPL_BSS_START_ADDR 0x80010000
+#define CONFIG_SPL_BSS_MAX_SIZE 0x10000
+#define CONFIG_SPL_MAX_SIZE 0x10000
+#define CONFIG_SPL_PAD_TO 0
+
+/* Dummy value */
+#define CONFIG_SYS_UBOOT_BASE 0
+
+/* Serial SPL */
+#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_SERIAL_SUPPORT)
+#define CONFIG_SYS_NS16550_MEM32
+#define CONFIG_SYS_NS16550_CLK 40000000
+#define CONFIG_SYS_NS16550_REG_SIZE -4
+#define CONFIG_SYS_NS16550_COM1 0xb0000c00
+#define CONFIG_CONS_INDEX 1
+#endif
+
/* UART */
#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200, \
230400, 460800, 921600 }
diff --git a/include/configs/linkit-smart-7688.h b/include/configs/linkit-smart-7688.h
index ca5b693e4cc..4276e95dee2 100644
--- a/include/configs/linkit-smart-7688.h
+++ b/include/configs/linkit-smart-7688.h
@@ -16,10 +16,30 @@
#define CONFIG_SYS_INIT_SP_OFFSET 0x400000
-#ifdef CONFIG_BOOT_RAM
+/* SPL */
+#if defined(CONFIG_SPL) && !defined(CONFIG_SPL_BUILD)
#define CONFIG_SKIP_LOWLEVEL_INIT
#endif
+#define CONFIG_SYS_UBOOT_START CONFIG_SYS_TEXT_BASE
+#define CONFIG_SPL_BSS_START_ADDR 0x80010000
+#define CONFIG_SPL_BSS_MAX_SIZE 0x10000
+#define CONFIG_SPL_MAX_SIZE 0x10000
+#define CONFIG_SPL_PAD_TO 0
+
+/* Dummy value */
+#define CONFIG_SYS_UBOOT_BASE 0
+
+/* Serial SPL */
+#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_SERIAL_SUPPORT)
+#define CONFIG_SYS_NS16550_MEM32
+#define CONFIG_SYS_NS16550_CLK 40000000
+#define CONFIG_SYS_NS16550_REG_SIZE -4
+#define CONFIG_SYS_NS16550_COM3 0xb0000e00
+#define CONFIG_CONS_INDEX 3
+
+#endif
+
/* UART */
#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200, \
230400, 460800, 921600 }
diff --git a/include/configs/mt7628.h b/include/configs/mt7628.h
new file mode 100644
index 00000000000..9b9218d2967
--- /dev/null
+++ b/include/configs/mt7628.h
@@ -0,0 +1,56 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (C) 2020 MediaTek Inc.
+ *
+ * Author: Weijie Gao <weijie.gao@mediatek.com>
+ */
+
+#ifndef __CONFIG_MT7628_H
+#define __CONFIG_MT7628_H
+
+#define CONFIG_SYS_HZ 1000
+#define CONFIG_SYS_MIPS_TIMER_FREQ 290000000
+
+#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE
+
+#define CONFIG_SYS_MALLOC_LEN 0x100000
+#define CONFIG_SYS_BOOTPARAMS_LEN 0x20000
+
+#define CONFIG_SYS_SDRAM_BASE 0x80000000
+#define CONFIG_SYS_LOAD_ADDR 0x80010000
+
+#define CONFIG_SYS_INIT_SP_OFFSET 0x80000
+
+#define CONFIG_SYS_BOOTM_LEN 0x1000000
+
+#define CONFIG_SYS_MAXARGS 16
+#define CONFIG_SYS_CBSIZE 1024
+
+/* Serial SPL */
+#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_SERIAL_SUPPORT)
+#define CONFIG_SYS_NS16550_MEM32
+#define CONFIG_SYS_NS16550_CLK 40000000
+#define CONFIG_SYS_NS16550_REG_SIZE -4
+#define CONFIG_SYS_NS16550_COM1 0xb0000c00
+#define CONFIG_CONS_INDEX 1
+#endif
+
+/* Serial common */
+#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200, \
+ 230400, 460800, 921600 }
+
+/* SPL */
+#if defined(CONFIG_SPL) && !defined(CONFIG_SPL_BUILD)
+#define CONFIG_SKIP_LOWLEVEL_INIT
+#endif
+
+#define CONFIG_SYS_UBOOT_START CONFIG_SYS_TEXT_BASE
+#define CONFIG_SPL_BSS_START_ADDR 0x80010000
+#define CONFIG_SPL_BSS_MAX_SIZE 0x10000
+#define CONFIG_SPL_MAX_SIZE 0x10000
+#define CONFIG_SPL_PAD_TO 0
+
+/* Dummy value */
+#define CONFIG_SYS_UBOOT_BASE 0
+
+#endif /* __CONFIG_MT7628_H */
diff --git a/include/configs/vocore2.h b/include/configs/vocore2.h
new file mode 100644
index 00000000000..8100e4dca7b
--- /dev/null
+++ b/include/configs/vocore2.h
@@ -0,0 +1,54 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2019 Mauro Condarelli <mc5686@mclink.it>
+ */
+
+#ifndef __VOCORE2_CONFIG_H__
+#define __VOCORE2_CONFIG_H__
+
+/* CPU */
+#define CONFIG_SYS_MIPS_TIMER_FREQ 290000000
+
+/* RAM */
+#define CONFIG_SYS_SDRAM_BASE 0x80000000
+
+#define CONFIG_SYS_LOAD_ADDR CONFIG_SYS_SDRAM_BASE + 0x100000
+
+#define CONFIG_SYS_INIT_SP_OFFSET 0x400000
+
+/* SPL */
+#if defined(CONFIG_SPL) && !defined(CONFIG_SPL_BUILD)
+#define CONFIG_SKIP_LOWLEVEL_INIT
+#endif
+
+#define CONFIG_SYS_UBOOT_START CONFIG_SYS_TEXT_BASE
+#define CONFIG_SPL_BSS_START_ADDR 0x80010000
+#define CONFIG_SPL_BSS_MAX_SIZE 0x10000
+#define CONFIG_SPL_MAX_SIZE 0x10000
+
+/* Dummy value */
+#define CONFIG_SYS_UBOOT_BASE 0
+
+/* Serial SPL */
+#define CONFIG_SYS_NS16550_MEM32
+#define CONFIG_SYS_NS16550_CLK 40000000
+#define CONFIG_SYS_NS16550_REG_SIZE -4
+#define CONFIG_SYS_NS16550_COM3 0xb0000e00
+#define CONFIG_CONS_INDEX 3
+
+/* RAM */
+#define CONFIG_SYS_MEMTEST_START 0x80100000
+#define CONFIG_SYS_MEMTEST_END 0x80400000
+
+/* Memory usage */
+#define CONFIG_SYS_MAXARGS 64
+#define CONFIG_SYS_MALLOC_LEN (1024 * 1024)
+#define CONFIG_SYS_BOOTPARAMS_LEN (128 * 1024)
+#define CONFIG_SYS_CBSIZE 512
+
+/* U-Boot */
+#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE
+
+/* Environment settings */
+
+#endif //__VOCORE2_CONFIG_H__
diff --git a/include/spl.h b/include/spl.h
index 8b15cd4914c..6bf9fd8bebb 100644
--- a/include/spl.h
+++ b/include/spl.h
@@ -224,6 +224,19 @@ int spl_load_simple_fit(struct spl_image_info *spl_image,
#define SPL_FIT_FOUND 2
/**
+ * spl_load_legacy_img() - Loads a legacy image from a device.
+ * @spl_image: Image description to set up
+ * @load: Structure containing the information required to load data.
+ * @header: Pointer to image header (including appended image)
+ *
+ * Reads an legacy image from the device. Loads u-boot image to
+ * specified load address.
+ * Returns 0 on success.
+ */
+int spl_load_legacy_img(struct spl_image_info *spl_image,
+ struct spl_load_info *load, ulong header);
+
+/**
* spl_load_imx_container() - Loads a imx container image from a device.
* @spl_image: Image description to set up
* @info: Structure containing the information required to load data.
diff --git a/lib/Kconfig b/lib/Kconfig
index 144a54da280..868de3bf3b8 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -434,6 +434,11 @@ config SPL_LZ4
fast compression and decompression speed. It belongs to the LZ77
family of byte-oriented compression schemes.
+config SPL_LZMA
+ bool "Enable LZMA decompression support for SPL build"
+ help
+ This enables support for LZMA compression altorithm for SPL boot.
+
config SPL_LZO
bool "Enable LZO decompression support in SPL"
help
diff --git a/lib/Makefile b/lib/Makefile
index ded9a932aa0..c6f862b0c22 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -67,6 +67,7 @@ obj-$(CONFIG_$(SPL_)ZLIB) += zlib/
obj-$(CONFIG_$(SPL_)ZSTD) += zstd/
obj-$(CONFIG_$(SPL_)GZIP) += gunzip.o
obj-$(CONFIG_$(SPL_)LZO) += lzo/
+obj-$(CONFIG_$(SPL_)LZMA) += lzma/
obj-$(CONFIG_$(SPL_)LZ4) += lz4_wrapper.o
obj-$(CONFIG_LIBAVB) += libavb/