[PATCH] imx: imx8mm: Add suppoer for Mettler-Toledo snowflake board.

Frieder Schrempf frieder.schrempf at kontron.de
Thu Mar 16 11:33:47 CET 2023


On 10.03.23 14:50, Sebastian Andrzej Siewior wrote:
> From: Manuel Traut <manuel.traut at mt.com>
> 
> The board is similar to Kontron's N801x design. It lacks external eMMC
> support and only supports only 1GiB of main memory.

Good to see some custom boards being upstreamed!

It would be worth mentioning here that it is based on the "Kontron SL
i.MX8M Mini" SoM, which is the proper name of the product nowadays.

What do you mean by "it lacks external eMMC support"?
There is an eMMC on the SoM, so the hardware does support it.

> 
> [ bigeasy: porting and a bit of cleanup ]
> 
> Signed-off-by: Manuel Traut <manuel.traut at mt.com>
> Signed-off-by: Sebastian Andrzej Siewior <bigeasy at linutronix.de>
> ---
>  arch/arm/dts/Makefile                         |    1 +
>  .../dts/imx8mm-mt-snowflake-v2-u-boot.dtsi    |  116 ++
>  arch/arm/dts/imx8mm-mt-snowflake-v2.dts       |  186 ++
>  arch/arm/mach-imx/imx8m/Kconfig               |    8 +
>  board/mt/snowflake_v2/Kconfig                 |   18 +
>  board/mt/snowflake_v2/MAINTAINERS             |    7 +
>  board/mt/snowflake_v2/Makefile                |    9 +
>  board/mt/snowflake_v2/imximage.cfg            |    8 +
>  board/mt/snowflake_v2/lpddr4_timing.c         | 1844 +++++++++++++++++
>  board/mt/snowflake_v2/snowflake_v2.c          |   32 +
>  board/mt/snowflake_v2/snowflake_v2.env        |   33 +
>  board/mt/snowflake_v2/spl.c                   |  167 ++
>  configs/snowflake_v2_emmcboot_defconfig       |  134 ++
>  include/configs/snowflake_v2.h                |   54 +
>  14 files changed, 2617 insertions(+)
>  create mode 100644 arch/arm/dts/imx8mm-mt-snowflake-v2-u-boot.dtsi
>  create mode 100644 arch/arm/dts/imx8mm-mt-snowflake-v2.dts
>  create mode 100644 board/mt/snowflake_v2/Kconfig
>  create mode 100644 board/mt/snowflake_v2/MAINTAINERS
>  create mode 100644 board/mt/snowflake_v2/Makefile
>  create mode 100644 board/mt/snowflake_v2/imximage.cfg
>  create mode 100644 board/mt/snowflake_v2/lpddr4_timing.c
>  create mode 100644 board/mt/snowflake_v2/snowflake_v2.c
>  create mode 100644 board/mt/snowflake_v2/snowflake_v2.env
>  create mode 100644 board/mt/snowflake_v2/spl.c
>  create mode 100644 configs/snowflake_v2_emmcboot_defconfig
>  create mode 100644 include/configs/snowflake_v2.h
> 
> diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
> index 7a577deb5023d..ba0786064847e 100644
> --- a/arch/arm/dts/Makefile
> +++ b/arch/arm/dts/Makefile
> @@ -964,6 +964,7 @@ dtb-$(CONFIG_ARCH_IMX8M) += \
>  	imx8mm-icore-mx8mm-edimm2.2.dtb \
>  	imx8mm-kontron-bl.dtb \
>  	imx8mm-kontron-bl-osm-s.dtb \
> +	imx8mm-mt-snowflake-v2.dtb \
>  	imx8mm-mx8menlo.dtb \
>  	imx8mm-phg.dtb \
>  	imx8mm-venice.dtb \
> diff --git a/arch/arm/dts/imx8mm-mt-snowflake-v2-u-boot.dtsi b/arch/arm/dts/imx8mm-mt-snowflake-v2-u-boot.dtsi
> new file mode 100644
> index 0000000000000..d6476db292b79
> --- /dev/null
> +++ b/arch/arm/dts/imx8mm-mt-snowflake-v2-u-boot.dtsi
> @@ -0,0 +1,116 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) 2020 Mettler Toledo GmbH
> + */
> +
> +/ {
> +
> +	aliases {
> +		usbgadget0 = &usbg1;
> +	};
> +
> +	usbg1: usbg1 {
> +		u-boot,dm-spl;
> +		compatible = "fsl,imx27-usb-gadget";
> +		dr_mode = "peripheral";
> +		chipidea,usb = <&usbotg1>;
> +		status = "okay";
> +	};
> +
> +	firmware {
> +		optee {
> +			compatible = "linaro,optee-tz";
> +			method = "smc";
> +		};
> +	};
> +};
> +
> +&i2c1 {
> +	status = "okay";
> +	u-boot,dm-spl;
> +	u-boot,dm-pre-reloc;
> +};
> +
> +&i2c2 {
> +	status = "okay";
> +	u-boot,dm-spl;
> +	u-boot,dm-pre-reloc;
> +};
> +
> +&pinctrl_ecspi1 {
> +	u-boot,dm-spl;
> +};
> +
> +&pinctrl_i2c1 {
> +	u-boot,dm-spl;
> +};
> +
> +&pinctrl_pmic {
> +	u-boot,dm-spl;
> +};
> +
> +&pinctrl_uart3 {
> +	u-boot,dm-spl;
> +	u-boot,dm-pre-reloc;
> +};
> +
> +&pinctrl_usdhc1 {
> +	u-boot,dm-spl;
> +};
> +
> +&pinctrl_usdhc1_100mhz {
> +	u-boot,dm-spl;
> +};
> +
> +&pinctrl_usdhc1_200mhz {
> +	u-boot,dm-spl;
> +};
> +
> +&pca9450 {
> +	u-boot,dm-spl;
> +};
> +
> +&{/soc at 0/bus at 30800000/i2c at 30a20000/pmic at 25/regulators} {
> +	u-boot,dm-spl;
> +};
> +
> +&ecspi1 {
> +	u-boot,dm-spl;
> +};
> +
> +&gpio1 {
> +	u-boot,dm-spl;
> +};
> +
> +&gpio2 {
> +	u-boot,dm-spl;
> +};
> +
> +&gpio3 {
> +	u-boot,dm-spl;
> +};
> +
> +&gpio4 {
> +	u-boot,dm-spl;
> +};
> +
> +&gpio5 {
> +	u-boot,dm-spl;
> +};
> +
> +&uart3 {
> +	u-boot,dm-spl;
> +	u-boot,dm-pre-reloc;
> +};
> +
> +&usdhc1 {
> +	u-boot,dm-spl;
> +};
> +
> +&wdog1 {
> +	u-boot,dm-spl;
> +};
> +
> +&pinctrl_wdog {
> +	u-boot,dm-spl;
> +};
> diff --git a/arch/arm/dts/imx8mm-mt-snowflake-v2.dts b/arch/arm/dts/imx8mm-mt-snowflake-v2.dts
> new file mode 100644
> index 0000000000000..49761b22afcf0
> --- /dev/null
> +++ b/arch/arm/dts/imx8mm-mt-snowflake-v2.dts
> @@ -0,0 +1,186 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) 2020 Mettler Toledo GmbH
> + */
> +
> +/dts-v1/;
> +
> +#include "imx8mm-kontron-sl.dtsi"
> +#include "imx8mm-u-boot.dtsi"
> +
> +/ {
> +	model = "Mettler Toledo i.MX8MM Snowflake V2";
> +	compatible = "mt,imx8mm-snowflake-v2", "fsl,imx8mm";

I think the compatible would normally include the SoM:

compatible = "mt,imx8mm-snowflake-v2", "kontron,imx8mm-sl", "fsl,imx8mm";

> +};
> +
> +&i2c1 {
> +	clock-frequency = <400000>;
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_i2c1>;
> +	status = "okay";
> +
> +	pca9450: pmic at 25 {
> +		compatible = "nxp,pca9450a";
> +		reg = <0x25>;
> +		pinctrl-names = "default";
> +		pinctrl-0 = <&pinctrl_pmic>;
> +		interrupt-parent = <&gpio1>;
> +		interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
> +
> +		regulators {
> +			reg_vdd_soc: BUCK1 {
> +				regulator-name = "buck1";
> +				regulator-min-microvolt = <800000>;
> +				regulator-max-microvolt = <850000>;
> +				regulator-boot-on;
> +				regulator-always-on;
> +				regulator-ramp-delay = <3125>;
> +				nxp,dvs-run-voltage = <850000>;
> +				nxp,dvs-standby-voltage = <800000>;
> +			};
> +
> +			reg_vdd_arm: BUCK2 {
> +				regulator-name = "buck2";
> +				regulator-min-microvolt = <850000>;
> +				regulator-max-microvolt = <950000>;
> +				regulator-boot-on;
> +				regulator-always-on;
> +				regulator-ramp-delay = <3125>;
> +				nxp,dvs-run-voltage = <950000>;
> +				nxp,dvs-standby-voltage = <850000>;
> +			};
> +
> +			reg_vdd_dram: BUCK3 {
> +				regulator-name = "buck3";
> +				regulator-min-microvolt = <850000>;
> +				regulator-max-microvolt = <950000>;
> +				regulator-boot-on;
> +				regulator-always-on;
> +			};
> +
> +			reg_vdd_3v3: BUCK4 {
> +				regulator-name = "buck4";
> +				regulator-min-microvolt = <3300000>;
> +				regulator-max-microvolt = <3300000>;
> +				regulator-boot-on;
> +				regulator-always-on;
> +			};
> +
> +			reg_vdd_1v8: BUCK5 {
> +				regulator-name = "buck5";
> +				regulator-min-microvolt = <1800000>;
> +				regulator-max-microvolt = <1800000>;
> +				regulator-boot-on;
> +				regulator-always-on;
> +			};
> +
> +			reg_nvcc_dram: BUCK6 {
> +				regulator-name = "buck6";
> +				regulator-min-microvolt = <1100000>;
> +				regulator-max-microvolt = <1100000>;
> +				regulator-boot-on;
> +				regulator-always-on;
> +			};
> +
> +			reg_nvcc_snvs: LDO1 {
> +				regulator-name = "ldo1";
> +				regulator-min-microvolt = <1800000>;
> +				regulator-max-microvolt = <1800000>;
> +				regulator-boot-on;
> +				regulator-always-on;
> +			};
> +
> +			reg_vdd_snvs: LDO2 {
> +				regulator-name = "ldo2";
> +				regulator-min-microvolt = <800000>;
> +				regulator-max-microvolt = <800000>;
> +				regulator-boot-on;
> +				regulator-always-on;
> +			};
> +
> +			reg_vdda: LDO3 {
> +				regulator-name = "ldo3";
> +				regulator-min-microvolt = <1800000>;
> +				regulator-max-microvolt = <1800000>;
> +				regulator-boot-on;
> +				regulator-always-on;
> +			};
> +
> +			reg_vdd_phy: LDO4 {
> +				regulator-name = "ldo4";
> +				regulator-min-microvolt = <900000>;
> +				regulator-max-microvolt = <900000>;
> +				regulator-boot-on;
> +				regulator-always-on;
> +			};
> +
> +			reg_nvcc_sd: LDO5 {
> +				regulator-name = "ldo5";
> +				regulator-min-microvolt = <1800000>;
> +				regulator-max-microvolt = <3300000>;
> +			};
> +		};
> +	};
> +};

The included SoM DTSI already contains the PMIC node. You can remove
that here. Or if you need to do adjustments for the board level you
should only overwrite what is needed instead of duplicating everything.

> +
> +&usbotg1 {
> +	dr_mode = "peripheral";
> +	status = "okay";
> +};
> +
> +&usbotg2 {
> +	dr_mode = "host";
> +	disable-over-current;
> +	#address-cells = <1>;
> +	#size-cells = <0>;
> +	status = "okay";
> +};
> +
> +&iomuxc {
> +	pinctrl-names = "default";
> +	pinctrl-0 = <&pinctrl_hog>;
> +
> +	pinctrl_hog: hoggrp {
> +		fsl,pins = <
> +			MX8MM_IOMUXC_GPIO1_IO03_GPIO1_IO3		0x19 /* \SOM_RTC_INT */
> +			MX8MM_IOMUXC_GPIO1_IO06_GPIO1_IO6		0x19 /* \SOM_USBC_INT */
> +			MX8MM_IOMUXC_GPIO1_IO09_GPIO1_IO9		0x184 /* SOM_DIS_ID0 */
> +			MX8MM_IOMUXC_GPIO1_IO10_GPIO1_IO10		0x184 /* SOM_DIS_ID1 */
> +			MX8MM_IOMUXC_GPIO1_IO11_GPIO1_IO11		0x184 /* SOM_DIS_ID2 */
> +			MX8MM_IOMUXC_SAI2_TXC_GPIO4_IO25		0x19 /* SOM_PCB_ID0 */
> +			MX8MM_IOMUXC_SAI2_TXD0_GPIO4_IO26		0x19 /* SOM_PCB_ID1 */
> +			MX8MM_IOMUXC_SAI2_MCLK_GPIO4_IO27		0x19 /* SOM_PCBA_ID0 */
> +			MX8MM_IOMUXC_SAI3_RXFS_GPIO4_IO28		0x19 /* SOM_PCBA_ID1 */
> +			MX8MM_IOMUXC_SAI5_RXFS_GPIO3_IO19		0x19 /* \SOM_STATLED_RES */
> +			MX8MM_IOMUXC_SAI5_RXC_GPIO3_IO20		0x19 /* \SOM_HUB_RES */
> +			MX8MM_IOMUXC_SAI5_RXD0_GPIO3_IO21		0x19 /* \SOM_SUPPLY_EN */
> +			MX8MM_IOMUXC_SAI5_RXD1_GPIO3_IO22		0x1c4 /* \SOM_COM_RES / version C */
> +			MX8MM_IOMUXC_SAI5_RXD2_GPIO3_IO23		0x184 /* SOM_DBG_GPIO0 */
> +			MX8MM_IOMUXC_SAI5_RXD3_GPIO3_IO24		0x184 /* SOM_DBG_GPIO1 */
> +			MX8MM_IOMUXC_SAI5_MCLK_GPIO3_IO25		0x184 /* SOM_DBG_GPIO2 */
> +			MX8MM_IOMUXC_SAI3_TXD_GPIO5_IO1			0x184 /* SOM_DBG_GPIO3 version C */
> +		>;
> +	};
> +
> +	pinctrl_sai1: sai1grp {
> +		fsl,pins = <
> +			MX8MM_IOMUXC_SAI1_TXFS_SAI1_TX_SYNC	0xd6
> +			MX8MM_IOMUXC_SAI1_TXC_SAI1_TX_BCLK	0xd6
> +			MX8MM_IOMUXC_SAI1_TXD0_SAI1_TX_DATA0	0xd6
> +		>;
> +	};
> +
> +	pinctrl_i2c1: i2c1grp {
> +		fsl,pins = <
> +			MX8MM_IOMUXC_I2C1_SCL_I2C1_SCL			0x400001c3
> +			MX8MM_IOMUXC_I2C1_SDA_I2C1_SDA			0x400001c3
> +		>;
> +	};

Same here, this node is already available from the SoM DTSI.

> +
> +	pinctrl_i2c4: i2c4grp {
> +		fsl,pins = <
> +			MX8MM_IOMUXC_I2C4_SCL_I2C4_SCL			0x400001c3
> +			MX8MM_IOMUXC_I2C4_SDA_I2C4_SDA			0x400001c3
> +		>;
> +	};
> +};
> diff --git a/arch/arm/mach-imx/imx8m/Kconfig b/arch/arm/mach-imx/imx8m/Kconfig
> index 5e4836b02feb5..a2bb07c8f54c9 100644
> --- a/arch/arm/mach-imx/imx8m/Kconfig
> +++ b/arch/arm/mach-imx/imx8m/Kconfig
> @@ -161,6 +161,13 @@ config TARGET_IMX8MN_DDR4_EVK
>  	select FSL_CAAM
>  	select SPL_CRYPTO if SPL
>  
> +config TARGET_MT_SNOWFLAKE_V2
> +	bool "MT Snowflake v2"
> +	select BINMAN
> +	select IMX8MM
> +	select SUPPORT_SPL
> +	select IMX8M_LPDDR4
> +
>  config TARGET_IMX8MN_VENICE
>  	bool "Support Gateworks Venice iMX8M Nano module"
>  	select BINMAN
> @@ -343,6 +350,7 @@ source "board/kontron/pitx_imx8m/Kconfig"
>  source "board/kontron/sl-mx8mm/Kconfig"
>  source "board/menlo/mx8menlo/Kconfig"
>  source "board/msc/sm2s_imx8mp/Kconfig"
> +source "board/mt/snowflake_v2/Kconfig"
>  source "board/phytec/phycore_imx8mm/Kconfig"
>  source "board/phytec/phycore_imx8mp/Kconfig"
>  source "board/purism/librem5/Kconfig"
> diff --git a/board/mt/snowflake_v2/Kconfig b/board/mt/snowflake_v2/Kconfig
> new file mode 100644
> index 0000000000000..f7c02ba1fbf61
> --- /dev/null
> +++ b/board/mt/snowflake_v2/Kconfig
> @@ -0,0 +1,18 @@
> +if TARGET_MT_SNOWFLAKE_V2
> +
> +config SYS_BOARD
> +	string
> +	default "snowflake_v2"
> +
> +config SYS_VENDOR
> +	string
> +	default "mt"
> +
> +config SYS_CONFIG_NAME
> +	string
> +	default "snowflake_v2"
> +
> +config IMX_CONFIG
> +	default "board/mt/snowflake_v2/imximage.cfg"
> +
> +endif
> diff --git a/board/mt/snowflake_v2/MAINTAINERS b/board/mt/snowflake_v2/MAINTAINERS
> new file mode 100644
> index 0000000000000..e60d24e32f57e
> --- /dev/null
> +++ b/board/mt/snowflake_v2/MAINTAINERS
> @@ -0,0 +1,7 @@
> +Mettler-Toledo Snowflake boards
> +M:	Manuel Traut <manuel.traut at mt.com>
> +S:	Maintained
> +F:	arch/arm/dts/imx8mm-mt-snowflake*
> +F:	board/mt/snowflake_v2
> +F:	configs/snowflake_v2_emmcboot_defconfig
> +F:	include/configs/snowflake_v2.h
> diff --git a/board/mt/snowflake_v2/Makefile b/board/mt/snowflake_v2/Makefile
> new file mode 100644
> index 0000000000000..6ced8f5b3e5ca
> --- /dev/null
> +++ b/board/mt/snowflake_v2/Makefile
> @@ -0,0 +1,9 @@
> +# SPDX-License-Identifier: GPL-2.0
> +# Copyright (C) 2020 Mettler Toledo GmbH
> +
> +obj-y := snowflake_v2.o
> +
> +ifdef CONFIG_SPL_BUILD
> +obj-y += spl.o
> +obj-$(CONFIG_IMX8M_LPDDR4) += lpddr4_timing.o
> +endif
> diff --git a/board/mt/snowflake_v2/imximage.cfg b/board/mt/snowflake_v2/imximage.cfg
> new file mode 100644
> index 0000000000000..20061521f227e
> --- /dev/null
> +++ b/board/mt/snowflake_v2/imximage.cfg
> @@ -0,0 +1,8 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * Copyright 2021 NXP
> + */
> +
> +
> +BOOT_FROM	sd
> +LOADER		u-boot-spl-ddr.bin	0x7E1000
> diff --git a/board/mt/snowflake_v2/lpddr4_timing.c b/board/mt/snowflake_v2/lpddr4_timing.c
> new file mode 100644
> index 0000000000000..6397d9114b5fe
> --- /dev/null
> +++ b/board/mt/snowflake_v2/lpddr4_timing.c
> @@ -0,0 +1,1844 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (C) 2019 Kontron Electronics GmbH
> + */
> +
> +#include <linux/kernel.h>
> +#include <common.h>
> +#include <asm/arch/ddr.h>
> +#include <asm/arch/lpddr4_define.h>
> +
> +struct dram_cfg_param ddr_ddrc_cfg[] = {
> +	/** Initialize DDRC registers **/
> +	{ 0x3d400304, 0x1 },
> +	{ 0x3d400030, 0x1 },

[...]

> diff --git a/board/mt/snowflake_v2/snowflake_v2.c b/board/mt/snowflake_v2/snowflake_v2.c
> new file mode 100644
> index 0000000000000..6510225321a06
> --- /dev/null
> +++ b/board/mt/snowflake_v2/snowflake_v2.c
> @@ -0,0 +1,32 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (C) 2019 Kontron Electronics GmbH
> + * Copyright (C) 2020 Mettler Toledo GmbH
> + */
> +
> +#include <asm/arch/imx-regs.h>
> +#include <asm/global_data.h>
> +#include <asm/io.h>
> +#include <fdt_support.h>
> +#include <linux/arm-smccc.h>
> +#include <linux/errno.h>
> +#include <net.h>
> +
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +int board_phys_sdram_size(phys_size_t *size)
> +{
> +	/* always 1GB RAM */
> +	*size = 0x40000000;
> +	return 0;
> +}
> +
> +int ft_board_setup(void *blob, struct bd_info *bd)
> +{
> +	return fdt_fixup_memory(blob, PHYS_SDRAM, gd->ram_size);
> +}
> +
> +int board_init(void)
> +{
> +	return 0;
> +}
> diff --git a/board/mt/snowflake_v2/snowflake_v2.env b/board/mt/snowflake_v2/snowflake_v2.env
> new file mode 100644
> index 0000000000000..1ad9a2b2e17e7
> --- /dev/null
> +++ b/board/mt/snowflake_v2/snowflake_v2.env
> @@ -0,0 +1,33 @@
> +bootargs_base=console=ttymxc2,115200 vt.global_cursor_default=0 fbcon=font:VGA8x8
> +script=boot.scr
> +bootdir=
> +bootdelay=1
> +bootpart=1
> +bootchooser=run bootchooser_1; run bootchooser_2; run bootchooser_3
> +bootchooser_1=test -n ${BOOT_ORDER} || setenv BOOT_ORDER "system0 system1";
> +                 test -n ${BOOT_system0_LEFT} || setenv BOOT_system0_LEFT 3;
> +                 test -n ${BOOT_system1_LEFT} || setenv BOOT_system1_LEFT 3;
> +                 setenv rauc_slot;
> +bootchooser_2=for BOOT_SLOT in ${BOOT_ORDER}; do if test x${rauc_slot} != x; then;
> +                 elif test x${BOOT_SLOT} = xsystem0; then
> +                 if test ${BOOT_system0_LEFT} -gt 0; then
> +                 echo Found valid slot system0, ${BOOT_system0_LEFT} attempts remaining;
> +                 setexpr BOOT_system0_LEFT ${BOOT_system0_LEFT} - 1;
> +                 setenv bootpart 1; setenv rauc_slot rauc.slot=system0; fi;
> +                 elif test x${BOOT_SLOT} = xsystem1; then
> +                 if test ${BOOT_system1_LEFT} -gt 0; then
> +                 echo Found valid slot system1, ${BOOT_system1_LEFT} attempts remaining;
> +                 setexpr BOOT_system1_LEFT ${BOOT_system1_LEFT} - 1;
> +                 setenv bootpart 2; setenv rauc_slot rauc.slot=system1; fi; fi; done
> +bootchooser_3=if test -n ${rauc_slot}; then saveenv; else
> +                 echo No valid slot found, resetting tries to 3;
> +                 setenv BOOT_system0_LEFT 3; setenv BOOT_system1_LEFT 3;
> +                 saveenv; reset; fi; echo Booting from ${rauc_slot}...;
> +emmcboot=run bootchooser; setenv bootargs ${bootargs_base}
> +                 root=/dev/mmcblk0p${bootpart} ro rootfstype=ext4 rootwait ${rauc_slot};
> +                 echo Booting from eMMC;
> +                 ext4load mmc 0:${bootpart} ${scriptaddr} /boot/fitImage && bootm ${scriptaddr}
> +sdboot=run bootchooser; setenv bootargs ${bootargs_base}
> +                 root=/dev/mmcblk1p${bootpart} ro rootfstype=ext4 rootwait ${rauc_slot};
> +                 echo Booting from SD card;
> +                 ext4load mmc 1:${bootpart} ${scriptaddr} /boot/fitImage && bootm ${scriptaddr}
> diff --git a/board/mt/snowflake_v2/spl.c b/board/mt/snowflake_v2/spl.c
> new file mode 100644
> index 0000000000000..3e27256914b32
> --- /dev/null
> +++ b/board/mt/snowflake_v2/spl.c
> @@ -0,0 +1,167 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (C) 2019 Kontron Electronics GmbH
> + * Copyright (C) 2020 Mettler Toledo GmbH
> + */
> +
> +#include <common.h>
> +#include <spl.h>
> +#include <asm/mach-imx/iomux-v3.h>
> +#include <asm/arch/imx8mm_pins.h>
> +#include <asm/arch/sys_proto.h>
> +#include <asm/arch/clock.h>
> +#include <asm/mach-imx/boot_mode.h>
> +#include <asm/arch/ddr.h>
> +#include <asm/armv8/mmu.h>
> +#include <asm/gpio.h>
> +
> +#include <dm/uclass.h>
> +#include <dm/device.h>
> +#include <dm/uclass-internal.h>
> +#include <dm/device-internal.h>
> +
> +#include <i2c.h>
> +#include <init.h>
> +#include <linux/delay.h>
> +
> +#include <power/pmic.h>
> +#include <power/pca9450.h>
> +
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +int spl_board_boot_device(enum boot_device boot_dev_spl)
> +{
> +	switch (boot_dev_spl) {
> +	case SD1_BOOT:
> +	case MMC1_BOOT:
> +		return BOOT_DEVICE_MMC1;
> +	case USB_BOOT:
> +		return BOOT_DEVICE_BOARD;
> +	default:
> +		return BOOT_DEVICE_NONE;
> +	}
> +}
> +
> +bool check_ram_available(long size)
> +{
> +	long sz = get_ram_size((long *)PHYS_SDRAM, size);
> +
> +	if (sz == size)
> +		return true;
> +
> +	return false;
> +}
> +
> +void spl_dram_init(void)
> +{
> +	u32 size = 0;
> +
> +	printf("Snowflake v2: DDR RAM INIT ");
> +	/*
> +	 * Overwrite some values to comply with the Micron 1GB/2GB DDRs.
> +	 */
> +	dram_timing.ddrc_cfg[2].val = 0xa1080020;
> +	dram_timing.ddrc_cfg[37].val = 0x1f;
> +
> +	dram_timing.fsp_msg[0].fsp_cfg[9].val = 0x110;
> +	dram_timing.fsp_msg[0].fsp_cfg[21].val = 0x1;
> +	dram_timing.fsp_msg[1].fsp_cfg[10].val = 0x110;
> +	dram_timing.fsp_msg[1].fsp_cfg[22].val = 0x1;
> +	dram_timing.fsp_msg[2].fsp_cfg[10].val = 0x110;
> +	dram_timing.fsp_msg[2].fsp_cfg[22].val = 0x1;
> +	dram_timing.fsp_msg[3].fsp_cfg[10].val = 0x110;
> +	dram_timing.fsp_msg[3].fsp_cfg[22].val = 0x1;

As you only support the 1GB DDR on this board, you could integrate these
values directly in the tables in lpddr4_timing.c and remove them here.

> +
> +	if (!ddr_init(&dram_timing) && check_ram_available(SZ_1G)) {
> +		size = 1;
> +		puts("1GB DDR RAM\n");
> +	} else {
> +		puts("Init DDR RAM failed\n");
> +		size = 1;
> +	}
> +
> +	writel(size, M4_BOOTROM_BASE_ADDR);

You could also simplify this and improve the error handling for your case:

if (ddr_init(&dram_timing) || !check_ram_available(SZ_1G)) {
	puts("Init DDR RAM failed\n");
	halt();
}

puts("1GB DDR RAM\n");
writel(1, M4_BOOTROM_BASE_ADDR);

> +}
> +
> +int board_fit_config_name_match(const char *name)
> +{
> +	puts("Snowflake: FIT CONFIG check\n");
> +	if (is_imx8mm() &&
> +	    !strcmp(name, "imx8mm-mt-snowflake-v2"))
> +		return 0;
> +
> +	puts("FIT CONFIG CHECK failed\n");
> +	return -1;
> +}
> +
> +int power_init_board(void)
> +{
> +	struct udevice *dev;
> +	int ret = pmic_get("pmic at 25", &dev);
> +
> +	if (ret) {
> +		puts("Snowflake: no PMIC\n");
> +		return ret;
> +	}
> +
> +	/* BUCKxOUT_DVS0/1 control BUCK123 output, clear PRESET_EN */
> +	pmic_reg_write(dev, PCA9450_BUCK123_DVS, 0x29);
> +	/* BUCK1 SOC 850mV */
> +	pmic_reg_write(dev, PCA9450_BUCK1OUT_DVS0, 0x14);
> +	pmic_reg_write(dev, PCA9450_BUCK1OUT_DVS1, 0x14);
> +	/* BUCK2 ARM 950mV/850mV */
> +	pmic_reg_write(dev, PCA9450_BUCK2OUT_DVS0, 0x1C);
> +	pmic_reg_write(dev, PCA9450_BUCK2OUT_DVS1, 0x14);
> +	/* BUCK3 DRAM/GPU/VPU 950mV */
> +	pmic_reg_write(dev, PCA9450_BUCK3OUT_DVS0, 0x1C);
> +	pmic_reg_write(dev, PCA9450_BUCK3OUT_DVS1, 0x1C);
> +	/* set VDD_SNVS_0V8 from default 0.85V to 0.8V */
> +	pmic_reg_write(dev, PCA9450_LDO2CTRL, 0xC0);
> +	return 0;
> +}
> +
> +void spl_board_init(void)
> +{
> +	struct udevice *dev;
> +	int ret;
> +
> +	puts("Normal Boot\n");
> +
> +	ret = uclass_get_device_by_name(UCLASS_CLK,
> +					"clock-controller at 30380000",
> +					&dev);
> +	if (ret < 0)
> +		printf("Failed to find clock node. Check device tree\n");
> +}
> +
> +void board_init_f(ulong dummy)
> +{
> +	int ret;
> +
> +	arch_cpu_init();
> +
> +	init_uart_clk(2);
> +
> +	timer_init();
> +
> +	/* Clear the BSS. */
> +	memset(__bss_start, 0, __bss_end - __bss_start);
> +
> +	ret = spl_init();
> +	if (ret) {
> +		debug("spl_init() failed: %d\n", ret);
> +		hang();
> +	}
> +
> +	preloader_console_init();
> +
> +	enable_tzc380();
> +
> +	power_init_board();
> +
> +	/* DDR initialization */
> +	spl_dram_init();
> +
> +	puts("Snowflake: lowlevel init DONE\n");
> +	board_init_r(NULL, 0);
> +}
> diff --git a/configs/snowflake_v2_emmcboot_defconfig b/configs/snowflake_v2_emmcboot_defconfig
> new file mode 100644
> index 0000000000000..3f1d443f69cd1
> --- /dev/null
> +++ b/configs/snowflake_v2_emmcboot_defconfig
> @@ -0,0 +1,134 @@
> +CONFIG_ARM=y
> +# CONFIG_ARM64_SUPPORT_AARCH32 is not set
> +CONFIG_ARCH_IMX8M=y
> +CONFIG_TEXT_BASE=0x40200000
> +CONFIG_SYS_MALLOC_LEN=0x2000000
> +CONFIG_SPL_GPIO=y
> +CONFIG_SPL_LIBCOMMON_SUPPORT=y
> +CONFIG_SPL_LIBGENERIC_SUPPORT=y
> +CONFIG_ENV_SIZE=0x1000
> +CONFIG_ENV_OFFSET=0x400000
> +CONFIG_DM_GPIO=y
> +CONFIG_DEFAULT_DEVICE_TREE="imx8mm-mt-snowflake-v2"
> +CONFIG_SPL_TEXT_BASE=0x7E1000
> +CONFIG_TARGET_MT_SNOWFLAKE_V2=y
> +CONFIG_SYS_PROMPT="u-boot=> "
> +CONFIG_SPL_MMC=y
> +CONFIG_SPL_SERIAL=y
> +CONFIG_SPL_DRIVERS_MISC=y
> +CONFIG_SPL_STACK=0x91fff0
> +CONFIG_SPL=y
> +CONFIG_ARMV8_SPL_EXCEPTION_VECTORS=y
> +CONFIG_SYS_LOAD_ADDR=0x40480000
> +CONFIG_SPL_PAYLOAD="u-boot.img"
> +CONFIG_DISTRO_DEFAULTS=y
> +CONFIG_SYS_BOOT_GET_CMDLINE=y
> +# CONFIG_ANDROID_BOOT_IMAGE is not set
> +CONFIG_FIT=y
> +CONFIG_FIT_EXTERNAL_OFFSET=0x3000
> +CONFIG_SPL_LOAD_FIT=y
> +CONFIG_SPL_LOAD_FIT_ADDRESS=0x500000
> +CONFIG_OF_SYSTEM_SETUP=y
> +CONFIG_BOOTCOMMAND="ext4load mmc 0:1 0x60480000 boot/leic-kernel.fit; setenv bootargs console=ttymxc2,115200 earlycon=ec_imx6q,0x30880000,115200 root=/dev/mmcblk0p1 rootwait rw; bootm 0x60480000"
> +CONFIG_SPL_HAS_BSS_LINKER_SECTION=y
> +CONFIG_SPL_BSS_START_ADDR=0x910000
> +CONFIG_SPL_BSS_MAX_SIZE=0x2000
> +CONFIG_SPL_BOARD_INIT=y
> +# CONFIG_SPL_RAW_IMAGE_SUPPORT is not set
> +# CONFIG_SPL_SHARES_INIT_SP_ADDR is not set
> +CONFIG_SYS_SPL_MALLOC=y
> +CONFIG_HAS_CUSTOM_SPL_MALLOC_START=y
> +CONFIG_CUSTOM_SYS_SPL_MALLOC_ADDR=0x42200000
> +CONFIG_SYS_SPL_MALLOC_SIZE=0x80000
> +CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR=y
> +CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x2C0
> +CONFIG_SPL_DMA=y
> +CONFIG_SPL_I2C=y
> +CONFIG_SPL_POWER=y
> +CONFIG_SPL_WATCHDOG=y
> +CONFIG_SYS_CBSIZE=2048
> +CONFIG_SYS_PBSIZE=276
> +# CONFIG_CMD_EXPORTENV is not set
> +# CONFIG_CMD_IMPORTENV is not set
> +# CONFIG_CMD_CRC32 is not set
> +CONFIG_CMD_CLK=y
> +CONFIG_CMD_FUSE=y
> +CONFIG_CMD_GPIO=y
> +CONFIG_CMD_I2C=y
> +CONFIG_CMD_MMC=y
> +CONFIG_CMD_USB_SDP=y
> +CONFIG_CMD_CACHE=y
> +CONFIG_CMD_REGULATOR=y
> +CONFIG_CMD_EXT4_WRITE=y
> +# CONFIG_SPL_DOS_PARTITION is not set
> +# CONFIG_ISO_PARTITION is not set
> +# CONFIG_SPL_EFI_PARTITION is not set
> +CONFIG_OF_CONTROL=y
> +CONFIG_SPL_OF_CONTROL=y
> +CONFIG_ENV_OVERWRITE=y
> +CONFIG_ENV_IS_IN_MMC=y
> +CONFIG_SYS_RELOC_GD_ENV_ADDR=y
> +CONFIG_SYS_MMC_ENV_DEV=1
> +CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
> +CONFIG_USE_HOSTNAME=y
> +CONFIG_HOSTNAME="snowflake-v2"
> +CONFIG_SPL_DM=y
> +CONFIG_SPL_CLK_COMPOSITE_CCF=y
> +CONFIG_CLK_COMPOSITE_CCF=y
> +CONFIG_SPL_CLK_IMX8MM=y
> +CONFIG_CLK_IMX8MM=y
> +CONFIG_USB_FUNCTION_FASTBOOT=y
> +CONFIG_FASTBOOT_BUF_ADDR=0x60480000
> +CONFIG_FASTBOOT_BUF_SIZE=0x7300000
> +CONFIG_FASTBOOT_FLASH=y
> +CONFIG_FASTBOOT_UUU_SUPPORT=y
> +CONFIG_FASTBOOT_FLASH_MMC_DEV=0
> +CONFIG_MXC_GPIO=y
> +CONFIG_DM_I2C=y
> +CONFIG_SUPPORT_EMMC_BOOT=y
> +CONFIG_MMC_IO_VOLTAGE=y
> +CONFIG_SPL_MMC_IO_VOLTAGE=y
> +CONFIG_MMC_UHS_SUPPORT=y
> +CONFIG_MMC_HS400_ES_SUPPORT=y
> +CONFIG_SPL_MMC_HS400_ES_SUPPORT=y
> +CONFIG_MMC_HS400_SUPPORT=y
> +CONFIG_SPL_MMC_HS400_SUPPORT=y
> +# CONFIG_MMC_VERBOSE is not set
> +CONFIG_MMC_SDHCI=y
> +CONFIG_SPL_MMC_SDHCI_ADMA=y
> +CONFIG_FSL_USDHC=y
> +CONFIG_PHYLIB=y
> +CONFIG_PHY_ATHEROS=y
> +CONFIG_PHY_GIGE=y
> +CONFIG_FEC_MXC=y
> +CONFIG_MII=y
> +CONFIG_PHY=y
> +CONFIG_NOP_PHY=y
> +CONFIG_PINCTRL=y
> +CONFIG_SPL_PINCTRL=y
> +CONFIG_PINCTRL_IMX8M=y
> +CONFIG_DM_PMIC=y
> +CONFIG_DM_PMIC_PCA9450=y
> +CONFIG_SPL_DM_PMIC_PCA9450=y
> +CONFIG_DM_REGULATOR=y
> +CONFIG_DM_REGULATOR_FIXED=y
> +CONFIG_DM_REGULATOR_GPIO=y
> +CONFIG_DM_SERIAL=y
> +CONFIG_MXC_UART=y
> +CONFIG_SYSRESET=y
> +CONFIG_SPL_SYSRESET=y
> +CONFIG_SYSRESET_PSCI=y
> +CONFIG_SYSRESET_WATCHDOG=y
> +CONFIG_DM_THERMAL=y
> +CONFIG_USB=y
> +# CONFIG_SPL_DM_USB is not set
> +CONFIG_USB_EHCI_HCD=y
> +# CONFIG_USB_EHCI_MX7 is not set
> +CONFIG_USB_GADGET=y
> +CONFIG_USB_GADGET_VENDOR_NUM=0x0525
> +CONFIG_USB_GADGET_PRODUCT_NUM=0xa4a5
> +CONFIG_CI_UDC=y
> +CONFIG_SDP_LOADADDR=0x50000000
> +CONFIG_IMX_WATCHDOG=y
> +# CONFIG_SPL_SHA1 is not set
> +# CONFIG_SPL_SHA256 is not set
> diff --git a/include/configs/snowflake_v2.h b/include/configs/snowflake_v2.h
> new file mode 100644
> index 0000000000000..f038dc9e6d7d8
> --- /dev/null
> +++ b/include/configs/snowflake_v2.h
> @@ -0,0 +1,54 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * Copyright (C) 2019 Kontron Electronics GmbH
> + * Copyright (C) 2020 Mettler Toledo GmbH
> + *
> + * Configuration settings for the MT Snowflake v2 Terminal, based on Kontron N8000 i.MX8MM SMARC module.

It's not a SMARC module. And nowadays the proper product name is
"Kontron SL i.MX8M Mini".

> + */
> +#ifndef __SNOWFLAKE_V2_IMX8M_MINI_H
> +#define __SNOWFLAKE_V2_IMX8M_MINI_H
> +
> +#ifdef CONFIG_SPL_BUILD
> +#include <config.h>
> +#endif
> +
> +#include <asm/arch/imx-regs.h>
> +#include <linux/sizes.h>
> +#include <asm/mach-imx/gpio.h>
> +
> +/*
> + * #######################################
> + * ### RAM                             ###
> + * #######################################
> + */
> +
> +#define PHYS_SDRAM			DDR_CSD1_BASE_ADDR
> +#define PHYS_SDRAM_SIZE			(SZ_1G)
> +#define CFG_SYS_SDRAM_BASE		PHYS_SDRAM
> +
> +#define CFG_SYS_INIT_RAM_ADDR	0x40000000
> +#define CFG_SYS_INIT_RAM_SIZE	0x200000
> +
> +/*
> + * #######################################
> + * ### USB                             ###
> + * #######################################
> + */
> +#ifdef CONFIG_USB_EHCI_HCD
> +#define CFG_MXC_USB_PORTSC		(PORT_PTS_UTMI | PORT_PTS_PTW)
> +#define CFG_MXC_USB_FLAGS		0
> +#endif
> +
> +#define BOOT_TARGET_DEVICES(func) \
> +        func(MMC, mmc, 0) \
> +        func(USB, usb, 0)
> +#include <config_distro_bootcmd.h>
> +/* Do not try to probe USB net adapters for net boot */
> +#undef BOOTENV_RUN_NET_USB_START
> +#define BOOTENV_RUN_NET_USB_START ""
> +
> +#ifdef CONFIG_SPL_BUILD
> +#define CFG_MALLOC_F_ADDR		0x930000
> +#endif
> +
> +#endif /* __SNOWFLAKE_V2_IMX8M_MINI_H */


More information about the U-Boot mailing list