imx: Add support for Kontron i.MX8MP OSM-S SoM and BL carrier board

This adds support for the Kontron Electronics OSM-S i.MX8MP SoM
and the matching baseboard BL i.MX8MP.

The SoM hardware complies to the Open Standard Module (OSM) 1.1
specification, size S (https://sget.org/standards/osm).

Signed-off-by: Frieder Schrempf <frieder.schrempf@kontron.de>
This commit is contained in:
Frieder Schrempf
2025-11-11 17:54:18 +01:00
committed by Fabio Estevam
parent 1817467e48
commit dfafac3207
15 changed files with 3533 additions and 0 deletions

View File

@@ -0,0 +1,124 @@
// SPDX-License-Identifier: GPL-2.0+ OR MIT
/*
* Copyright (C) 2022 Kontron Electronics GmbH
*/
#include "imx8mp-u-boot.dtsi"
/ {
wdt-reboot {
compatible = "wdt-reboot";
wdt = <&wdog1>;
bootph-pre-ram;
};
};
&gpio1 {
bootph-pre-ram;
};
&gpio2 {
bootph-pre-ram;
};
&gpio3 {
bootph-pre-ram;
};
&gpio4 {
bootph-pre-ram;
};
&gpio5 {
bootph-pre-ram;
};
/* Enable I2C1 to probe for a touch controller on LVDS connector */
&i2c1 {
status = "okay";
};
&i2c5 {
bootph-pre-ram;
};
&pinctrl_i2c5 {
bootph-pre-ram;
};
&pinctrl_i2c5_gpio {
bootph-pre-ram;
};
&pinctrl_pmic {
bootph-pre-ram;
};
&pinctrl_uart3 {
bootph-pre-ram;
};
&pinctrl_wdog {
bootph-pre-ram;
};
&pca9450 {
bootph-pre-ram;
};
&reg_vdd_soc {
bootph-pre-ram;
};
&reg_vdd_arm {
bootph-pre-ram;
};
&reg_vdd_3v3 {
bootph-pre-ram;
};
&reg_vdd_1v8 {
bootph-pre-ram;
};
&reg_nvcc_dram {
bootph-pre-ram;
};
&reg_nvcc_snvs {
bootph-pre-ram;
};
&reg_vdda {
bootph-pre-ram;
};
&reg_nvcc_sd {
bootph-pre-ram;
};
&uart3 {
bootph-pre-ram;
};
&usb_dwc3_0 {
/*
* OTG role switching is currently not supported in U-Boot, use peripheral
* as default.
*/
dr_mode = "peripheral";
};
&usb3_phy0 {
/*
* Workaround to fix USB in U-Boot until the following commit from
* linux-next-20251111 has landed and been synced to dts/upstream:
* 6504297872c7 ("arm64: dts: imx8mp-kontron: Fix USB OTG role switching")
*/
/delete-property/ vbus-supply;
};
&wdog1 {
bootph-pre-ram;
};

View File

@@ -158,6 +158,19 @@ config TARGET_KONTRON_MX8MM
select ARCH_MISC_INIT
select SPL_CRYPTO if SPL
config TARGET_KONTRON_MX8MP
bool "Kontron OSM-S/BL i.MX8MP"
select BINMAN
select IMX8MP
select SUPPORT_SPL
select IMX8M_LPDDR4
select FSL_CAAM
select ARCH_MISC_INIT
select SPL_CRYPTO if SPL
help
Kontron Electronics BL i.MX8MP using SoM module conformant to OSM
standard 1.1 size S.
config TARGET_IMX8MN_BSH_SMM_S2
bool "imx8mn-bsh-smm-s2"
select IMX8MN
@@ -434,6 +447,7 @@ source "board/freescale/imx8mn_evk/Kconfig"
source "board/freescale/imx8mp_evk/Kconfig"
source "board/gateworks/venice/Kconfig"
source "board/google/imx8mq_phanbell/Kconfig"
source "board/kontron/osm-s-mx8mp/Kconfig"
source "board/kontron/pitx_imx8m/Kconfig"
source "board/kontron/sl-mx8mm/Kconfig"
source "board/menlo/mx8menlo/Kconfig"

View File

@@ -0,0 +1,17 @@
if TARGET_KONTRON_MX8MP
config SYS_BOARD
string
default "osm-s-mx8mp"
config SYS_VENDOR
string
default "kontron"
config SYS_CONFIG_NAME
string
default "kontron-osm-s-mx8mp"
source "board/kontron/common/Kconfig"
endif

View File

@@ -0,0 +1,7 @@
Kontron OSM-S/BL i.MX8M Plus Boards
M: Frieder Schrempf <frieder.schrempf@kontron.de>
S: Maintained
F: board/kontron/osm-s-mx8mp
F: configs/kontron-osm-s-mx8mp_defconfig
F: doc/board/kontron/osm-s-mx8mp.rst
F: include/configs/kontron-osm-s-mx8mp.h

View File

@@ -0,0 +1,9 @@
# SPDX-License-Identifier: GPL-2.0+
# (C) Copyright 2023 Kontron Electronics GmbH
obj-y := osm-s-mx8mp.o
ifdef CONFIG_SPL_BUILD
obj-y += spl.o
obj-$(CONFIG_IMX8M_LPDDR4) += lpddr4_timing.o
endif

View File

@@ -0,0 +1,8 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2023 Kontron Electronics GmbH
*/
ROM_VERSION v2
BOOT_FROM sd
LOADER u-boot-spl-ddr.bin 0x920000

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,175 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2023 Kontron Electronics GmbH
*/
#include <asm/arch/imx-regs.h>
#include <asm/arch/sys_proto.h>
#include <asm/global_data.h>
#include <asm/io.h>
#include <asm/mach-imx/boot_mode.h>
#include <dm/uclass.h>
#include <efi.h>
#include <efi_loader.h>
#include <env_internal.h>
#include <fdt_support.h>
#include <init.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <mmc.h>
#include <net.h>
#include <power/regulator.h>
#include "../common/hw-uid.h"
DECLARE_GLOBAL_DATA_PTR;
#if IS_ENABLED(CONFIG_KONTRON_HW_UID)
struct uid_otp_loc uid_otp_locations[] = {
{
.addr = (u32 *)(OCOTP_BASE_ADDR + 0x7A0),
.len = 2,
.format = UID_OTP_FORMAT_DEC,
.desc = "BOARD"
},
{
.addr = (u32 *)(OCOTP_BASE_ADDR + 0x780),
.len = 2,
.format = UID_OTP_FORMAT_DEC,
.desc = "SOM"
},
#if IS_ENABLED(CONFIG_KONTRON_HW_UID_USE_SOC_FALLBACK)
{
.addr = (u32 *)(OCOTP_BASE_ADDR + 0xE00),
.len = 2,
.format = UID_OTP_FORMAT_HEX,
.desc = "SOC"
}
#endif
};
#endif /* CONFIG_KONTRON_HW_UID */
#if IS_ENABLED(CONFIG_EFI_HAVE_CAPSULE_SUPPORT)
struct efi_fw_image fw_images[] = {
{
.fw_name = u"KONTRON-OSM-S-MX8MP-UBOOT",
.image_index = 1,
},
};
struct efi_capsule_update_info update_info = {
.dfu_string = "mmc 0=flash-bin raw 0 0x2000 mmcpart 1",
.images = fw_images,
};
u8 num_image_type_guids = ARRAY_SIZE(fw_images);
#endif /* EFI_HAVE_CAPSULE_SUPPORT */
int board_phys_sdram_size(phys_size_t *size)
{
if (!size)
return -EINVAL;
*size = get_ram_size((void *)PHYS_SDRAM, 0x200000000);
return 0;
}
int ft_board_setup(void *blob, struct bd_info *bd)
{
enum boot_device boot_dev;
char env_str_sd[] = "sd-card";
char env_str_emmc[] = "emmc";
char *env_config_str;
if (env_get_location(0, 0) != ENVL_MMC)
return 0;
boot_dev = get_boot_device();
if (boot_dev == SD2_BOOT)
env_config_str = env_str_sd;
else if (boot_dev == MMC1_BOOT)
env_config_str = env_str_emmc;
else
return 0;
/*
* Export a string to the devicetree that tells userspace tools like
* libubootenv where the environment is currently coming from.
*/
return fdt_find_and_setprop(blob, "/chosen", "u-boot,env-config",
env_config_str, strlen(env_config_str) + 1, 1);
}
int board_late_init(void)
{
if (IS_ENABLED(CONFIG_KONTRON_HW_UID))
get_serial_number(uid_otp_locations, ARRAY_SIZE(uid_otp_locations));
if (is_usb_boot()) {
env_set("bootcmd", "fastboot 0");
env_set("bootdelay", "0");
}
return 0;
}
#if IS_ENABLED(CONFIG_ENV_IS_IN_MMC)
int board_mmc_get_env_dev(int devno)
{
return devno;
}
uint mmc_get_env_part(struct mmc *mmc)
{
if (IS_SD(mmc))
return EMMC_HWPART_DEFAULT;
switch (EXT_CSD_EXTRACT_BOOT_PART(mmc->part_config)) {
case EMMC_BOOT_PART_BOOT1:
return EMMC_HWPART_BOOT1;
case EMMC_BOOT_PART_BOOT2:
return EMMC_HWPART_BOOT2;
default:
return EMMC_HWPART_DEFAULT;
}
}
int mmc_get_env_addr(struct mmc *mmc, int copy, u32 *env_addr)
{
/* use normal offset for SD card */
if (IS_SD(mmc)) {
*env_addr = CONFIG_ENV_OFFSET;
if (copy)
*env_addr = CONFIG_ENV_OFFSET_REDUND;
return 0;
}
switch (EXT_CSD_EXTRACT_BOOT_PART(mmc->part_config)) {
case EMMC_BOOT_PART_BOOT1:
case EMMC_BOOT_PART_BOOT2:
*env_addr = mmc->capacity - CONFIG_ENV_SIZE - CONFIG_ENV_SIZE;
if (copy)
*env_addr = mmc->capacity - CONFIG_ENV_SIZE;
break;
default:
*env_addr = CONFIG_ENV_OFFSET;
if (copy)
*env_addr = CONFIG_ENV_OFFSET_REDUND;
}
return 0;
}
#endif
enum env_location env_get_location(enum env_operation op, int prio)
{
if (prio)
return ENVL_UNKNOWN;
if (CONFIG_IS_ENABLED(ENV_IS_NOWHERE) && is_usb_boot())
return ENVL_NOWHERE;
return arch_env_get_location(op, prio);
}

View File

@@ -0,0 +1,6 @@
kernel_addr_r=0x42000000
fdt_addr_r=0x48000000
fdtoverlay_addr_r=0x49000000
ramdisk_addr_r=0x48080000
scriptaddr=0x40000000
pxefile_addr_r=0x40100000

View File

@@ -0,0 +1,358 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2023 Kontron Electronics GmbH
*/
#include <asm/arch/imx8mp_pins.h>
#include <asm/arch/clock.h>
#include <asm/arch/ddr.h>
#include <asm/arch/imx-regs.h>
#include <asm/arch/sys_proto.h>
#include <asm/global_data.h>
#include <asm/gpio.h>
#include <asm/mach-imx/boot_mode.h>
#include <asm/mach-imx/iomux-v3.h>
#include <dm/uclass.h>
#include <dm/device.h>
#include <dm/uclass-internal.h>
#include <dm/device-internal.h>
#include <hang.h>
#include <i2c.h>
#include <init.h>
#include <linux/errno.h>
#include <linux/delay.h>
#include <power/pca9450.h>
#include <power/pmic.h>
#include <spl.h>
DECLARE_GLOBAL_DATA_PTR;
int spl_board_boot_device(enum boot_device boot_dev_spl)
{
if (IS_ENABLED(CONFIG_SPL_BOOTROM_SUPPORT))
return BOOT_DEVICE_BOOTROM;
switch (boot_dev_spl) {
case SD1_BOOT:
case MMC1_BOOT:
return BOOT_DEVICE_MMC1;
case SD2_BOOT:
case MMC2_BOOT:
return BOOT_DEVICE_MMC2;
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;
}
static void spl_dram_init(void)
{
u32 size = 0;
int i, ret;
/*
* First check the largest possible DDR size of 8GB, then try the lower
* configs.
*/
ret = ddr_init(&dram_timing);
if (!ret && check_ram_available(SZ_4G << 1))
size = 8;
// assume 4GB if ddr_init() succeeds but 8GB can not be addressed
else if (!ret) {
/*
* For some strange, unknown reason freezes are occurring if we run
* check_ram_available() after the second call to ddr_init(). This
* doesn't seem to be an issue with caching as it also happens with
* caches disable. The workaround that does the trick is accessing the
* DDR areas once more before calling ddr_init() and
* check_ram_available() again. This can be done by rerunning the size
* check on the first few bytes of the DDR.
* On the other hand this breaks the 1GB DDR init, but we can skip this
* as the 1GB is single rank and the training fails. We can detect that
* by checking the return code of ddr_init().
*/
check_ram_available(256);
/*
* Overwrite some values to comply with the 4GB DDR.
*/
dram_timing.ddrc_cfg[5].val = 0x7a0118;
dram_timing.ddrc_cfg[12].val = 0x650048;
dram_timing.ddrc_cfg[13].val = 0x140048;
dram_timing.ddrc_cfg[23].val = 0x120;
dram_timing.ddrc_cfg[39].val = 0x17;
dram_timing.ddrc_cfg[46].val = 0xf0f;
dram_timing.ddrc_cfg[62].val = 0xc001c;
dram_timing.ddrc_cfg[66].val = 0x160048;
dram_timing.ddrc_cfg[77].val = 0x1d;
dram_timing.ddrc_cfg[87].val = 0x30007;
dram_timing.ddrc_cfg[91].val = 0x160048;
dram_timing.ddrc_cfg[102].val = 0x8;
for (i = 114; i < 138; i++)
dram_timing.ddrphy_cfg[i].val = 0xe38;
dram_timing.ddrphy_cfg[155].val = 0xdc;
dram_timing.ddrphy_cfg[164].val = 0xdc;
dram_timing.ddrphy_cfg[173].val = 0xdc;
dram_timing.fsp_msg[0].fsp_cfg[3].val = 0x283c;
dram_timing.fsp_msg[0].fsp_cfg[4].val = 0x11;
dram_timing.fsp_msg[0].fsp_cfg[12].val = 0x4865;
dram_timing.fsp_msg[0].fsp_cfg[13].val = 0x4800;
dram_timing.fsp_msg[0].fsp_cfg[17].val = 0x4865;
dram_timing.fsp_msg[0].fsp_cfg[18].val = 0x4800;
dram_timing.fsp_msg[0].fsp_cfg[24].val = 0x6500;
dram_timing.fsp_msg[0].fsp_cfg[26].val = 0x48;
dram_timing.fsp_msg[0].fsp_cfg[30].val = 0x6500;
dram_timing.fsp_msg[0].fsp_cfg[32].val = 0x48;
dram_timing.fsp_msg[1].fsp_cfg[4].val = 0x283c;
dram_timing.fsp_msg[1].fsp_cfg[5].val = 0x11;
dram_timing.fsp_msg[1].fsp_cfg[14].val = 0x4800;
dram_timing.fsp_msg[1].fsp_cfg[19].val = 0x4800;
dram_timing.fsp_msg[1].fsp_cfg[27].val = 0x48;
dram_timing.fsp_msg[1].fsp_cfg[33].val = 0x48;
dram_timing.fsp_msg[2].fsp_cfg[4].val = 0x283c;
dram_timing.fsp_msg[2].fsp_cfg[5].val = 0x11;
dram_timing.fsp_msg[2].fsp_cfg[14].val = 0x4800;
dram_timing.fsp_msg[2].fsp_cfg[19].val = 0x4800;
dram_timing.fsp_msg[2].fsp_cfg[27].val = 0x48;
dram_timing.fsp_msg[2].fsp_cfg[33].val = 0x48;
dram_timing.fsp_msg[3].fsp_cfg[3].val = 0x283c;
dram_timing.fsp_msg[3].fsp_cfg[4].val = 0x11;
dram_timing.fsp_msg[3].fsp_cfg[14].val = 0x4865;
dram_timing.fsp_msg[3].fsp_cfg[15].val = 0x4800;
dram_timing.fsp_msg[3].fsp_cfg[19].val = 0x4865;
dram_timing.fsp_msg[3].fsp_cfg[20].val = 0x4800;
dram_timing.fsp_msg[3].fsp_cfg[26].val = 0x6500;
dram_timing.fsp_msg[3].fsp_cfg[28].val = 0x48;
dram_timing.fsp_msg[3].fsp_cfg[32].val = 0x6500;
dram_timing.fsp_msg[3].fsp_cfg[34].val = 0x48;
if (!ddr_init(&dram_timing) && check_ram_available(SZ_4G))
size = 4;
}
// assume 1GB if 8GB training failed
else if (size == 0) {
/*
* Overwrite some values to comply with the 1GB DDR.
*/
dram_timing.ddrc_cfg[2].val = 0xa1080020;
dram_timing.ddrc_cfg[5].val = 0x7a00b4;
dram_timing.ddrc_cfg[12].val = 0x550048;
dram_timing.ddrc_cfg[13].val = 0x15002f;
dram_timing.ddrc_cfg[23].val = 0xbc;
dram_timing.ddrc_cfg[39].val = 0x1f;
dram_timing.ddrc_cfg[45].val = 0xf070707;
dram_timing.ddrc_cfg[62].val = 0xc0012;
dram_timing.ddrc_cfg[66].val = 0x16002f;
dram_timing.ddrc_cfg[77].val = 0x13;
dram_timing.ddrc_cfg[87].val = 0x30005;
dram_timing.ddrc_cfg[91].val = 0x16002f;
dram_timing.ddrc_cfg[102].val = 0x5;
for (i = 90; i < 114; i++)
dram_timing.ddrphy_cfg[i].val = 0x680;
for (; i < 138; i++)
dram_timing.ddrphy_cfg[i].val = 0x69a;
dram_timing.ddrphy_cfg[155].val = 0x104;
dram_timing.ddrphy_cfg[164].val = 0x104;
dram_timing.ddrphy_cfg[173].val = 0x104;
dram_timing.fsp_msg[0].fsp_cfg[3].val = 0x3030;
dram_timing.fsp_msg[0].fsp_cfg[4].val = 0x14;
dram_timing.fsp_msg[0].fsp_cfg[9].val = 0x110;
dram_timing.fsp_msg[0].fsp_cfg[12].val = 0x4855;
dram_timing.fsp_msg[0].fsp_cfg[13].val = 0x2f00;
dram_timing.fsp_msg[0].fsp_cfg[14].val = 0x15;
dram_timing.fsp_msg[0].fsp_cfg[17].val = 0x4855;
dram_timing.fsp_msg[0].fsp_cfg[18].val = 0x2f00;
dram_timing.fsp_msg[0].fsp_cfg[19].val = 0x15;
dram_timing.fsp_msg[0].fsp_cfg[21].val = 0x1;
dram_timing.fsp_msg[0].fsp_cfg[24].val = 0x5500;
dram_timing.fsp_msg[0].fsp_cfg[26].val = 0x2f;
dram_timing.fsp_msg[0].fsp_cfg[27].val = 0x1500;
dram_timing.fsp_msg[0].fsp_cfg[30].val = 0x5500;
dram_timing.fsp_msg[0].fsp_cfg[32].val = 0x2f;
dram_timing.fsp_msg[0].fsp_cfg[33].val = 0x1500;
dram_timing.fsp_msg[1].fsp_cfg[4].val = 0x3030;
dram_timing.fsp_msg[1].fsp_cfg[5].val = 0x14;
dram_timing.fsp_msg[1].fsp_cfg[10].val = 0x110;
dram_timing.fsp_msg[1].fsp_cfg[14].val = 0x2f00;
dram_timing.fsp_msg[1].fsp_cfg[19].val = 0x2f00;
dram_timing.fsp_msg[1].fsp_cfg[22].val = 0x1;
dram_timing.fsp_msg[1].fsp_cfg[27].val = 0x2f;
dram_timing.fsp_msg[1].fsp_cfg[33].val = 0x2f;
dram_timing.fsp_msg[2].fsp_cfg[4].val = 0x3030;
dram_timing.fsp_msg[2].fsp_cfg[5].val = 0x14;
dram_timing.fsp_msg[2].fsp_cfg[10].val = 0x110;
dram_timing.fsp_msg[2].fsp_cfg[14].val = 0x2f00;
dram_timing.fsp_msg[2].fsp_cfg[19].val = 0x2f00;
dram_timing.fsp_msg[2].fsp_cfg[22].val = 0x1;
dram_timing.fsp_msg[2].fsp_cfg[27].val = 0x2f;
dram_timing.fsp_msg[2].fsp_cfg[33].val = 0x2f;
dram_timing.fsp_msg[3].fsp_cfg[3].val = 0x3030;
dram_timing.fsp_msg[3].fsp_cfg[4].val = 0x14;
dram_timing.fsp_msg[3].fsp_cfg[11].val = 0x110;
dram_timing.fsp_msg[3].fsp_cfg[14].val = 0x4855;
dram_timing.fsp_msg[3].fsp_cfg[15].val = 0x2f00;
dram_timing.fsp_msg[3].fsp_cfg[16].val = 0x15;
dram_timing.fsp_msg[3].fsp_cfg[19].val = 0x4855;
dram_timing.fsp_msg[3].fsp_cfg[20].val = 0x2f00;
dram_timing.fsp_msg[3].fsp_cfg[21].val = 0x15;
dram_timing.fsp_msg[3].fsp_cfg[23].val = 0x1;
dram_timing.fsp_msg[3].fsp_cfg[26].val = 0x5500;
dram_timing.fsp_msg[3].fsp_cfg[28].val = 0x2f;
dram_timing.fsp_msg[3].fsp_cfg[29].val = 0x1500;
dram_timing.fsp_msg[3].fsp_cfg[32].val = 0x5500;
dram_timing.fsp_msg[3].fsp_cfg[34].val = 0x2f;
dram_timing.fsp_msg[3].fsp_cfg[35].val = 0x1500;
if (!ddr_init(&dram_timing) && check_ram_available(SZ_1G))
size = 1;
}
if (size == 0) {
printf("Failed to initialize DDR RAM!\n");
size = 1;
} else {
printf("DDR: LPDDR4 initialized (%dGB)\n", size);
}
gd->ram_size = size;
}
void spl_board_init(void)
{
struct udevice *dev;
int ret;
if (IS_ENABLED(CONFIG_FSL_CAAM)) {
ret = uclass_get_device_by_driver(UCLASS_MISC, DM_DRIVER_GET(caam_jr), &dev);
if (ret)
printf("Failed to initialize %s: %d\n", dev->name, ret);
}
/*
* Set GIC clock to 500Mhz for OD VDD_SOC. Kernel driver does
* not allow to change it. Should set the clock after PMIC
* setting done. Default is 400Mhz (system_pll1_800m with div = 2)
* set by ROM for ND VDD_SOC
*/
clock_enable(CCGR_GIC, 0);
clock_set_target_val(GIC_CLK_ROOT, CLK_ROOT_ON | CLK_ROOT_SOURCE_SEL(5));
clock_enable(CCGR_GIC, 1);
}
static int power_init_board(void)
{
struct udevice *dev;
int ret = pmic_get("pmic@25", &dev);
if (ret == -ENODEV)
puts("No pmic found\n");
if (ret)
return ret;
/* BUCKxOUT_DVS0/1 control BUCK123 output */
pmic_reg_write(dev, PCA9450_BUCK123_DVS, 0x29);
/* Increase VDD_SOC and VDD_ARM to OD voltage 0.95V */
pmic_reg_write(dev, PCA9450_BUCK1OUT_DVS0, 0x1C);
pmic_reg_write(dev, PCA9450_BUCK2OUT_DVS0, 0x1C);
/* Set BUCK1 DVS1 to suspend controlled through PMIC_STBY_REQ */
pmic_reg_write(dev, PCA9450_BUCK1OUT_DVS1, 0x14);
pmic_reg_write(dev, PCA9450_BUCK1CTRL, 0x59);
/* Set WDOG_B_CFG to cold reset */
pmic_reg_write(dev, PCA9450_RESET_CTRL, 0xA1);
/* Enable I2C level translator */
pmic_reg_write(dev, PCA9450_CONFIG2, 0x01);
return 0;
}
unsigned long board_spl_mmc_get_uboot_raw_sector(struct mmc *mmc, unsigned long raw_sect)
{
/*
* The image offset on SD/MMC devices is 32 KiB, except for eMMC boot from
* HW boot part. In this case it is 0 KiB. In order to make the bootloader
* universal, check for HW boot part and adjust the offset.
*/
if (!IS_SD(mmc)) {
switch (EXT_CSD_EXTRACT_BOOT_PART(mmc->part_config)) {
case EMMC_BOOT_PART_BOOT1:
case EMMC_BOOT_PART_BOOT2:
raw_sect -= 32 * 2;
break;
}
}
return raw_sect;
}
const char *spl_board_loader_name(u32 boot_device)
{
static char name[16];
struct mmc *mmc;
switch (boot_device) {
case BOOT_DEVICE_MMC1:
mmc_init_device(0);
mmc = find_mmc_device(0);
mmc_init(mmc);
snprintf(name, sizeof(name), "eMMC %s",
emmc_hwpart_names[EXT_CSD_EXTRACT_BOOT_PART(mmc->part_config)]);
return name;
case BOOT_DEVICE_MMC2:
sprintf(name, "SD card");
return name;
}
return NULL;
}
void board_init_f(ulong dummy)
{
int ret;
arch_cpu_init();
init_uart_clk(2);
ret = spl_early_init();
if (ret) {
debug("spl_early_init() failed: %d\n", ret);
hang();
}
preloader_console_init();
enable_tzc380();
/* PMIC initialization */
power_init_board();
/* DDR initialization */
spl_dram_init();
}

View File

@@ -0,0 +1,203 @@
CONFIG_ARM=y
CONFIG_ARCH_IMX8M=y
CONFIG_TEXT_BASE=0x40200000
CONFIG_SYS_MALLOC_LEN=0x4000000
CONFIG_SPL_GPIO=y
CONFIG_SPL_LIBCOMMON_SUPPORT=y
CONFIG_SPL_LIBGENERIC_SUPPORT=y
CONFIG_ENV_SIZE=0x10000
CONFIG_ENV_OFFSET=0x1E0000
CONFIG_IMX_CONFIG="board/kontron/osm-s-mx8mp/imximage.cfg"
CONFIG_DM_GPIO=y
CONFIG_KONTRON_HW_UID=y
CONFIG_DEFAULT_DEVICE_TREE="freescale/imx8mp-kontron-bl-osm-s"
CONFIG_TARGET_KONTRON_MX8MP=y
CONFIG_OF_LIBFDT_OVERLAY=y
CONFIG_SPL_MMC=y
CONFIG_SPL_SERIAL=y
CONFIG_SPL_DRIVERS_MISC=y
CONFIG_BOOTCOUNT_BOOTLIMIT=3
CONFIG_SPL_STACK=0x96fc00
CONFIG_SPL_TEXT_BASE=0x920000
CONFIG_SPL_HAS_BSS_LINKER_SECTION=y
CONFIG_SPL_BSS_START_ADDR=0x98fc00
CONFIG_SPL_BSS_MAX_SIZE=0x400
CONFIG_SYS_LOAD_ADDR=0x42000000
CONFIG_SPL=y
CONFIG_ENV_OFFSET_REDUND=0x1F0000
CONFIG_IMX_BOOTAUX=y
CONFIG_SPL_IMX_ROMAPI_LOADADDR=0x48000000
CONFIG_EFI_SET_TIME=y
CONFIG_EFI_RUNTIME_UPDATE_CAPSULE=y
CONFIG_EFI_CAPSULE_ON_DISK=y
CONFIG_EFI_CAPSULE_FIRMWARE_FIT=y
CONFIG_FIT=y
CONFIG_FIT_EXTERNAL_OFFSET=0x3000
CONFIG_SPL_LOAD_FIT=y
CONFIG_BOOTSTD_FULL=y
CONFIG_BOOTMETH_RAUC=y
CONFIG_OF_BOARD_SETUP=y
CONFIG_OF_SYSTEM_SETUP=y
CONFIG_SYS_CBSIZE=2048
CONFIG_SYS_PBSIZE=2074
CONFIG_BOARD_TYPES=y
# CONFIG_BOARD_INIT is not set
CONFIG_BOARD_LATE_INIT=y
CONFIG_SPL_MAX_SIZE=0x26000
CONFIG_SPL_BOARD_INIT=y
CONFIG_SPL_SYS_MALLOC_SIMPLE=y
# CONFIG_SPL_SHARES_INIT_SP_ADDR is not set
CONFIG_SPL_HAVE_INIT_STACK=y
CONFIG_SPL_SYS_MALLOC=y
CONFIG_SPL_HAS_CUSTOM_MALLOC_START=y
CONFIG_SPL_CUSTOM_SYS_MALLOC_ADDR=0x42200000
CONFIG_SPL_SYS_MALLOC_SIZE=0x80000
CONFIG_SPL_SYS_MMCSD_RAW_MODE=y
CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x300
CONFIG_SPL_I2C=y
CONFIG_SPL_POWER=y
CONFIG_SPL_WATCHDOG=y
CONFIG_CMD_NVEDIT_EFI=y
CONFIG_CRC32_VERIFY=y
CONFIG_CMD_EEPROM=y
CONFIG_SYS_I2C_EEPROM_ADDR_LEN=2
CONFIG_SYS_EEPROM_SIZE=8192
CONFIG_SYS_EEPROM_PAGE_WRITE_BITS=5
CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS=6
CONFIG_CMD_MD5SUM=y
CONFIG_MD5SUM_VERIFY=y
CONFIG_CMD_MEMTEST=y
CONFIG_CMD_SHA1SUM=y
CONFIG_SHA1SUM_VERIFY=y
# CONFIG_CMD_LZMADEC is not set
CONFIG_CMD_CLK=y
CONFIG_CMD_DFU=y
CONFIG_CMD_FUSE=y
CONFIG_CMD_GPIO=y
CONFIG_CMD_GPT=y
CONFIG_CMD_GPT_RENAME=y
CONFIG_CMD_I2C=y
CONFIG_CMD_LSBLK=y
CONFIG_CMD_MBR=y
CONFIG_CMD_MMC=y
CONFIG_CMD_BKOPS_ENABLE=y
CONFIG_MMC_SPEED_MODE_SET=y
CONFIG_CMD_READ=y
CONFIG_CMD_SPI=y
CONFIG_CMD_USB=y
CONFIG_CMD_USB_SDP=y
CONFIG_CMD_USB_MASS_STORAGE=y
CONFIG_CMD_WDT=y
CONFIG_CMD_BOOTCOUNT=y
CONFIG_CMD_CACHE=y
CONFIG_CMD_EFIDEBUG=y
CONFIG_CMD_RTC=y
CONFIG_CMD_TIME=y
CONFIG_CMD_GETTIME=y
CONFIG_CMD_UUID=y
CONFIG_CMD_PMIC=y
CONFIG_CMD_REGULATOR=y
CONFIG_CMD_SMC=y
CONFIG_HASH_VERIFY=y
CONFIG_CMD_BTRFS=y
CONFIG_CMD_EXT4_WRITE=y
CONFIG_CMD_FS_UUID=y
CONFIG_PARTITION_TYPE_GUID=y
CONFIG_OF_CONTROL=y
CONFIG_SPL_OF_CONTROL=y
CONFIG_OF_UPSTREAM=y
CONFIG_ENV_IS_NOWHERE=y
CONFIG_ENV_IS_IN_MMC=y
CONFIG_ENV_REDUNDANT=y
CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
CONFIG_USE_HOSTNAME=y
CONFIG_HOSTNAME="kontron-mx8mp"
CONFIG_VERSION_VARIABLE=y
CONFIG_TFTP_TSIZE=y
CONFIG_NET_RANDOM_ETHADDR=y
CONFIG_SPL_DM=y
CONFIG_SPL_DM_SEQ_ALIAS=y
CONFIG_REGMAP=y
CONFIG_SYSCON=y
CONFIG_BOOTCOUNT_LIMIT=y
CONFIG_BOOTCOUNT_ENV=y
CONFIG_CLK_COMPOSITE_CCF=y
CONFIG_SPL_CLK_IMX8MP=y
CONFIG_CLK_IMX8MP=y
CONFIG_USB_FUNCTION_FASTBOOT=y
CONFIG_FASTBOOT_BUF_ADDR=0x42000000
CONFIG_FASTBOOT_FLASH=y
CONFIG_FASTBOOT_UUU_SUPPORT=y
CONFIG_FASTBOOT_FLASH_MMC_DEV=0
CONFIG_FASTBOOT_MMC_BOOT_SUPPORT=y
CONFIG_FASTBOOT_MMC_USER_SUPPORT=y
CONFIG_GPIO_HOG=y
CONFIG_MXC_GPIO=y
CONFIG_DM_I2C=y
CONFIG_DM_I2C_GPIO=y
CONFIG_USB_HUB_USB251XB=y
CONFIG_I2C_EEPROM=y
CONFIG_SPL_I2C_EEPROM=y
CONFIG_SYS_I2C_EEPROM_ADDR=0x50
CONFIG_SUPPORT_EMMC_BOOT=y
CONFIG_MMC_IO_VOLTAGE=y
CONFIG_SPL_MMC_IO_VOLTAGE=y
CONFIG_MMC_UHS_SUPPORT=y
CONFIG_SPL_MMC_UHS_SUPPORT=y
CONFIG_MMC_HS400_ES_SUPPORT=y
CONFIG_MMC_HS400_SUPPORT=y
CONFIG_FSL_USDHC=y
CONFIG_PHY_ETHERNET_ID=y
CONFIG_DM_ETH_PHY=y
CONFIG_PHY_GIGE=y
CONFIG_DWC_ETH_QOS=y
CONFIG_DWC_ETH_QOS_IMX=y
CONFIG_FEC_MXC=y
CONFIG_RGMII=y
CONFIG_MII=y
CONFIG_RMII=y
CONFIG_PHY_IMX8MQ_USB=y
CONFIG_PINCTRL=y
CONFIG_SPL_PINCTRL=y
CONFIG_PINCTRL_IMX8M=y
CONFIG_POWER_DOMAIN=y
CONFIG_IMX8M_POWER_DOMAIN=y
CONFIG_IMX8MP_HSIOMIX_BLKCTRL=y
CONFIG_DM_PMIC=y
CONFIG_DM_PMIC_PCA9450=y
CONFIG_SPL_DM_PMIC_PCA9450=y
CONFIG_DM_REGULATOR=y
CONFIG_DM_REGULATOR_PCA9450=y
CONFIG_SPL_DM_REGULATOR_PCA9450=y
CONFIG_DM_REGULATOR_FIXED=y
CONFIG_DM_REGULATOR_GPIO=y
CONFIG_DM_RTC=y
CONFIG_RTC_RV3028=y
CONFIG_RTC_RV8803=y
CONFIG_DM_SERIAL=y
CONFIG_MXC_UART=y
CONFIG_SPI=y
CONFIG_DM_SPI=y
CONFIG_MXC_SPI=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_DM_USB_GADGET=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_DWC3=y
CONFIG_USB_XHCI_DWC3_OF_SIMPLE=y
CONFIG_USB_EHCI_HCD=y
CONFIG_MXC_USB_OTG_HACTIVE=y
CONFIG_USB_DWC3=y
CONFIG_USB_DWC3_GENERIC=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_MANUFACTURER="FSL"
CONFIG_USB_GADGET_VENDOR_NUM=0x0525
CONFIG_USB_GADGET_PRODUCT_NUM=0xa4a5
CONFIG_USB_ETHER=y
CONFIG_USB_ETH_CDC=y
CONFIG_IMX_WATCHDOG=y

View File

@@ -0,0 +1,3 @@
#include <configs/kontron-osm-s-mx8mp.config>
CONFIG_SPL_BOOTROM_SUPPORT=y

View File

@@ -6,6 +6,7 @@ Kontron
.. toctree::
:maxdepth: 2
osm-s-mx8mp
pitx-imx8m
sl28
sl-mx6ul

View File

@@ -0,0 +1,104 @@
.. SPDX-License-Identifier: GPL-2.0+
Kontron Electronics i.MX8MP SoMs and Boards
===========================================
The OSM-S i.MX8MP by Kontron Electronics GmbH is a SoM module with an
i.MX8M-Plus SoC, up to 8 GB LPDDR4 RAM, eMMC, PMIC, RTC.
The matching evaluation boards (Board-Line, BL) have two Ethernet ports,
USB 2.0, HDMI/LVDS, SD card, CAN, RS485, RS232 and much more.
The OSM-S i.MX8MP is compliant to the Open Standard Module (OSM) 1.1
specification, size S (https://sget.org/standards/osm).
Quick Start
-----------
- Get and Build the Trusted Firmware-A (TF-A)
- Get the DDR firmware
- Build U-Boot
- Boot
.. note::
To build on a x86-64 host machine, you need a GNU cross toolchain for the
target architecture (aarch64). Check your distros package manager or
download and install the necessary tools (``aarch64-linux-gnu-*``) manually.
Get and Build the Trusted Firmware-A (TF-A)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
There are two sources for the TF-A. Mainline and NXP. Get the one you prefer
(support and features might differ).
.. note::
If you are using GCC 12 and you get compiler/linker errors, try to add the
following arguments to your make command as workaround:
``CFLAGS="-Wno-array-bounds" LDFLAGS="--no-warn-rwx-segments"``
**NXP's imx-atf**
1. Get TF-A from: https://github.com/nxp-imx/imx-atf, branch: lf_v2.6
2. Build
.. code-block:: bash
$ make PLAT=imx8mp CROSS_COMPILE=aarch64-linux-gnu- IMX_BOOT_UART_BASE="0x30880000" bl31
$ cp build/imx8mp/release/bl31.bin $(builddir)
.. note::
*builddir* is U-Boot's build directory (source directory for in-tree builds)
**Mainline TF-A**
1. Get TF-A from: https://git.trustedfirmware.org/TF-A/trusted-firmware-a.git/, tag: v2.4
2. Build
.. code-block:: bash
$ make PLAT=imx8mp CROSS_COMPILE=aarch64-linux-gnu- IMX_BOOT_UART_BASE="0x30880000" bl31
$ cp build/imx8mp/release/bl31.bin $(builddir)
Get the DDR firmware
^^^^^^^^^^^^^^^^^^^^
.. code-block:: bash
$ wget https://www.nxp.com/lgfiles/NMG/MAD/YOCTO/firmware-imx-8.18.bin
$ chmod +x firmware-imx-8.18.bin
$ ./firmware-imx-8.18.bin
$ cp firmware-imx-8.18/firmware/ddr/synopsys/lpddr4_pmu_train_1d_imem_202006.bin $(builddir)
$ cp firmware-imx-8.18/firmware/ddr/synopsys/lpddr4_pmu_train_1d_dmem_202006.bin $(builddir)
$ cp firmware-imx-8.18/firmware/ddr/synopsys/lpddr4_pmu_train_2d_imem_202006.bin $(builddir)
$ cp firmware-imx-8.18/firmware/ddr/synopsys/lpddr4_pmu_train_2d_dmem_202006.bin $(builddir)
Build U-Boot
^^^^^^^^^^^^
.. code-block:: bash
$ make kontron-osm-s-mx8mp_defconfig
$ make CROSS_COMPILE=aarch64-linux-gnu-
Copy the flash.bin to SD card at an offset of 32 KiB:
.. code-block:: bash
$ dd if=flash.bin of=/dev/sd[x] bs=1K seek=32 conv=notrunc
Boot
^^^^
Put the SD card in the slot on the board and apply power. Check the serial
console for output.
Further Information
-------------------
The bootloader configuration is setup to be used with kernel FIT images. Legacy
images might not be working out of the box.
Please see https://docs.kontron-electronics.de for further vendor documentation.

View File

@@ -0,0 +1,30 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (C) 2023 Kontron Electronics GmbH
*
* Configuration settings for the Kontron OSM-S/BL i.MX8M Plus boards and modules.
*/
#ifndef __KONTRON_MX8MP_CONFIG_H
#define __KONTRON_MX8MP_CONFIG_H
#include <asm/arch/imx-regs.h>
#include <linux/sizes.h>
/* RAM */
#define PHYS_SDRAM DDR_CSD1_BASE_ADDR
#define PHYS_SDRAM_SIZE (SZ_2G + SZ_1G)
#define PHYS_SDRAM_2 0x100000000
#define PHYS_SDRAM_2_SIZE (SZ_1G + SZ_4G)
#define CFG_SYS_SDRAM_BASE PHYS_SDRAM
#define CFG_SYS_INIT_RAM_ADDR 0x40000000
#define CFG_SYS_INIT_RAM_SIZE SZ_512K
/* Board and environment settings */
#ifdef CONFIG_USB_EHCI_HCD
#define CFG_MXC_USB_PORTSC (PORT_PTS_UTMI | PORT_PTS_PTW)
#define CFG_MXC_USB_FLAGS 0
#endif
#endif /* __KONTRON_MX8MP_CONFIG_H */