diff options
| author | Tom Rini <[email protected]> | 2025-12-08 13:17:27 -0600 |
|---|---|---|
| committer | Tom Rini <[email protected]> | 2025-12-08 13:17:27 -0600 |
| commit | 59202e5ae76ef3acb34c4236e43248f1cd3fc642 (patch) | |
| tree | 30004ced6a059b2c25afb0aca8b049908c2212c3 /board | |
| parent | 8e12d6ccb3cfa84dd275a1b852b2a235de0162b0 (diff) | |
| parent | 0e0a198a68be71148f5ec27ef86796174f91436f (diff) | |
Merge tag 'v2026.01-rc4' into next
Prepare v2026.01-rc4
Diffstat (limited to 'board')
33 files changed, 871 insertions, 69 deletions
diff --git a/board/BuR/brppt1/MAINTAINERS b/board/BuR/brppt1/MAINTAINERS index a974a97c157..fc2ee146668 100644 --- a/board/BuR/brppt1/MAINTAINERS +++ b/board/BuR/brppt1/MAINTAINERS @@ -1,9 +1,8 @@ BRPPT1 BOARD -M: Wolfgang Wallner <[email protected]> +M: Wolfgang Wallner <[email protected]> S: Maintained F: board/BuR/brppt1/ F: board/BuR/common/ F: include/configs/brppt1.h F: configs/brppt1_mmc_defconfig -F: configs/brppt1_nand_defconfig -F: configs/brppt1_spi_defconfig +F: arch/arm/dts/am335x-brppt1-mmc* diff --git a/board/BuR/brppt2/MAINTAINERS b/board/BuR/brppt2/MAINTAINERS index bfeaa571a82..84cb6573463 100644 --- a/board/BuR/brppt2/MAINTAINERS +++ b/board/BuR/brppt2/MAINTAINERS @@ -1,7 +1,8 @@ BUR_PPT2 BOARD -M: Wolfgang Wallner <[email protected]> +M: Wolfgang Wallner <[email protected]> S: Maintained F: board/BuR/brppt2/ F: board/BuR/common/ F: include/configs/brppt2.h F: configs/brppt2_defconfig +F: arch/arm/dts/imx6dl-brppt2.dts diff --git a/board/BuR/brsmarc1/MAINTAINERS b/board/BuR/brsmarc1/MAINTAINERS index 7421f61fc43..8716002c172 100644 --- a/board/BuR/brsmarc1/MAINTAINERS +++ b/board/BuR/brsmarc1/MAINTAINERS @@ -1,7 +1,8 @@ BRSMARC1 BOARD -M: Wolfgang Wallner <[email protected]> +M: Wolfgang Wallner <[email protected]> S: Maintained F: board/BuR/brsmarc1/ F: board/BuR/common/ F: include/configs/brsmarc1.h F: configs/brsmarc1_defconfig +F: arch/arm/dts/am335x-brsmarc1.dts diff --git a/board/BuR/brxre1/MAINTAINERS b/board/BuR/brxre1/MAINTAINERS index f826a44b6ac..b424ddca6ca 100644 --- a/board/BuR/brxre1/MAINTAINERS +++ b/board/BuR/brxre1/MAINTAINERS @@ -1,5 +1,5 @@ BRXRE1 BOARD -M: Wolfgang Wallner <[email protected]> +M: Wolfgang Wallner <[email protected]> S: Maintained F: board/BuR/brxre1/ F: board/BuR/common/ diff --git a/board/BuR/zynq/MAINTAINERS b/board/BuR/zynq/MAINTAINERS index d655cae58d4..e2b04980403 100644 --- a/board/BuR/zynq/MAINTAINERS +++ b/board/BuR/zynq/MAINTAINERS @@ -1,5 +1,5 @@ ZYNQ BOARD -M: Wolfgang Wallner <[email protected]> +M: Wolfgang Wallner <[email protected]> S: Maintained F: board/BuR/zynq/ F: board/BuR/common/ diff --git a/board/armltd/integrator/MAINTAINERS b/board/armltd/integrator/MAINTAINERS index 8af765eaebc..a228fc3daec 100644 --- a/board/armltd/integrator/MAINTAINERS +++ b/board/armltd/integrator/MAINTAINERS @@ -1,5 +1,5 @@ INTEGRATOR BOARD -M: Linus Walleij <[email protected]> +M: Linus Walleij <[email protected]> S: Maintained F: board/armltd/integrator/ F: include/configs/integratorcp.h diff --git a/board/armltd/vexpress64/MAINTAINERS b/board/armltd/vexpress64/MAINTAINERS index c38ab520c52..58ab5db7e4a 100644 --- a/board/armltd/vexpress64/MAINTAINERS +++ b/board/armltd/vexpress64/MAINTAINERS @@ -1,18 +1,18 @@ VEXPRESS64 PLATFORM M: David Feng <[email protected]> -M: Linus Walleij <[email protected]> +M: Linus Walleij <[email protected]> M: Peter Hoyes <[email protected]> S: Maintained F: board/armltd/vexpress64/ F: include/configs/vexpress_aemv8.h VEXPRESS_AEMV8A_SEMI BOARD -M: Linus Walleij <[email protected]> +M: Linus Walleij <[email protected]> S: Maintained F: configs/vexpress_aemv8a_semi_defconfig JUNO DEVELOPMENT PLATFORM BOARD -M: Linus Walleij <[email protected]> +M: Linus Walleij <[email protected]> S: Maintained F: configs/vexpress_aemv8a_juno_defconfig diff --git a/board/broadcom/bcmns/MAINTAINERS b/board/broadcom/bcmns/MAINTAINERS index 63c6d8bb4ac..4972d6cc934 100644 --- a/board/broadcom/bcmns/MAINTAINERS +++ b/board/broadcom/bcmns/MAINTAINERS @@ -1,5 +1,5 @@ BCMNS BOARD -M: Linus Walleij <[email protected]> +M: Linus Walleij <[email protected]> S: Maintained F: board/broadcom/bcmns/ F: configs/bcmns_defconfig diff --git a/board/raspberrypi/rpi/lowlevel_init.S b/board/raspberrypi/rpi/lowlevel_init.S index 8c39b3e12e8..30c0b0c27a8 100644 --- a/board/raspberrypi/rpi/lowlevel_init.S +++ b/board/raspberrypi/rpi/lowlevel_init.S @@ -16,7 +16,8 @@ save_boot_params: /* The firmware provided ATAG/FDT address can be found in r2/x0 */ #ifdef CONFIG_ARM64 - adr x8, fw_dtb_pointer + adrp x8, fw_dtb_pointer + add x8, x8, #:lo12:fw_dtb_pointer str x0, [x8] #else ldr r8, =fw_dtb_pointer diff --git a/board/raspberrypi/rpi/rpi.c b/board/raspberrypi/rpi/rpi.c index 1b0b664fa2b..f9b643555dd 100644 --- a/board/raspberrypi/rpi/rpi.c +++ b/board/raspberrypi/rpi/rpi.c @@ -3,6 +3,8 @@ * (C) Copyright 2012-2016 Stephen Warren */ +#define LOG_CATEGORY LOGC_BOARD + #include <config.h> #include <dm.h> #include <env.h> @@ -332,13 +334,27 @@ int dram_init(void) #ifdef CONFIG_OF_BOARD int dram_init_banksize(void) { + phys_addr_t total_size = 0; + int i; int ret; ret = fdtdec_setup_memory_banksize(); if (ret) return ret; - return fdtdec_setup_mem_size_base(); + ret = fdtdec_setup_mem_size_base(); + if (ret) + return ret; + + /* Update gd->ram_size to reflect total RAM across all banks */ + for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) { + if (gd->bd->bi_dram[i].size == 0) + break; + total_size += gd->bd->bi_dram[i].size; + } + gd->ram_size = total_size; + + return 0; } #endif @@ -354,15 +370,13 @@ static void set_fdtfile(void) } /* - * If the firmware provided a valid FDT at boot time, let's expose it in - * ${fdt_addr} so it may be passed unmodified to the kernel. + * Allow U-Boot to use its control FDT with extlinux if one is not provided. + * This will then go through the usual fixups that U-Boot does, before being + * handed off to Linux */ static void set_fdt_addr(void) { - if (fdt_magic(fw_dtb_pointer) != FDT_MAGIC) - return; - - env_set_hex("fdt_addr", fw_dtb_pointer); + env_set_hex("fdt_addr", (ulong)gd->fdt_blob); } /* @@ -608,7 +622,10 @@ int ft_board_setup(void *blob, struct bd_info *bd) { int node; - update_fdt_from_fw(blob, (void *)fw_dtb_pointer); + if (blob == gd->fdt_blob) + log_debug("Same FDT: nothing to do\n"); + else + update_fdt_from_fw(blob, (void *)gd->fdt_blob); if (CONFIG_IS_ENABLED(FDT_SIMPLEFB)) { node = fdt_node_offset_by_compatible(blob, -1, "simple-framebuffer"); diff --git a/board/renesas/MAINTAINERS b/board/renesas/MAINTAINERS index 13551cdd2b4..8571bb02576 100644 --- a/board/renesas/MAINTAINERS +++ b/board/renesas/MAINTAINERS @@ -6,7 +6,7 @@ N: grpeach N: r2dplus N: r7s72100 N: r8a66597 -N: r8a77 +N: r8a7[78] N: r9a0[0-9]g N: rcar N: renesas diff --git a/board/renesas/common/Makefile b/board/renesas/common/Makefile index 1849c995aee..889de8ea9ac 100644 --- a/board/renesas/common/Makefile +++ b/board/renesas/common/Makefile @@ -43,6 +43,10 @@ else obj-y += gen4-common.o endif endif + +ifdef CONFIG_RCAR_GEN5 +obj-y += gen5-common.o +endif endif endif diff --git a/board/renesas/common/gen5-common.c b/board/renesas/common/gen5-common.c new file mode 100644 index 00000000000..a05a3e8abef --- /dev/null +++ b/board/renesas/common/gen5-common.c @@ -0,0 +1,75 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2025 Renesas Electronics Corp. + */ + +#include <asm/arch/renesas.h> +#include <asm/arch/sys_proto.h> +#include <asm/global_data.h> +#include <asm/io.h> +#include <asm/mach-types.h> +#include <asm/processor.h> +#include <asm/system.h> +#include <linux/errno.h> + +DECLARE_GLOBAL_DATA_PTR; + +static void init_generic_timer(void) +{ + const u32 freq = CONFIG_SYS_CLK_FREQ; + + /* Update memory mapped and register based freqency */ + asm volatile ("msr cntfrq_el0, %0" :: "r" (freq)); + writel(freq, CNTFID0); + + /* Enable counter */ + setbits_le32(CNTCR_BASE, CNTCR_EN); +} + +static void init_gic_v3(void) +{ + /* GIC v3 power on */ + writel(BIT(1), GICR_LPI_PWRR); + + /* Wait till the WAKER_CA_BIT changes to 0 */ + clrbits_le32(GICR_LPI_WAKER, BIT(1)); + while (readl(GICR_LPI_WAKER) & BIT(2)) + ; + + writel(0xffffffff, GICR_SGI_BASE + GICR_IGROUPR0); +} + +void s_init(void) +{ + if (current_el() == 3) + init_generic_timer(); +} + +int board_early_init_f(void) +{ + return 0; +} + +int board_init(void) +{ + /* Allow WDT reset */ + writel(RST_KCPROT_DIS, RST_RESKCPROT0); + clrbits_le32(RST_WDTRSTCR, RST_WWDT_RSTMSK | RST_RWDT_RSTMSK); + + if (current_el() != 3) + return 0; + init_gic_v3(); + + return 0; +} + +void __weak reset_cpu(void) +{ + writel(RST_KCPROT_DIS, RST_RESKCPROT0); + writel(0x1, RST_SWSRES1A); +} + +int ft_board_setup(void *blob, struct bd_info *bd) +{ + return 0; +} diff --git a/board/renesas/ironhide/Kconfig b/board/renesas/ironhide/Kconfig new file mode 100644 index 00000000000..34b596714f3 --- /dev/null +++ b/board/renesas/ironhide/Kconfig @@ -0,0 +1,15 @@ +if TARGET_IRONHIDE + +config SYS_SOC + default "renesas" + +config SYS_BOARD + default "ironhide" + +config SYS_VENDOR + default "renesas" + +config SYS_CONFIG_NAME + default "ironhide" + +endif diff --git a/board/samsung/e850-96/Makefile b/board/samsung/e850-96/Makefile index 76b8d47994e..e9c62d3181f 100644 --- a/board/samsung/e850-96/Makefile +++ b/board/samsung/e850-96/Makefile @@ -3,4 +3,4 @@ # Copyright (C) 2024, Linaro Limited # Sam Protsenko <[email protected]> -obj-y := e850-96.o fw.o acpm.o pmic.o +obj-y := e850-96.o fw.o acpm.o pmic.o bootdev.o diff --git a/board/samsung/e850-96/bootdev.c b/board/samsung/e850-96/bootdev.c new file mode 100644 index 00000000000..7d5ae7128f4 --- /dev/null +++ b/board/samsung/e850-96/bootdev.c @@ -0,0 +1,99 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2025 Linaro Ltd. + * Author: Sam Protsenko <[email protected]> + * + * Routines for checking current boot device. + */ + +#include <linux/arm-smccc.h> +#include <vsprintf.h> +#include "bootdev.h" + +/* Flag from BL2 bootloader in RAM */ +#define BL2_TAG_ADDR 0x80000000 /* DRAM base */ +#define BL2_TAG 0xabcdef + +/* Boot device info location in iRAM (only accessible from EL3) */ +#define IRAM_BASE 0x02020000 +#define BOOTDEVICE_INFO_ADDR (IRAM_BASE + 0x64) + +/* SMC call for getting boot device information from EL3 monitor */ +#define SMC_CMD_CHECK_SECOND_BOOT -233 + +/* Boot device constants for the encoded boot device info value */ +#define BD_NO_DEVICE 0x0 +#define BD_UFS 0x1 +#define BD_EMMC 0x2 +#define BD_ERROR 0x3 +#define BD_USB 0x4 +#define BD_SDMMC 0x5 +#define BD_UFS_CARD 0x6 +#define BD_SPI 0x7 + +/* If BL2 bootloader wasn't executed, it means U-Boot is running via JTAG */ +static bool bootdev_is_jtag_session(void) +{ + u32 bl2_tag_val = *(u32 *)BL2_TAG_ADDR; + + return bl2_tag_val != BL2_TAG; +} + +/* Obtain boot device information encoded in 32-bit value */ +static u32 bootdev_get_info(void) +{ + u32 info; + + /* + * On regular boot U-Boot is executed by BL2 bootloader, and is running + * in EL1 mode, so the boot device information has to be obtained via + * SMC call from EL3 software (EL3 monitor), which can read that info + * from the protected iRAM memory. If U-Boot is running via TRACE32 JTAG + * (in EL3 mode), read the boot device info directly from iRAM, as EL3 + * software might not be available. + */ + if (bootdev_is_jtag_session()) { + info = *(u32 *)BOOTDEVICE_INFO_ADDR; + } else { + struct arm_smccc_res res; + + arm_smccc_smc(SMC_CMD_CHECK_SECOND_BOOT, 0, 0, 0, 0, 0, 0, 0, + &res); + info = (u32)res.a2; + } + + return info; +} + +enum bootdev bootdev_get_current(void) +{ + u32 info, magic, order, dev; + + info = bootdev_get_info(); + magic = info >> 24; + order = info & 0xf; + dev = (info >> (4 * order)) & 0xf; + + if (magic != 0xcb) + panic("Abnormal boot"); + + switch (dev) { + case BD_UFS: + return BOOTDEV_UFS; + case BD_EMMC: + return BOOTDEV_EMMC; + case BD_USB: + return BOOTDEV_USB; + case BD_SDMMC: + return BOOTDEV_SD; + default: + return BOOTDEV_ERROR; + } + + return BOOTDEV_ERROR; +} + +bool bootdev_is_usb(void) +{ + return bootdev_get_current() == BOOTDEV_USB; +} diff --git a/board/samsung/e850-96/bootdev.h b/board/samsung/e850-96/bootdev.h new file mode 100644 index 00000000000..5f454bf0090 --- /dev/null +++ b/board/samsung/e850-96/bootdev.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) 2025 Linaro Ltd. + * Sam Protsenko <[email protected]> + */ + +#ifndef __E850_96_BOOTDEV_H +#define __E850_96_BOOTDEV_H + +#include <stdbool.h> + +enum bootdev { + BOOTDEV_ERROR, + BOOTDEV_SD, + BOOTDEV_EMMC, + BOOTDEV_USB, + BOOTDEV_UFS, +}; + +enum bootdev bootdev_get_current(void); +bool bootdev_is_usb(void); + +#endif /* __E850_96_BOOTDEV_H */ diff --git a/board/samsung/e850-96/e850-96.c b/board/samsung/e850-96/e850-96.c index 3df241edde2..415505f2561 100644 --- a/board/samsung/e850-96/e850-96.c +++ b/board/samsung/e850-96/e850-96.c @@ -11,6 +11,7 @@ #include <net.h> #include <usb.h> #include <asm/io.h> +#include "bootdev.h" #include "fw.h" #include "pmic.h" @@ -31,6 +32,10 @@ #define EMMC_DEV_NUM 0 #define EMMC_ESP_PART 1 +/* Firmware size */ +#define LDFW_MAX_SIZE SZ_4M +#define SP_MAX_SIZE SZ_1M + struct efi_fw_image fw_images[] = { { .image_type_id = E850_96_FWBL1_IMAGE_GUID, @@ -77,16 +82,6 @@ static struct acpm acpm = { .ipc_ch = EXYNOS850_IPC_AP_I3C, }; -int dram_init(void) -{ - return fdtdec_setup_mem_size_base(); -} - -int dram_init_banksize(void) -{ - return fdtdec_setup_memory_banksize(); -} - /* Read the unique SoC ID from OTP registers */ static u64 get_chip_id(void) { @@ -137,11 +132,34 @@ static void setup_ethaddr(void) eth_env_set_enetaddr("ethaddr", mac_addr); } +static void load_firmware_usb(void) +{ + int err; + + printf("Loading LDFW firmware (over USB)...\n"); + err = load_image_usb(USB_DN_IMAGE_LDFW, LDFW_NWD_ADDR, LDFW_MAX_SIZE); + if (err) { + printf("ERROR: LDFW loading failed (%d)\n", err); + return; + } + + err = init_ldfw(LDFW_NWD_ADDR); + if (err) { + printf("ERROR: LDFW init failed (%d)\n", err); + /* Do not return, still need to download SP */ + } + + printf("Loading SP firmware (over USB)...\n"); + err = load_image_usb(USB_DN_IMAGE_SP, LDFW_NWD_ADDR, SP_MAX_SIZE); + if (err) + printf("ERROR: SP loading failed (%d)\n", err); +} + /* * Call this in board_late_init() to avoid probing block devices before * efi_init_early(). */ -void load_firmware(void) +static void load_firmware_blk(void) { const char *ifname; ulong dev, part; @@ -161,16 +179,41 @@ void load_firmware(void) } printf("Loading LDFW firmware (from %s %ld)...\n", ifname, dev); - err = load_ldfw(ifname, dev, part, LDFW_NWD_ADDR); - if (err) + err = load_ldfw_from_blk(ifname, dev, part, LDFW_NWD_ADDR); + if (err) { printf("ERROR: LDFW loading failed (%d)\n", err); + return; + } + err = init_ldfw(LDFW_NWD_ADDR); + if (err) + printf("ERROR: LDFW init failed (%d)\n", err); +} + +int dram_init(void) +{ + return fdtdec_setup_mem_size_base(); +} + +int dram_init_banksize(void) +{ + return fdtdec_setup_memory_banksize(); } int board_late_init(void) { setup_serial(); setup_ethaddr(); - load_firmware(); + + if (bootdev_is_usb()) + load_firmware_usb(); + else + load_firmware_blk(); + + if (bootdev_is_usb()) { + env_set("bootcmd", "echo \"Entering DFU mode...\"; " + "dfu 0 mmc 0"); + env_set("bootdelay", "0"); + } return 0; } diff --git a/board/samsung/e850-96/fw.c b/board/samsung/e850-96/fw.c index 64235c01a25..576167122ec 100644 --- a/board/samsung/e850-96/fw.c +++ b/board/samsung/e850-96/fw.c @@ -11,14 +11,19 @@ #include <linux/arm-smccc.h> #include "fw.h" -#define LDFW_RAW_PART "ldfw" -#define LDFW_FAT_PATH "/EFI/firmware/ldfw.bin" +#define LDFW_RAW_PART "ldfw" +#define LDFW_FAT_PATH "/EFI/firmware/ldfw.bin" +#define LDFW_MAGIC 0x10adab1e -#define LDFW_MAGIC 0x10adab1e -#define SMC_CMD_LOAD_LDFW -0x500 -#define SDM_HW_RESET_STATUS 0x1230 -#define SDM_SW_RESET_STATUS 0x1231 -#define SB_ERROR_PREFIX 0xfdaa0000 +/* SMC command for providing LDFW to EL3 monitor */ +#define SMC_CMD_LOAD_LDFW -0x500 +/* SMC command for loading some binary over USB */ +#define SMC_CMD_LOAD_IMAGE_BY_USB -0x512 + +/* Error codes for SMC_CMD_LOAD_LDFW */ +#define SDM_HW_RESET_STATUS 0x1230 +#define SDM_SW_RESET_STATUS 0x1231 +#define SB_ERROR_PREFIX 0xfdaa0000 struct ldfw_header { u32 magic; @@ -94,7 +99,27 @@ static int read_fw_from_raw(const char *ifname, int dev, const char *part_name, } /** - * load_ldfw - Load the loadable firmware (LDFW) + * load_image_usb - Load some binary over USB during USB boot + * @type: Image type + * @addr: Memory address where the image should be downloaded to + * @size: Image size + * + * Return: 0 on success or a negative value on error. + */ +int load_image_usb(enum usb_dn_image type, phys_addr_t addr, phys_size_t size) +{ + struct arm_smccc_res res; + + arm_smccc_smc(SMC_CMD_LOAD_IMAGE_BY_USB, (u64)type, addr, size, + 0, 0, 0, 0, &res); + if (res.a0) + return -EIO; + + return 0; +} + +/** + * load_ldfw_from_blk - Load the loadable firmware (LDFW) from block device * @ifname: Interface name of the block device to load the firmware from * @dev: Device number * @part: Partition number @@ -102,24 +127,37 @@ static int read_fw_from_raw(const char *ifname, int dev, const char *part_name, * * Return: 0 on success or a negative value on error. */ -int load_ldfw(const char *ifname, int dev, int part, phys_addr_t addr) +int load_ldfw_from_blk(const char *ifname, int dev, int part, phys_addr_t addr) { - struct ldfw_header *hdr; - struct arm_smccc_res res; void *buf = (void *)addr; - u64 size = 0; - int err, i; + int err; /* First try to read LDFW from EFI partition, then from the raw one */ err = read_fw_from_fat(ifname, dev, part, LDFW_FAT_PATH, buf); - if (err) { - err = read_fw_from_raw(ifname, dev, LDFW_RAW_PART, buf); - if (err) - return err; - } + if (err) + return read_fw_from_raw(ifname, dev, LDFW_RAW_PART, buf); + + return 0; +} + +/** + * init_ldfw - Provide the LDFW (loaded to RAM) to EL3 monitor to make use of it + * @addr: Memory address where LDFW resides + * + * EL3 monitor will copy the LDFW from the provided Normal World memory @addr to + * Secure World location, and start using it. + * + * Return: 0 on success or a negative value on error. + */ +int init_ldfw(phys_addr_t addr) +{ + struct ldfw_header *hdr; + struct arm_smccc_res res; + u64 size = 0; + int err, i; /* Validate LDFW by magic number in its header */ - hdr = buf; + hdr = (struct ldfw_header *)addr; if (hdr->magic != LDFW_MAGIC) { debug("%s: Wrong LDFW magic; is LDFW flashed?\n", __func__); return -EINVAL; diff --git a/board/samsung/e850-96/fw.h b/board/samsung/e850-96/fw.h index 73d9615d4a9..68f943e8bbc 100644 --- a/board/samsung/e850-96/fw.h +++ b/board/samsung/e850-96/fw.h @@ -9,6 +9,14 @@ #include <asm/types.h> -int load_ldfw(const char *ifname, int dev, int part, phys_addr_t addr); +/* Image types for downloading over USB */ +enum usb_dn_image { + USB_DN_IMAGE_LDFW = 1, /* Loadable Firmware */ + USB_DN_IMAGE_SP = 2, /* Secure Payload (tzsw.img) */ +}; + +int load_image_usb(enum usb_dn_image type, phys_addr_t addr, phys_size_t size); +int load_ldfw_from_blk(const char *ifname, int dev, int part, phys_addr_t addr); +int init_ldfw(phys_addr_t addr); #endif /* __E850_96_FW_H */ diff --git a/board/samsung/exynos-mobile/Kconfig b/board/samsung/exynos-mobile/Kconfig new file mode 100644 index 00000000000..ed7d16b8c6b --- /dev/null +++ b/board/samsung/exynos-mobile/Kconfig @@ -0,0 +1,18 @@ +if TARGET_EXYNOS_MOBILE + +config ENV_SOURCE_FILE + default "exynos-mobile" + +config LNX_KRNL_IMG_TEXT_OFFSET_BASE + default TEXT_BASE + +config SYS_BOARD + default "exynos-mobile" + +config SYS_CONFIG_NAME + default "exynos-mobile" + +config SYS_VENDOR + default "samsung" + +endif # TARGET_EXYNOS_MOBILE diff --git a/board/samsung/exynos-mobile/MAINTAINERS b/board/samsung/exynos-mobile/MAINTAINERS new file mode 100644 index 00000000000..11fea212fb1 --- /dev/null +++ b/board/samsung/exynos-mobile/MAINTAINERS @@ -0,0 +1,6 @@ +Exynos Generic Boards (for mobile devices) +M: Kaustabh Chakraborty <[email protected]> +S: Maintained +F: board/samsung/exynos-mobile/ +F: configs/exynos-mobile_defconfig +F: include/configs/exynos-mobile.h diff --git a/board/samsung/exynos-mobile/Makefile b/board/samsung/exynos-mobile/Makefile new file mode 100644 index 00000000000..e049ed217c1 --- /dev/null +++ b/board/samsung/exynos-mobile/Makefile @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0 +# +# Copyright (C) 2025 Kaustabh Chakraborty <[email protected]> + +obj-y := exynos-mobile.o diff --git a/board/samsung/exynos-mobile/debug-exynos7870.config b/board/samsung/exynos-mobile/debug-exynos7870.config new file mode 100644 index 00000000000..1aa506a675d --- /dev/null +++ b/board/samsung/exynos-mobile/debug-exynos7870.config @@ -0,0 +1,7 @@ +CONFIG_DEBUG_UART=y +CONFIG_DEBUG_UART_BASE=0x13820000 +CONFIG_DEBUG_UART_CLOCK=133250000 +CONFIG_DEBUG_UART_S5P=y +CONFIG_LOG=y +CONFIG_LOG_CONSOLE=y +CONFIG_LOG_MAX_LEVEL=8 diff --git a/board/samsung/exynos-mobile/exynos-mobile.c b/board/samsung/exynos-mobile/exynos-mobile.c new file mode 100644 index 00000000000..8ef38816abf --- /dev/null +++ b/board/samsung/exynos-mobile/exynos-mobile.c @@ -0,0 +1,403 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Samsung Exynos Generic Board Source (for mobile devices) + * + * Copyright (c) 2025 Kaustabh Chakraborty <[email protected]> + */ + +#include <asm/armv8/mmu.h> +#include <blk.h> +#include <bootflow.h> +#include <ctype.h> +#include <dm/ofnode.h> +#include <env.h> +#include <errno.h> +#include <init.h> +#include <limits.h> +#include <linux/sizes.h> +#include <lmb.h> +#include <part.h> +#include <stdbool.h> + +DECLARE_GLOBAL_DATA_PTR; + +#define lmb_alloc(size, addr) \ + lmb_alloc_mem(LMB_MEM_ALLOC_ANY, SZ_2M, addr, size, LMB_NONE) + +struct exynos_board_info { + const char *name; + const char *chip; + const u64 *const dram_bank_bases; + + char serial[64]; + + int (*const match)(struct exynos_board_info *); + const char *match_model; + const u8 match_max_rev; +}; + +/* + * The memory mapping includes all DRAM banks, along with the + * peripheral block, and a sentinel at the end. This is filled in + * dynamically. + */ +static struct mm_region exynos_mem_map[CONFIG_NR_DRAM_BANKS + 2] = { + { + /* Peripheral MMIO block */ + .virt = 0x10000000UL, + .phys = 0x10000000UL, + .size = 0x10000000UL, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN, + }, +}; + +struct mm_region *mem_map = exynos_mem_map; + +static const u64 exynos7870_common_dram_bank_bases[CONFIG_NR_DRAM_BANKS] = { + 0x40000000, 0x80000000, 0x100000000, +}; + +static const char *exynos_prev_bl_get_bootargs(void) +{ + void *prev_bl_fdt_base = (void *)get_prev_bl_fdt_addr(); + int chosen_node_offset, ret; + const struct fdt_property *bootargs_prop; + + ret = fdt_check_header(prev_bl_fdt_base); + if (ret < 0) { + log_err("%s: FDT is invalid (FDT_ERR %d)\n", __func__, ret); + return NULL; + } + + ret = fdt_path_offset(prev_bl_fdt_base, "/chosen"); + chosen_node_offset = ret; + if (ret < 0) { + log_err("%s: /chosen node not found (FDT_ERR %d)\n", __func__, + ret); + return NULL; + } + + bootargs_prop = fdt_get_property(prev_bl_fdt_base, chosen_node_offset, + "bootargs", &ret); + if (!bootargs_prop) { + log_err("%s: /chosen/bootargs property not found (FDT_ERR %d)\n", + __func__, ret); + return NULL; + } + + return bootargs_prop->data; +} + +static int exynos7870_fdt_match(struct exynos_board_info *board_info) +{ + const char *prev_bl_bootargs; + int val, ret; + + prev_bl_bootargs = exynos_prev_bl_get_bootargs(); + if (!prev_bl_bootargs) + return -1; + + /* + * Read the cmdline property which stores the + * bootloader/firmware version. An example value of the option + * can be: "J600GDXU3ARH5". This can be used to verify the model + * of the device. + */ + ret = cmdline_get_arg(prev_bl_bootargs, "androidboot.bootloader", &val); + if (ret < 0) { + log_err("%s: unable to find property for bootloader version (%d)\n", + __func__, ret); + return -1; + } + + if (strncmp(prev_bl_bootargs + val, board_info->match_model, + strlen(board_info->match_model))) + return -1; + + /* + * Read the cmdline property which stores the hardware revision. + * This is required to allow selecting one of multiple dtbs + * available of a single device, varying in hardware changes in + * different revisions. + */ + ret = cmdline_get_arg(prev_bl_bootargs, "androidboot.revision", &val); + if (ret < 0) + ret = cmdline_get_arg(prev_bl_bootargs, "androidboot.hw_rev", &val); + if (ret < 0) { + log_err("%s: unable to find property for bootloader revision (%d)\n", + __func__, ret); + return -1; + } + + if (strtoul(prev_bl_bootargs + val, NULL, 10) > board_info->match_max_rev) + return -1; + + /* + * Read the cmdline property which stores the serial number. + * Store this in the board info struct. + */ + ret = cmdline_get_arg(prev_bl_bootargs, "androidboot.serialno", &val); + if (ret > 0) + strlcpy(board_info->serial, prev_bl_bootargs + val, ret); + + return 0; +} + +/* + * This array is used for matching the models and revisions with the + * devicetree used by U-Boot. This allows a single U-Boot to work on + * multiple devices. + * + * Entries are kept in lexicographical order of board SoCs, followed by + * board names. + */ +static struct exynos_board_info exynos_board_info_match[] = { + { + /* Samsung Galaxy A2 Core */ + .name = "a2corelte", + .chip = "exynos7870", + .dram_bank_bases = exynos7870_common_dram_bank_bases, + .match = exynos7870_fdt_match, + .match_model = "A260", + .match_max_rev = U8_MAX, + }, { + /* Samsung Galaxy J6 */ + .name = "j6lte", + .chip = "exynos7870", + .dram_bank_bases = exynos7870_common_dram_bank_bases, + .match = exynos7870_fdt_match, + .match_model = "J600", + .match_max_rev = U8_MAX, + }, { + /* Samsung Galaxy J7 Prime */ + .name = "on7xelte", + .chip = "exynos7870", + .dram_bank_bases = exynos7870_common_dram_bank_bases, + .match = exynos7870_fdt_match, + .match_model = "G610", + .match_max_rev = U8_MAX, + }, +}; + +static void exynos_parse_dram_banks(const struct exynos_board_info *board_info, + const void *fdt_base) +{ + u64 mem_addr, mem_size = 0; + u32 na, ns, i, j; + int offset; + + if (fdt_check_header(fdt_base) < 0) + return; + + /* #address-cells and #size-cells as defined in the fdt root. */ + na = fdt_address_cells(fdt_base, 0); + ns = fdt_size_cells(fdt_base, 0); + + fdt_for_each_subnode(offset, fdt_base, 0) { + if (strncmp(fdt_get_name(fdt_base, offset, NULL), "memory", 6)) + continue; + + for (i = 0; ; i++) { + mem_addr = fdtdec_get_addr_size_fixed(fdt_base, offset, + "reg", i, na, ns, + &mem_size, false); + if (mem_addr == FDT_ADDR_T_NONE) + break; + + if (!mem_size) + continue; + + for (j = 0; j < CONFIG_NR_DRAM_BANKS; j++) { + if (board_info->dram_bank_bases[j] != mem_addr) + continue; + + mem_map[j + 1].phys = mem_addr; + mem_map[j + 1].virt = mem_addr; + mem_map[j + 1].size = mem_size; + mem_map[j + 1].attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | + PTE_BLOCK_INNER_SHARE; + break; + } + } + } +} + +static int exynos_fastboot_setup(void) +{ + struct blk_desc *blk_dev; + struct disk_partition info = {0}; + char buf[128]; + phys_addr_t addr; + int offset, i, j; + + /* Allocate and define buffer address for fastboot interface. */ + if (lmb_alloc(CONFIG_FASTBOOT_BUF_SIZE, &addr)) { + log_err("%s: failed to allocate fastboot buffer\n", __func__); + return -ENOMEM; + } + env_set_hex("fastboot_addr_r", addr); + + blk_dev = blk_get_dev("mmc", CONFIG_FASTBOOT_FLASH_MMC_DEV); + if (!blk_dev) { + log_err("%s: required mmc device not available\n", __func__); + return -ENODEV; + } + + strcpy(buf, "fastboot_partition_alias_"); + offset = strlen(buf); + + for (i = 1; i < CONFIG_EFI_PARTITION_ENTRIES_NUMBERS; i++) { + if (part_get_info(blk_dev, i, &info)) + continue; + + /* + * The partition name must be lowercase (stored in buf[]), + * as is expected in all fastboot partitions ... + */ + strlcpy(buf + offset, info.name, sizeof(buf) - offset); + for (j = offset; buf[j]; j++) + buf[j] = tolower(buf[j]); + if (!strcmp(buf + offset, info.name)) + continue; + /* + * ... However, if that isn't the case, a fastboot + * partition alias must be defined to establish it. + */ + env_set(buf, info.name); + } + + return 0; +} + +int board_fit_config_name_match(const char *name) +{ + struct exynos_board_info *board_info; + char buf[128]; + unsigned int i; + int ret; + + /* + * Iterate over exynos_board_info_match[] to select the + * appropriate board info struct. If not found, exit. + */ + for (i = 0; i < ARRAY_SIZE(exynos_board_info_match); i++) { + board_info = exynos_board_info_match + i; + snprintf(buf, sizeof(buf), "%s-%s", board_info->chip, + board_info->name); + + if (!strcmp(name, buf)) + break; + } + if (i == ARRAY_SIZE(exynos_board_info_match)) + return -1; + + /* + * Execute match logic for the target board. This is separated + * as the process may be different for multiple boards. + */ + ret = board_info->match(board_info); + if (ret) + return ret; + + /* + * Store the correct board info struct in gd->board_type to + * allow other functions to access it. + */ + gd->board_type = (ulong)board_info; + log_debug("%s: device detected: %s\n", __func__, name); + + return 0; +} + +int timer_init(void) +{ + ofnode timer_node; + + /* + * In a lot of Exynos devices, the previous bootloader does not + * set CNTFRQ_EL0 properly. However, the timer node in + * devicetree has the correct frequency, use that instead. + */ + timer_node = ofnode_by_compatible(ofnode_null(), "arm,armv8-timer"); + gd->arch.timer_rate_hz = ofnode_read_u32_default(timer_node, + "clock-frequency", 0); + + return 0; +} + +int board_early_init_f(void) +{ + const struct exynos_board_info *board_info; + + if (!gd->board_type) + return -ENODATA; + board_info = (const struct exynos_board_info *)gd->board_type; + + exynos_parse_dram_banks(board_info, gd->fdt_blob); + /* + * Some devices have multiple variants based on the amount of + * memory and internal storage. The lowest bank base has been + * observed to have the same memory range in all board variants. + * For variants with more memory, the previous bootloader should + * overlay the devicetree with the required extra memory ranges. + */ + exynos_parse_dram_banks(board_info, (const void *)get_prev_bl_fdt_addr()); + + return 0; +} + +int dram_init(void) +{ + unsigned int i; + + /* Select the largest RAM bank for U-Boot. */ + for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) { + if (gd->ram_size < mem_map[i + 1].size) { + gd->ram_base = mem_map[i + 1].phys; + gd->ram_size = mem_map[i + 1].size; + } + } + + return 0; +} + +int dram_init_banksize(void) +{ + unsigned int i; + + for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) { + gd->bd->bi_dram[i].start = mem_map[i + 1].phys; + gd->bd->bi_dram[i].size = mem_map[i + 1].size; + } + + return 0; +} + +int board_init(void) +{ + return 0; +} + +int misc_init_r(void) +{ + const struct exynos_board_info *board_info; + char buf[128]; + + if (!gd->board_type) + return -ENODATA; + board_info = (const struct exynos_board_info *)gd->board_type; + + env_set("platform", board_info->chip); + env_set("board", board_info->name); + + if (strlen(board_info->serial)) + env_set("serial#", board_info->serial); + + /* EFI booting requires the path to correct dtb, specify it here. */ + snprintf(buf, sizeof(buf), "exynos/%s-%s.dtb", board_info->chip, + board_info->name); + env_set("fdtfile", buf); + + return exynos_fastboot_setup(); +} diff --git a/board/samsung/exynos-mobile/exynos-mobile.env b/board/samsung/exynos-mobile/exynos-mobile.env new file mode 100644 index 00000000000..aa2e89afbac --- /dev/null +++ b/board/samsung/exynos-mobile/exynos-mobile.env @@ -0,0 +1,18 @@ +stdin=serial,button-kbd +stdout=serial,vidconsole +stderr=serial,vidconsole + +bootdelay=0 +bootcmd=bootefi bootmgr; pause; bootmenu + +fastbootcmd=echo "Fastboot Mode"; + fastboot -l $fastboot_addr_r usb 0 + +bootmenu_0=Continue Boot=boot +bootmenu_1=Enter Fastboot Mode=run fastbootcmd +bootmenu_2=UEFI Maintenance Menu=eficonfig +bootmenu_3=Reboot=reset +bootmenu_4=Power Off=poweroff + +button_cmd_0_name=Volume Down Key +button_cmd_0=bootmenu diff --git a/board/softing/vining_fpga/socfpga.c b/board/softing/vining_fpga/socfpga.c index ec2c7ea3631..475c19f2781 100644 --- a/board/softing/vining_fpga/socfpga.c +++ b/board/softing/vining_fpga/socfpga.c @@ -8,7 +8,7 @@ #include <env.h> #include <init.h> #include <net.h> -#include <status_led.h> +#include <led.h> #include <asm/arch/reset_manager.h> #include <asm/global_data.h> #include <asm/io.h> @@ -24,10 +24,16 @@ DECLARE_GLOBAL_DATA_PTR; int board_late_init(void) { const unsigned int usb_nrst_gpio = 35; + struct udevice *dev; int ret; - status_led_set(1, CONFIG_LED_STATUS_ON); - status_led_set(2, CONFIG_LED_STATUS_ON); + ret = led_get_by_label("status_1", &dev); + if (!ret) + led_set_state(dev, LEDST_ON); + + ret = led_get_by_label("status_2", &dev); + if (!ret) + led_set_state(dev, LEDST_ON); /* Address of boot parameters for ATAG (if ATAG is used) */ gd->bd->bi_boot_params = CFG_SYS_SDRAM_BASE + 0x100; diff --git a/board/ti/am335x/board.c b/board/ti/am335x/board.c index 712818ec235..90e37a8d913 100644 --- a/board/ti/am335x/board.c +++ b/board/ti/am335x/board.c @@ -429,7 +429,7 @@ void scale_vcores_generic(int freq) { int sil_rev, mpu_vdd; - if (!IS_ENABLED(CONFIG_DM_PMIC_TPS65910)) + if (!IS_ENABLED(CONFIG_SPL_POWER_TPS65910)) return; /* diff --git a/board/ti/am62x/evm.c b/board/ti/am62x/evm.c index 6bb243ee597..e9eba57eba7 100644 --- a/board/ti/am62x/evm.c +++ b/board/ti/am62x/evm.c @@ -82,11 +82,16 @@ struct efi_capsule_update_info update_info = { }; #if CONFIG_IS_ENABLED(TI_I2C_BOARD_DETECT) +int do_board_detect(void) +{ + return do_board_detect_am6(); +} + int checkboard(void) { struct ti_am6_eeprom *ep = TI_AM6_EEPROM_DATA; - if (!do_board_detect_am6()) + if (!do_board_detect()) printf("Board: %s rev %s\n", ep->name, ep->version); return 0; @@ -97,7 +102,7 @@ static void setup_board_eeprom_env(void) { char *name = "am62x_skevm"; - if (do_board_detect_am6()) + if (do_board_detect()) goto invalid_eeprom; if (board_is_am62x_skevm()) diff --git a/board/ti/am64x/evm.c b/board/ti/am64x/evm.c index 3688cf2ca25..25076a8a588 100644 --- a/board/ti/am64x/evm.c +++ b/board/ti/am64x/evm.c @@ -114,11 +114,16 @@ void spl_perform_board_fixups(struct spl_image_info *spl_image) #endif #ifdef CONFIG_TI_I2C_BOARD_DETECT +int do_board_detect(void) +{ + return do_board_detect_am6(); +} + int checkboard(void) { struct ti_am6_eeprom *ep = TI_AM6_EEPROM_DATA; - if (!do_board_detect_am6()) + if (!do_board_detect()) printf("Board: %s rev %s\n", ep->name, ep->version); return 0; @@ -135,7 +140,7 @@ static void setup_board_eeprom_env(void) { char *name = "am64x_gpevm"; - if (do_board_detect_am6()) + if (do_board_detect()) goto invalid_eeprom; if (board_is_am64x_gpevm()) diff --git a/board/ti/am65x/evm.c b/board/ti/am65x/evm.c index 68606746d5f..b35a9229033 100644 --- a/board/ti/am65x/evm.c +++ b/board/ti/am65x/evm.c @@ -72,11 +72,16 @@ int board_fit_config_name_match(const char *name) #endif #ifdef CONFIG_TI_I2C_BOARD_DETECT +int do_board_detect(void) +{ + return do_board_detect_am6(); +} + int checkboard(void) { struct ti_am6_eeprom *ep = TI_AM6_EEPROM_DATA; - if (do_board_detect_am6()) + if (do_board_detect()) /* EEPROM not populated */ printf("Board: %s rev %s\n", "AM6-COMPROCEVM", "E3"); else @@ -89,7 +94,7 @@ static void setup_board_eeprom_env(void) { char *name = "am65x"; - if (do_board_detect_am6()) + if (do_board_detect()) goto invalid_eeprom; if (board_is_am65x_base_board()) diff --git a/board/ti/common/board_detect.c b/board/ti/common/board_detect.c index d49e26fa453..a235ea9ef21 100644 --- a/board/ti/common/board_detect.c +++ b/board/ti/common/board_detect.c @@ -825,7 +825,7 @@ bool __maybe_unused board_ti_was_eeprom_read(void) return false; } -#if CONFIG_IS_ENABLED(TI_I2C_BOARD_DETECT) +#if IS_ENABLED(CONFIG_TI_I2C_BOARD_DETECT) int do_board_detect_am6(void) { int ret; diff --git a/board/ti/omap3evm/MAINTAINERS b/board/ti/omap3evm/MAINTAINERS index fb4268b312f..491ab4fbed7 100644 --- a/board/ti/omap3evm/MAINTAINERS +++ b/board/ti/omap3evm/MAINTAINERS @@ -1,5 +1,5 @@ EVM BOARD -M: Derald D. Woods <[email protected]> +M: Tom Rini <[email protected]> S: Maintained F: board/ti/omap3evm/ F: include/configs/omap3_evm.h |
