[PATCH v2 19/21] mips: mtmips: add SPL support

Stefan Roese sr at denx.de
Fri Jan 17 15:58:31 CET 2020


On 17.01.20 14:15, Daniel Schwierzeck wrote:
> 
> 
> Am 17.01.20 um 08:46 schrieb Weijie Gao:
>> This patch adds SPL support for mtmips platform. The lowlevel architecture
>> is split into SPL and the rest parts are built into a memory loadable
>> u-boot image. Optional SPL_DM and OF_CONTROL are also supported.
>>
>> The increment of size is very small (< 10 KiB) if SPL_DM and OF_CONTROL are
>> not enabled and the memory bootable u-boot (u-boot.img) is generated
>> automatically so there is not need to add a separate config for it.
>>
>> A lzma compressed payload (u-boot-lzma.img) is also generated and it will
>> be combined with u-boot-spl.bin to form the unified ROM bootable binary
>> u-boot-mtmips.bin.
>>
>> A spl loader is added to support uncompress the payload.
>>
>> Signed-off-by: Weijie Gao <weijie.gao at mediatek.com>
>> ---
>> Changes since v1:
>>    move spl loader into this patch.
>>    add full pinmux for all three uarts.
>>    add optional DM & DT support.
>> ---
>>   Makefile                                    |   9 ++
>>   arch/mips/Kconfig                           |   3 +
>>   arch/mips/dts/mt7628-u-boot.dtsi            |  24 ++++
>>   arch/mips/mach-mtmips/Kconfig               |  24 ++++
>>   arch/mips/mach-mtmips/Makefile              |   1 +
>>   arch/mips/mach-mtmips/include/mach/serial.h |  13 +++
>>   arch/mips/mach-mtmips/include/mach/spl.h    |  14 +++
>>   arch/mips/mach-mtmips/mt7628/Makefile       |   1 +
>>   arch/mips/mach-mtmips/mt7628/serial.c       |  34 ++++++
>>   arch/mips/mach-mtmips/spl.c                 |  31 +++++
>>   arch/mips/mach-mtmips/spl_load.c            | 121 ++++++++++++++++++++
>>   11 files changed, 275 insertions(+)
>>   create mode 100644 arch/mips/dts/mt7628-u-boot.dtsi
>>   create mode 100644 arch/mips/mach-mtmips/include/mach/serial.h
>>   create mode 100644 arch/mips/mach-mtmips/include/mach/spl.h
>>   create mode 100644 arch/mips/mach-mtmips/mt7628/serial.c
>>   create mode 100644 arch/mips/mach-mtmips/spl.c
>>   create mode 100644 arch/mips/mach-mtmips/spl_load.c
>>
>> diff --git a/Makefile b/Makefile
>> index 8013cbd9f9..1e18a37913 100644
>> --- a/Makefile
>> +++ b/Makefile
>> @@ -895,6 +895,7 @@ ALL-$(CONFIG_OF_SEPARATE) += u-boot-dtb-tegra.bin
>>   endif
>>   
>>   ALL-$(CONFIG_ARCH_MEDIATEK) += u-boot-mtk.bin
>> +ALL-$(CONFIG_ARCH_MTMIPS) += u-boot-mtmips.bin
>>   
>>   # Add optional build target if defined in board/cpu/soc headers
>>   ifneq ($(CONFIG_BUILD_TARGET),)
>> @@ -1664,6 +1665,14 @@ u-boot-mtk.bin: u-boot.bin FORCE
>>   	$(call if_changed,mkimage)
>>   endif
>>   
>> +ifeq ($(CONFIG_SPL),y)
>> +u-boot-mtmips.bin: u-boot.dtb u-boot-lzma.img spl/u-boot-spl.bin FORCE
>> +	$(call if_changed,binman)
>> +else
>> +u-boot-mtmips.bin: u-boot.bin FORCE
>> +	$(call if_changed,copy)
>> +endif
>> +
>>   ARCH_POSTLINK := $(wildcard $(srctree)/arch/$(ARCH)/Makefile.postlink)
>>   
>>   # Rule to link u-boot
>> diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
>> index 5f82caf8be..5f74f549b5 100644
>> --- a/arch/mips/Kconfig
>> +++ b/arch/mips/Kconfig
>> @@ -98,6 +98,9 @@ config ARCH_MTMIPS
>>   	select SUPPORTS_CPU_MIPS32_R2
>>   	select SUPPORTS_LITTLE_ENDIAN
>>   	select SYSRESET
>> +	select SUPPORT_SPL
>> +	select SPL_LZMA
>> +	select BINMAN
>>   
>>   config ARCH_JZ47XX
>>   	bool "Support Ingenic JZ47xx"
>> diff --git a/arch/mips/dts/mt7628-u-boot.dtsi b/arch/mips/dts/mt7628-u-boot.dtsi
>> new file mode 100644
>> index 0000000000..213959105f
>> --- /dev/null
>> +++ b/arch/mips/dts/mt7628-u-boot.dtsi
>> @@ -0,0 +1,24 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/*
>> + * Copyright (C) 2020 MediaTek Inc.
>> + *
>> + * Author: Weijie Gao <weijie.gao at mediatek.com>
>> + */
>> +
>> +/ {
>> +	binman {
>> +		filename = "u-boot-mtmips.bin";
>> +		pad-byte = <0xff>;
>> +
>> +#ifdef CONFIG_SPL
>> +		u-boot-spl {
>> +		};
>> +
>> +		u-boot-lzma-img {
>> +		};
>> +#else
>> +		u-boot {
>> +		};
>> +#endif
>> +	};
>> +};
>> diff --git a/arch/mips/mach-mtmips/Kconfig b/arch/mips/mach-mtmips/Kconfig
>> index 3f25de8b85..9b42d5b581 100644
>> --- a/arch/mips/mach-mtmips/Kconfig
>> +++ b/arch/mips/mach-mtmips/Kconfig
>> @@ -20,8 +20,16 @@ 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_LOADER_SUPPORT
>> +	bool
>> +	default y
>> +
> 
> this option should be moved to arch/mips/Kconfig and should be added
> with patch 15/21 because you use reference that option in the generic
> MIPS u-boot-spl.lds
> 
>>   choice
>>   	prompt "MediaTek MIPS SoC select"
>>   
>> @@ -34,6 +42,14 @@ config SOC_MT7628
>>   	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_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.
>>   
>> @@ -88,6 +104,14 @@ endchoice
>>   config SUPPORTS_BOOT_RAM
>>   	bool
>>   
>> +config SPL_UART2_SPIS_PINMUX
>> +	bool "Use alternative pinmux for UART2 in SPL stage"
>> +	depends on SPL_SERIAL_SUPPORT
>> +	default n
>> +	help
>> +	  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/seeed/linkit-smart-7688/Kconfig"
>>   
>> diff --git a/arch/mips/mach-mtmips/Makefile b/arch/mips/mach-mtmips/Makefile
>> index 72f0369030..08d2a236d0 100644
>> --- a/arch/mips/mach-mtmips/Makefile
>> +++ b/arch/mips/mach-mtmips/Makefile
>> @@ -3,5 +3,6 @@
>>   obj-y += cpu.o
>>   obj-y += ddr_init.o
>>   obj-y += ddr_cal.o
>> +obj-$(CONFIG_SPL_BUILD) += spl.o spl_load.o
>>   
>>   obj-$(CONFIG_SOC_MT7628) += mt7628/
>> 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 0000000000..bfa246b428
>> --- /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 at 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/include/mach/spl.h b/arch/mips/mach-mtmips/include/mach/spl.h
>> new file mode 100644
>> index 0000000000..5674dd533e
>> --- /dev/null
>> +++ b/arch/mips/mach-mtmips/include/mach/spl.h
>> @@ -0,0 +1,14 @@
>> +/* SPDX-License-Identifier: GPL-2.0 */
>> +/*
>> + * Copyright (C) 2020 MediaTek Inc. All Rights Reserved.
>> + *
>> + * Author: Weijie Gao <weijie.gao at mediatek.com>
>> + */
>> +#ifndef	_MACH_MTMIPS_SPL_H_
>> +#define	_MACH_MTMIPS_SPL_H_
>> +
>> +#include <asm/spl.h>
>> +
>> +#define BOOT_DEVICE_MTMIPS_NOR	(BOOT_DEVICE_BOOTROM + 0x100)
>> +
>> +#endif /* _MACH_MTMIPS_SPL_H_ */
>> diff --git a/arch/mips/mach-mtmips/mt7628/Makefile b/arch/mips/mach-mtmips/mt7628/Makefile
>> index db62e90d77..7e139d5adf 100644
>> --- a/arch/mips/mach-mtmips/mt7628/Makefile
>> +++ b/arch/mips/mach-mtmips/mt7628/Makefile
>> @@ -3,3 +3,4 @@
>>   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/serial.c b/arch/mips/mach-mtmips/mt7628/serial.c
>> new file mode 100644
>> index 0000000000..a7d324792d
>> --- /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 at 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/spl.c b/arch/mips/mach-mtmips/spl.c
>> new file mode 100644
>> index 0000000000..f12fb70d75
>> --- /dev/null
>> +++ b/arch/mips/mach-mtmips/spl.c
>> @@ -0,0 +1,31 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/*
>> + * Copyright (C) 2020 MediaTek Inc. All Rights Reserved.
>> + *
>> + * Author: Weijie Gao <weijie.gao at mediatek.com>
>> + */
>> +
>> +#include <common.h>
>> +#include <spl.h>
>> +#include <linux/sizes.h>
>> +#include <mach/serial.h>
>> +#include <mach/spl.h>
>> +
>> +DECLARE_GLOBAL_DATA_PTR;
>> +
>> +void __noreturn board_init_f(ulong dummy)
>> +{
>> +	spl_init();
>> +
>> +#ifdef CONFIG_SPL_SERIAL_SUPPORT
>> +	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_MTMIPS_NOR;
>> +}
>> diff --git a/arch/mips/mach-mtmips/spl_load.c b/arch/mips/mach-mtmips/spl_load.c
>> new file mode 100644
>> index 0000000000..95dd491baa
>> --- /dev/null
>> +++ b/arch/mips/mach-mtmips/spl_load.c
>> @@ -0,0 +1,121 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/*
>> + * Copyright (C) 2020 MediaTek Inc. All Rights Reserved.
>> + *
>> + * Author: Weijie Gao <weijie.gao at mediatek.com>
>> + */
>> +
>> +#include <common.h>
>> +#include <cpu_func.h>
>> +#include <asm/sections.h>
>> +#include <linux/compiler.h>
>> +#include <linux/sizes.h>
>> +#include <mach/spl.h>
>> +#include <spl.h>
>> +
>> +#ifdef CONFIG_SPL_LZMA
>> +#include <lzma/LzmaTypes.h>
>> +#include <lzma/LzmaDec.h>
>> +#include <lzma/LzmaTools.h>
>> +#endif /* CONFIG_SPL_LZMA */
>> +
>> +#if CONFIG_IS_ENABLED(OF_CONTROL) && defined(CONFIG_OF_SEPARATE)
>> +#include <fdt.h>
>> +#endif
>> +
>> +static ulong spl_dtb_size(void)
>> +{
>> +#if CONFIG_IS_ENABLED(OF_CONTROL)
>> +	void *fdt = __image_copy_end;
>> +
>> +	if (fdt_magic(fdt) == FDT_MAGIC)
>> +		return fdt_totalsize(fdt);
>> +#endif
>> +
>> +	return 0;
>> +}
>> +
>> +static int spl_try_load_image(struct spl_image_info *spl_image,
>> +			      void *image_addr)
>> +{
>> +	int ret;
>> +	uintptr_t dataptr;
>> +	struct image_header hdr;
>> +	size_t __maybe_unused lzma_len;
>> +
>> +	memcpy(&hdr, (const void *)image_addr, sizeof(hdr));
>> +
>> +	ret = spl_parse_image_header(spl_image, &hdr);
>> +	if (ret)
>> +		return ret;
>> +
>> +	if (!spl_image->entry_point)
>> +		spl_image->entry_point = spl_image->load_addr;
>> +
>> +	dataptr = (uintptr_t)image_addr + sizeof(hdr);
>> +
>> +	switch (hdr.ih_comp) {
>> +	case IH_COMP_NONE:
>> +		/*
>> +		 * Load real U-Boot from its location to its defined location
>> +		 * in SDRAM
>> +		 */
>> +		if (spl_image->load_addr != dataptr) {
>> +			memmove((void *)spl_image->load_addr, (void *)dataptr,
>> +				spl_image->size);
>> +		}
>> +		break;
>> +#ifdef CONFIG_SPL_LZMA
>> +	case IH_COMP_LZMA:
>> +		/*
>> +		 * Uncompress real U-Boot to its defined location in SDRAM
>> +		 */
>> +		lzma_len = SZ_8M;
>> +
>> +		ret = lzmaBuffToBuffDecompress((u8 *)spl_image->load_addr,
>> +					       &lzma_len, (u8 *)dataptr,
>> +					       spl_image->size);
>> +
>> +		if (ret) {
>> +			printf("Error: LZMA uncompression error: %d\n", ret);
>> +			return ret;
>> +		}
>> +
>> +		spl_image->size = lzma_len;
>> +		break;
>> +#endif /* CONFIG_SPL_LZMA */
>> +	default:
>> +		debug("Warning: Unsupported compression method found in image "
>> +		      "header at offset 0x%p\n", image_addr);
>> +		return -EINVAL;
>> +	}
>> +
>> +	flush_cache((unsigned long)spl_image->load_addr, spl_image->size);
>> +
>> +	return 0;
>> +}
>> +
>> +static int spl_mtk_nor_load_image(struct spl_image_info *spl_image,
>> +				  struct spl_boot_device *bootdev)
>> +{
>> +	ulong offset = spl_dtb_size();
>> +
>> +	/*
>> +	 * Loading of the payload to SDRAM is done with skipping of
>> +	 * the mkimage header
>> +	 */
>> +	spl_image->flags |= SPL_COPY_PAYLOAD_ONLY;
>> +
>> +	/* Try to boot without padding */
>> +	if (!spl_try_load_image(spl_image, (u8 *)__image_copy_end + offset))
>> +		return 0;
>> +
>> +#ifdef CONFIG_SYS_UBOOT_BASE
>> +	/* Try user defined offset */
>> +	if (!spl_try_load_image(spl_image, (void *)CONFIG_SYS_UBOOT_BASE))
>> +		return 0;
>> +#endif
>> +
>> +	return -EINVAL;
>> +}
>> +SPL_LOAD_IMAGE_METHOD("NOR", 0, BOOT_DEVICE_MTMIPS_NOR, spl_mtk_nor_load_image);
>>
> 
> maybe in a future patch series this could be refactored to a generic SPL
> decompressor in common/spl/ with spl_nor.c as the first user. Then it
> could be used by other archs or other SPL boot methods like SPI or NAND.

Yes, I fully agree with Daniel. Please move this into the common SPL code
so that it can be used by other platforms as well. This compression is a
great feature that should be generally available.

Thanks,
Stefan


More information about the U-Boot mailing list