* [PATCH 0/9] ARM: K3 updates @ 2025-02-05 9:48 Sascha Hauer 2025-02-05 9:48 ` [PATCH 1/9] ARM: k3: Add function to enable 32k crystal Sascha Hauer ` (8 more replies) 0 siblings, 9 replies; 10+ messages in thread From: Sascha Hauer @ 2025-02-05 9:48 UTC (permalink / raw) To: open list:BAREBOX This series has some updates for the TI K3 architecture. We add support for bootstrapping boards via USB DFU. This has been sent earlier, this time booting from eMMC is added as well. On K3 SoCs we need a bunch of images after the first stage has been loaded: OP-TEE, ti-dm firmware, TF-A binary and finally a barebox binary. Until now these are expected as distinct images on the SD cards FAT partition. This is impractical for booting from eMMC boot partitions and also DFU boot, so this series adds support for handling a FIP image containing these binaries. Also some misc patches like enabling the 32k crystal needed for accurate RTC frequency Sascha Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> --- Sascha Hauer (9): ARM: k3: Add function to enable 32k crystal ARM: k3: add function to detect eMMC boot ARM: k3: do not mount /boot when booting from eMMC ARM: k3: r5: add USB DFU and eMMC boot support ARM: am625-sk: enable 32k crystal mci: am654: parse generic mmc node properties ARM: k3: limit eMMC frequency to 25MHz ARM: am625-sk: put environment on eMMC when booting from it serial: omap: Use ttyS as Linux console name Documentation/boards/ti-k3.rst | 47 +++++ arch/arm/boards/am625-sk/Makefile | 1 + arch/arm/boards/am625-sk/board.c | 35 ++++ arch/arm/dts/k3-am625-beagleplay.dts | 4 + arch/arm/dts/k3-am625-sk.dts | 19 ++ arch/arm/mach-k3/common.c | 36 ++++ arch/arm/mach-k3/r5.c | 367 ++++++++++++++++++++++++++++++++--- drivers/mci/am654-sdhci.c | 1 + drivers/serial/serial_ns16550.c | 4 +- include/mach/k3/common.h | 9 + 10 files changed, 490 insertions(+), 33 deletions(-) --- base-commit: a40a4c0d054f3b6aac272236c982d24c4ac72eaa change-id: 20250205-k3-emmc-eaa3df9f3ffd Best regards, -- Sascha Hauer <s.hauer@pengutronix.de> ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 1/9] ARM: k3: Add function to enable 32k crystal 2025-02-05 9:48 [PATCH 0/9] ARM: K3 updates Sascha Hauer @ 2025-02-05 9:48 ` Sascha Hauer 2025-02-05 9:48 ` [PATCH 2/9] ARM: k3: add function to detect eMMC boot Sascha Hauer ` (7 subsequent siblings) 8 siblings, 0 replies; 10+ messages in thread From: Sascha Hauer @ 2025-02-05 9:48 UTC (permalink / raw) To: open list:BAREBOX The external 32k crystal is optional and by default LFOSC0 is sourced by a RC oscillator. This adds a function to be called by board code when the 32k crystal is present and shall be used to source LFOSC0 from the crystal. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> --- arch/arm/mach-k3/common.c | 20 ++++++++++++++++++++ include/mach/k3/common.h | 1 + 2 files changed, 21 insertions(+) diff --git a/arch/arm/mach-k3/common.c b/arch/arm/mach-k3/common.c index 3922a0ff19..c779e873c9 100644 --- a/arch/arm/mach-k3/common.c +++ b/arch/arm/mach-k3/common.c @@ -170,6 +170,26 @@ static void of_delete_node_path(struct device_node *root, const char *path) of_delete_node(np); } +#define MCU_CTRL_MMR0_BASE 0x04500000 +#define MCU_CTRL_LFXOSC_CTRL (MCU_CTRL_MMR0_BASE + 0x8038) +#define MCU_CTRL_LFXOSC_32K_DISABLE_VAL BIT(7) +#define MCU_CTRL_DEVICE_CLKOUT_LFOSC_SELECT_VAL (0x3) +#define MCU_CTRL_DEVICE_CLKOUT_32K_CTRL (MCU_CTRL_MMR0_BASE + 0x8058) + +void am625_enable_32k_crystal(void) +{ + u32 val; + + /* Enable 32k crystal */ + val = readl(MCU_CTRL_LFXOSC_CTRL); + val &= ~(MCU_CTRL_LFXOSC_32K_DISABLE_VAL); + writel(val, MCU_CTRL_LFXOSC_CTRL); + + /* select 32k clock from LFOSC0 */ + writel(MCU_CTRL_DEVICE_CLKOUT_LFOSC_SELECT_VAL, + MCU_CTRL_DEVICE_CLKOUT_32K_CTRL); +} + #define CTRLMMR_WKUP_JTAG_DEVICE_ID (AM625_WKUP_CTRL_MMR0_BASE + 0x18) #define JTAG_DEV_CORE_NR GENMASK(21, 19) diff --git a/include/mach/k3/common.h b/include/mach/k3/common.h index d7ceea51d7..3377dc8895 100644 --- a/include/mach/k3/common.h +++ b/include/mach/k3/common.h @@ -6,5 +6,6 @@ void am625_get_bootsource(enum bootsource *src, int *instance); u64 am625_sdram_size(void); void am625_register_dram(void); +void am625_enable_32k_crystal(void); #endif /* __MACH_K3_COMMON_H */ -- 2.39.5 ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 2/9] ARM: k3: add function to detect eMMC boot 2025-02-05 9:48 [PATCH 0/9] ARM: K3 updates Sascha Hauer 2025-02-05 9:48 ` [PATCH 1/9] ARM: k3: Add function to enable 32k crystal Sascha Hauer @ 2025-02-05 9:48 ` Sascha Hauer 2025-02-05 9:48 ` [PATCH 3/9] ARM: k3: do not mount /boot when booting from eMMC Sascha Hauer ` (6 subsequent siblings) 8 siblings, 0 replies; 10+ messages in thread From: Sascha Hauer @ 2025-02-05 9:48 UTC (permalink / raw) To: open list:BAREBOX Booting from eMMC on K3 SoCs requires some special handling. With SD card boot we put the environment in the boot FAT partition whereas with eMMC boot we want to put it into the raw eMMC device. Also with eMMC boot we have to load the subsequent stages from the eMMC boot partitions and from the boot FAT otherwise. Add a function to detect eMMC boot to base these decisions on. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> --- arch/arm/mach-k3/common.c | 13 +++++++++++++ include/mach/k3/common.h | 1 + 2 files changed, 14 insertions(+) diff --git a/arch/arm/mach-k3/common.c b/arch/arm/mach-k3/common.c index c779e873c9..7ded1f3f04 100644 --- a/arch/arm/mach-k3/common.c +++ b/arch/arm/mach-k3/common.c @@ -162,6 +162,19 @@ void am625_get_bootsource(enum bootsource *src, int *instance) k3_get_bootsource(devstat, src, instance); } +bool k3_boot_is_emmc(void) +{ + u32 bootmode = readl(AM625_BOOT_PARAM_TABLE_INDEX_OCRAM); + u32 devstat = readl(AM625_CTRLMMR_MAIN_DEVSTAT); + + if (bootmode != K3_PRIMARY_BOOTMODE) + return false; + if (FIELD_GET(MAIN_DEVSTAT_PRIMARY_BOOTMODE, devstat) != BOOT_DEVICE_EMMC) + return false; + + return true; +} + static void of_delete_node_path(struct device_node *root, const char *path) { struct device_node *np; diff --git a/include/mach/k3/common.h b/include/mach/k3/common.h index 3377dc8895..7f0796f7f4 100644 --- a/include/mach/k3/common.h +++ b/include/mach/k3/common.h @@ -4,6 +4,7 @@ #include <bootsource.h> void am625_get_bootsource(enum bootsource *src, int *instance); +bool k3_boot_is_emmc(void); u64 am625_sdram_size(void); void am625_register_dram(void); void am625_enable_32k_crystal(void); -- 2.39.5 ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 3/9] ARM: k3: do not mount /boot when booting from eMMC 2025-02-05 9:48 [PATCH 0/9] ARM: K3 updates Sascha Hauer 2025-02-05 9:48 ` [PATCH 1/9] ARM: k3: Add function to enable 32k crystal Sascha Hauer 2025-02-05 9:48 ` [PATCH 2/9] ARM: k3: add function to detect eMMC boot Sascha Hauer @ 2025-02-05 9:48 ` Sascha Hauer 2025-02-05 9:48 ` [PATCH 4/9] ARM: k3: r5: add USB DFU and eMMC boot support Sascha Hauer ` (5 subsequent siblings) 8 siblings, 0 replies; 10+ messages in thread From: Sascha Hauer @ 2025-02-05 9:48 UTC (permalink / raw) To: open list:BAREBOX When booting from eMMC we load the subsequent stages from eMMC boot partitions, so we do not need a boot FAT partition on eMMC. We can use an unpartitioned area in the eMMC user area in this case, so bail out from mounting /boot when eMMC boot is detected. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> --- arch/arm/mach-k3/common.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm/mach-k3/common.c b/arch/arm/mach-k3/common.c index 7ded1f3f04..97cb46d58e 100644 --- a/arch/arm/mach-k3/common.c +++ b/arch/arm/mach-k3/common.c @@ -275,6 +275,9 @@ static int omap_env_init(void) if (bootsource_get() != BOOTSOURCE_MMC) return 0; + if (k3_boot_is_emmc()) + return 0; + instance = bootsource_get_instance(); cdevname = xasprintf("mmc%d", instance); -- 2.39.5 ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 4/9] ARM: k3: r5: add USB DFU and eMMC boot support 2025-02-05 9:48 [PATCH 0/9] ARM: K3 updates Sascha Hauer ` (2 preceding siblings ...) 2025-02-05 9:48 ` [PATCH 3/9] ARM: k3: do not mount /boot when booting from eMMC Sascha Hauer @ 2025-02-05 9:48 ` Sascha Hauer 2025-02-05 9:48 ` [PATCH 5/9] ARM: am625-sk: enable 32k crystal Sascha Hauer ` (4 subsequent siblings) 8 siblings, 0 replies; 10+ messages in thread From: Sascha Hauer @ 2025-02-05 9:48 UTC (permalink / raw) To: open list:BAREBOX This patch adds USB DFU and eMMC boot support for the k3 SoCs. DFU mode is entered when the SoC is booted from USB. For continuing the boot we need several binaries (bl31, OP-TEE, barebox, ti-dm firmware), these can be uploaded as distinct files or combined together as a FIP image. This patch also adds the possibility to put a FIP image on the SD/eMMC card which is then preferred over the distinct files which were previously expected on SD/eMMC cards. Also the K3 SoCs have a boot mode to boot from eMMC boot partitions for which this patch adds support. When this bootmode is selected the tiboot3.bin file is loaded from the active boot partition. We then need to load the FIP image from the same boot partition. This image is expected to be at offset 1MiB in the boot partition. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> --- Documentation/boards/ti-k3.rst | 47 ++++++ arch/arm/mach-k3/r5.c | 367 +++++++++++++++++++++++++++++++++++++---- include/mach/k3/common.h | 7 + 3 files changed, 390 insertions(+), 31 deletions(-) diff --git a/Documentation/boards/ti-k3.rst b/Documentation/boards/ti-k3.rst index a1bf0b92e8..4b3822c020 100644 --- a/Documentation/boards/ti-k3.rst +++ b/Documentation/boards/ti-k3.rst @@ -69,6 +69,9 @@ OP-TEE is built from https://github.com/OP-TEE/optee_os.git:: PLATFORM=k3-am62x cp out/arm-plat-k3/core/tee-raw.bin $TI_BOOT/optee.bin +OP-TEE is optional. barebox will continue without ``optee.bin`` when the file +does not exist. + Copying ti-dm.bin ----------------- @@ -77,3 +80,47 @@ copied to the eMMC/SD as well:: cp $TI_LINUX_FIRMWARE/ti-dm/am62xx/ipc_echo_testb_mcu1_0_release_strip.xer5f $TI_BOOT/ti-dm.bin +Combining binaries into a FIP image +----------------------------------- + +Alternatively to putting the different binaries (``barebox.bin``, ``bl31.bin``, ``optee.bin`` +and ``ti-dm.bin``) into the FAT image the files can be combined into a FIP image named +``k3.fip``.:: + + fiptool create --soc-fw bl31.bin \ + --tos-fw optee.bin \ + --nt-fw barebox-beagleplay.img \ + --blob uuid=9e8c2017-8b94-4e2b-a7b3-a0f88eabb8ae,file=ti-dm.bin k3.fip + +USB DFU boot +------------ +K3 Boards can be booted via USB DFU. When in USB boot mode the initial stage can be uploaded +using ``dfu-util``:: + + dfu-util -D barebox-beagleplay-r5.img -a bootloader + +This will start the initial stage which then expects the following stages which can +be uploaded with ``dfu-util`` as well, either as FIP image:: + + dfu-util -D k3.fip -a fip + +or as separate files:: + + dfu-util -D blb31.bin -a tfa + dfu-util -D optee.bin -a optee + dfu-util -D ti-dm.bin -a ti-dm + dfu-util -D barebox-beagleplay.img -a barebox + +Uploading optee.bin can be skipped in case it's not needed. + +eMMC boot +--------- +K3 boards can boot from eMMC boot partitions. In this mode the ROM reads the tiboot3.bin +raw from the active boot partition. In this mode barebox expects the FIP image with the +following stages in the same boot partition at offset 1MiB. There is a barebox update handler +which takes a combined image consisting of tiboot3.bin and the FIP image to allow for a +failsafe update. This image can't be generated by the barebox build system though. It has +to be generated by a build system or manually:: + + dd if=images/barebox-beagleplay-r5.img of=barebox-beagleplay-emmc.img + dd if=k3.fip of=barebox-beagleplay-emmc.img bs=1024 seek=1024 diff --git a/arch/arm/mach-k3/r5.c b/arch/arm/mach-k3/r5.c index 32d98fe89a..8fa65eaaf9 100644 --- a/arch/arm/mach-k3/r5.c +++ b/arch/arm/mach-k3/r5.c @@ -6,6 +6,7 @@ #include <init.h> #include <libfile.h> #include <fs.h> +#include <fip.h> #include <firmware.h> #include <linux/remoteproc.h> #include <soc/ti/ti_sci_protocol.h> @@ -14,6 +15,10 @@ #include <asm/cache.h> #include <linux/sizes.h> #include <barebox.h> +#include <bootsource.h> +#include <linux/usb/gadget-multi.h> +#include <mach/k3/common.h> +#include <mci.h> #define RTC_BASE_ADDRESS 0x2b1f0000 #define K3RTC_KICK0_UNLOCK_VALUE 0x83e70b13 @@ -217,38 +222,279 @@ void am625_early_init(void) ti_pd_wait(pd_base, 0); } +#if IN_PROPER + /* * The bl31 and optee binaries are relocatable, but these addresses * are hardcoded as reserved mem regions in the upstream device trees. */ -#define BL31_ADDRESS 0x9e780000 -#define OPTEE_ADDRESS 0x9e800000 +#define BL31_ADDRESS (void *)0x9e780000 +#define BL32_ADDRESS (void *)0x9e800000 +#define BAREBOX_ADDRESS (void *)0x80080000 -static int k3_r5_start_image(void) +static void *k3_ti_dm; + +static bool have_bl31; +static bool have_bl32; +static bool have_bl33; + +static uuid_t uuid_bl31 = UUID_EL3_RUNTIME_FIRMWARE_BL31; +static uuid_t uuid_ti_dm_fw = UUID_TI_DM_FW; +static uuid_t uuid_bl33 = UUID_NON_TRUSTED_FIRMWARE_BL33; +static uuid_t uuid_bl32 = UUID_SECURE_PAYLOAD_BL32; + +struct fip_image { + struct list_head entries; + void *buf; +}; + +struct fip_image_entry { + struct fip_toc_entry entry; + struct list_head list; +}; + +static void fip_image_free(struct fip_image *fip_image) { - int err; - void *ti_dm_buf; - ssize_t size; - struct firmware fw; - const struct ti_sci_handle *ti_sci; - void *bl31 = (void *)BL31_ADDRESS; - void *barebox = (void *)0x80080000; - void *optee = (void *)OPTEE_ADDRESS; - struct elf_image *elf; - void __noreturn (*ti_dm)(void); - struct rproc *arm64_rproc; + struct fip_image_entry *e, *tmp; - ti_sci = ti_sci_get_handle(NULL); - if (IS_ERR(ti_sci)) - return -EINVAL; + if (!fip_image) + return; - arm64_rproc = ti_k3_am64_get_handle(); - if (!arm64_rproc) { - pr_err("Cannot get rproc handle\n"); - return -EINVAL; + list_for_each_entry_safe(e, tmp, &fip_image->entries, list) + free(e); + + free(fip_image->buf); + free(fip_image); +} + +static struct fip_image *open_fip(const char *filename, size_t offset) +{ + fip_toc_header_t toc_header; + int ret; + int fd; + struct fip_image *fip_image = NULL; + LIST_HEAD(entries); + size_t fip_headers_size, total = 0; + struct fip_image_entry *e; + off_t pos; + int n_entries = 0; + + fd = open(filename, O_RDONLY); + if (fd < 0) + return ERR_PTR(fd); + + pos = lseek(fd, offset, SEEK_SET); + if (pos != offset) { + ret = -EINVAL; + goto err; + } + + fip_image = xzalloc(sizeof(*fip_image)); + INIT_LIST_HEAD(&fip_image->entries); + + ret = read_full(fd, &toc_header, sizeof(toc_header)); + if (ret < 0) + goto err; + + if (ret < sizeof(toc_header)) { + ret = -ENODATA; + goto err; + } + + if (toc_header.name != TOC_HEADER_NAME) { + pr_err("%s is not a FIP file: unknown magic = 0x%08x\n", + filename, toc_header.name); + ret = -EINVAL; + goto err; + } + + /* read all toc entries */ + while (1) { + struct fip_image_entry *entry = xzalloc(sizeof(*entry)); + struct fip_toc_entry *toc_entry = &entry->entry; + + ret = read_full(fd, toc_entry, sizeof(*toc_entry)); + if (ret < 0) + goto err; + if (ret < sizeof(*toc_entry)) { + ret = -ENODATA; + goto err; + } + + list_add_tail(&entry->list, &fip_image->entries); + + pr_debug("Read TOC entry %pU %llu %llu\n", &toc_entry->uuid, + toc_entry->offset_address, toc_entry->size); + + /* Found the ToC terminator, we are done. */ + if (memcmp(&toc_entry->uuid, &uuid_null, sizeof(uuid_t)) == 0) + break; + } + + /* determine buffer size */ + list_for_each_entry(e, &fip_image->entries, list) { + uint64_t this_end = e->entry.offset_address + e->entry.size; + + if (this_end > total) + total = this_end; + n_entries++; + } + + fip_headers_size = n_entries * sizeof(struct fip_toc_entry) + sizeof(fip_toc_header_t); + + total -= fip_headers_size; + + fip_image->buf = malloc(total); + if (!fip_image->buf) { + ret = -ENOMEM; + goto err; + } + + ret = read_full(fd, fip_image->buf, total); + if (ret < 0) + goto err; + + if (ret < total) { + ret = -ENODATA; + goto err; } - size = read_file_into_buf("/boot/optee.bin", optee, SZ_32M); + close(fd); + + list_for_each_entry(e, &fip_image->entries, list) + e->entry.offset_address -= fip_headers_size; + + return fip_image; +err: + close(fd); + fip_image_free(fip_image); + + return ERR_PTR(ret); +} + +static void fip_copy(struct fip_image *fip_image) +{ + struct fip_image_entry *e; + void *buf = fip_image->buf; + + list_for_each_entry(e, &fip_image->entries, list) { + struct fip_toc_entry *toc_entry = &e->entry; + + if (!memcmp(&toc_entry->uuid, &uuid_bl31, sizeof(uuid_t))) { + memcpy(BL31_ADDRESS, buf + toc_entry->offset_address, toc_entry->size); + have_bl31 = true; + } + + if (!memcmp(&toc_entry->uuid, &uuid_bl33, sizeof(uuid_t))) { + memcpy(BAREBOX_ADDRESS, buf + toc_entry->offset_address, toc_entry->size); + have_bl33 = true; + } + + if (!memcmp(&toc_entry->uuid, &uuid_bl32, sizeof(uuid_t))) { + memcpy(BL32_ADDRESS, buf + toc_entry->offset_address, toc_entry->size); + have_bl32 = true; + } + + if (!memcmp(&toc_entry->uuid, &uuid_ti_dm_fw, sizeof(uuid_t))) { + k3_ti_dm = xmemdup(buf + toc_entry->offset_address, toc_entry->size); + } + } +} + +static int load_fip(const char *filename, off_t offset) +{ + struct fip_image *fip_image; + + fip_image = open_fip(filename, offset); + if (IS_ERR(fip_image)) { + pr_err("Cannot open FIP image: %pe\n", fip_image); + return PTR_ERR(fip_image); + } + + fip_copy(fip_image); + + fip_image_free(fip_image); + + return 0; +} + +static void do_dfu(void) +{ + struct usbgadget_funcs funcs = {}; + int ret; + struct stat s; + ssize_t size; + + funcs.flags |= USBGADGET_DFU; + funcs.dfu_opts = "/optee.bin(optee)c," + "/bl31.bin(tfa)c," + "/ti-dm.bin(ti-dm)c," + "/barebox.bin(barebox)cs," + "/fip.img(fip)cs"; + + ret = usbgadget_prepare_register(&funcs); + if (ret) + goto err; + + while (1) { + if (!have_bl32) { + size = read_file_into_buf("/optee.bin", BL32_ADDRESS, SZ_32M); + if (size > 0) { + printf("Downloaded OP-TEE\n"); + have_bl32 = true; + } + } + + if (!have_bl31) { + size = read_file_into_buf("/bl31.bin", BL31_ADDRESS, SZ_32M); + if (size > 0) { + printf("Downloaded TF-A\n"); + have_bl31 = true; + } + } + + if (!k3_ti_dm) { + ret = read_file_2("/ti-dm.bin", &size, &k3_ti_dm, FILESIZE_MAX); + if (!ret) { + printf("Downloaded TI-DM\n"); + } + } + + size = read_file_into_buf("/barebox.bin", BAREBOX_ADDRESS, SZ_32M); + if (size > 0) { + have_bl33 = true; + printf("Downloaded barebox image, DFU done\n"); + break; + } + + ret = stat("/fip.img", &s); + if (!ret) { + printf("Downloaded FIP image, DFU done\n"); + load_fip("/fip.img", 0); + break; + } + + command_slice_release(); + mdelay(50); + command_slice_acquire(); + }; + + return; + +err: + pr_err("DFU failed with: %pe\n", ERR_PTR(ret)); +} + +static int load_images(void) +{ + ssize_t size; + int err; + + err = load_fip("/boot/k3.fip", 0); + if (!err) + return 0; + + size = read_file_into_buf("/boot/optee.bin", BL32_ADDRESS, SZ_32M); if (size < 0) { if (size != -ENOENT) { pr_err("Cannot load optee.bin: %pe\n", ERR_PTR(size)); @@ -256,31 +502,89 @@ static int k3_r5_start_image(void) } pr_info("optee.bin not found, continue without\n"); } else { - pr_debug("Loaded optee.bin (size %u) to 0x%p\n", size, optee); + pr_debug("Loaded optee.bin (size %u) to 0x%p\n", size, BL32_ADDRESS); } - size = read_file_into_buf("/boot/barebox.bin", barebox, optee - barebox); + size = read_file_into_buf("/boot/barebox.bin", BAREBOX_ADDRESS, SZ_32M); if (size < 0) { pr_err("Cannot load barebox.bin: %pe\n", ERR_PTR(size)); return size; } - pr_debug("Loaded barebox.bin (size %u) to 0x%p\n", size, barebox); + pr_debug("Loaded barebox.bin (size %u) to 0x%p\n", size, BAREBOX_ADDRESS); - size = read_file_into_buf("/boot/bl31.bin", bl31, barebox - optee); + size = read_file_into_buf("/boot/bl31.bin", BL31_ADDRESS, SZ_32M); if (size < 0) { pr_err("Cannot load bl31.bin: %pe\n", ERR_PTR(size)); return size; } - pr_debug("Loaded bl31.bin (size %u) to 0x%p\n", size, bl31); + pr_debug("Loaded bl31.bin (size %u) to 0x%p\n", size, BL31_ADDRESS); - err = read_file_2("/boot/ti-dm.bin", &size, &ti_dm_buf, FILESIZE_MAX); + err = read_file_2("/boot/ti-dm.bin", &size, &k3_ti_dm, FILESIZE_MAX); if (err) { pr_err("Cannot load ti-dm.bin: %pe\n", ERR_PTR(err)); return err; } pr_debug("Loaded ti-dm.bin (size %u)\n", size); - elf = elf_open_binary(ti_dm_buf); + return 0; +} + +static int load_fip_emmc(void) +{ + int bootpart; + struct mci *mci; + char *fname; + const char *mmcdev = "mmc0"; + + device_detect_by_name(mmcdev); + + mci = mci_get_device_by_name(mmcdev); + if (!mci) + return -EINVAL; + + bootpart = mci->bootpart; + + if (bootpart != 1 && bootpart != 2) { + pr_err("Unexpected bootpart value %d\n", bootpart); + bootpart = 1; + } + + fname = xasprintf("/dev/%s.boot%d", mmcdev, bootpart - 1); + + load_fip(fname, K3_EMMC_BOOTPART_TIBOOT3_BIN_SIZE); + + free(fname); + + return 0; +} + +static int k3_r5_start_image(void) +{ + int err; + struct firmware fw; + const struct ti_sci_handle *ti_sci; + struct elf_image *elf; + void __noreturn (*ti_dm)(void); + struct rproc *arm64_rproc; + + if (IS_ENABLED(CONFIG_USB_GADGET_DFU) && bootsource_get() == BOOTSOURCE_SERIAL) + do_dfu(); + else if (k3_boot_is_emmc()) + load_fip_emmc(); + else + load_images(); + + ti_sci = ti_sci_get_handle(NULL); + if (IS_ERR(ti_sci)) + return -EINVAL; + + arm64_rproc = ti_k3_am64_get_handle(); + if (!arm64_rproc) { + pr_err("Cannot get rproc handle\n"); + return -EINVAL; + } + + elf = elf_open_binary(k3_ti_dm); if (IS_ERR(elf)) { pr_err("Cannot open ELF image %pe\n", elf); return PTR_ERR(elf); @@ -292,9 +596,9 @@ static int k3_r5_start_image(void) elf_close(elf); } - free(ti_dm_buf); + free(k3_ti_dm); - fw.data = bl31; + fw.data = BL31_ADDRESS; /* Release all the exclusive devices held by SPL before starting ATF */ pr_info("Starting TF-A on A53 core\n"); @@ -324,3 +628,4 @@ static int xload(void) hang(); } postenvironment_initcall(xload); +#endif /* IN_PROPER */ diff --git a/include/mach/k3/common.h b/include/mach/k3/common.h index 7f0796f7f4..14dfc4a28a 100644 --- a/include/mach/k3/common.h +++ b/include/mach/k3/common.h @@ -2,6 +2,11 @@ #define __MACH_K3_COMMON_H #include <bootsource.h> +#include <linux/sizes.h> +#include <linux/uuid.h> + +#define UUID_TI_DM_FW \ + UUID_INIT(0x9e8c2017, 0x8b94, 0x4e2b, 0xa7, 0xb3, 0xa0, 0xf8, 0x8e, 0xab, 0xb8, 0xae) void am625_get_bootsource(enum bootsource *src, int *instance); bool k3_boot_is_emmc(void); @@ -9,4 +14,6 @@ u64 am625_sdram_size(void); void am625_register_dram(void); void am625_enable_32k_crystal(void); +#define K3_EMMC_BOOTPART_TIBOOT3_BIN_SIZE SZ_1M + #endif /* __MACH_K3_COMMON_H */ -- 2.39.5 ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 5/9] ARM: am625-sk: enable 32k crystal 2025-02-05 9:48 [PATCH 0/9] ARM: K3 updates Sascha Hauer ` (3 preceding siblings ...) 2025-02-05 9:48 ` [PATCH 4/9] ARM: k3: r5: add USB DFU and eMMC boot support Sascha Hauer @ 2025-02-05 9:48 ` Sascha Hauer 2025-02-05 9:48 ` [PATCH 6/9] mci: am654: parse generic mmc node properties Sascha Hauer ` (3 subsequent siblings) 8 siblings, 0 replies; 10+ messages in thread From: Sascha Hauer @ 2025-02-05 9:48 UTC (permalink / raw) To: open list:BAREBOX The am625-sk board has the 32k crystal equipped. Enable it to source the RTC from the crystal rather than from the imprecise RC oscillator. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> --- arch/arm/boards/am625-sk/Makefile | 1 + arch/arm/boards/am625-sk/board.c | 30 ++++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/arch/arm/boards/am625-sk/Makefile b/arch/arm/boards/am625-sk/Makefile index 1ff9e75a00..8c45b1e154 100644 --- a/arch/arm/boards/am625-sk/Makefile +++ b/arch/arm/boards/am625-sk/Makefile @@ -1,3 +1,4 @@ pbl-y += lowlevel.o +obj-y += board.o pbl-$(CONFIG_MACH_K3_CORTEX_A) += entry.o pbl-$(CONFIG_MACH_K3_CORTEX_R5) += entry-r5.o am625-sk-ddr.o am625sip-sk-ddr.o diff --git a/arch/arm/boards/am625-sk/board.c b/arch/arm/boards/am625-sk/board.c new file mode 100644 index 0000000000..fd3bcdeac6 --- /dev/null +++ b/arch/arm/boards/am625-sk/board.c @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#define pr_fmt(fmt) "am625-sk: " fmt + +#include <linux/kernel.h> +#include <mach/k3/common.h> +#include <driver.h> +#include <bbu.h> + +static int am625_sk_probe(struct device *dev) +{ + am625_enable_32k_crystal(); + + return 0; +} + +static __maybe_unused struct of_device_id am625_sk_ids[] = { + { + .compatible = "ti,am625-sk", + }, { + /* sentinel */ + } +}; + +static struct driver am625_sk_driver = { + .name = "am625-sk", + .probe = am625_sk_probe, + .of_compatible = am625_sk_ids, +}; +coredevice_platform_driver(am625_sk_driver); -- 2.39.5 ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 6/9] mci: am654: parse generic mmc node properties 2025-02-05 9:48 [PATCH 0/9] ARM: K3 updates Sascha Hauer ` (4 preceding siblings ...) 2025-02-05 9:48 ` [PATCH 5/9] ARM: am625-sk: enable 32k crystal Sascha Hauer @ 2025-02-05 9:48 ` Sascha Hauer 2025-02-05 9:48 ` [PATCH 7/9] ARM: k3: limit eMMC frequency to 25MHz Sascha Hauer ` (2 subsequent siblings) 8 siblings, 0 replies; 10+ messages in thread From: Sascha Hauer @ 2025-02-05 9:48 UTC (permalink / raw) To: open list:BAREBOX Call mci_of_parse_node() to parse generic node properties like max-frequency to lower the maximum allowed frequency. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> --- drivers/mci/am654-sdhci.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/mci/am654-sdhci.c b/drivers/mci/am654-sdhci.c index 9787642011..2c1fa5d804 100644 --- a/drivers/mci/am654-sdhci.c +++ b/drivers/mci/am654-sdhci.c @@ -594,6 +594,7 @@ static int am654_sdhci_probe(struct device *dev) mci = &plat->mci; mci->f_max = clk_get_rate(plat->clk); mci->f_min = 50000000 / 256; + mci_of_parse_node(mci, np); if (plat->soc_data->flags & DLL_PRESENT) { ret = of_property_read_u32(np, "ti,trm-icp", &plat->trm_icp); -- 2.39.5 ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 7/9] ARM: k3: limit eMMC frequency to 25MHz 2025-02-05 9:48 [PATCH 0/9] ARM: K3 updates Sascha Hauer ` (5 preceding siblings ...) 2025-02-05 9:48 ` [PATCH 6/9] mci: am654: parse generic mmc node properties Sascha Hauer @ 2025-02-05 9:48 ` Sascha Hauer 2025-02-05 9:48 ` [PATCH 8/9] ARM: am625-sk: put environment on eMMC when booting from it Sascha Hauer 2025-02-05 9:48 ` [PATCH 9/9] serial: omap: Use ttyS as Linux console name Sascha Hauer 8 siblings, 0 replies; 10+ messages in thread From: Sascha Hauer @ 2025-02-05 9:48 UTC (permalink / raw) To: open list:BAREBOX The eMMCs on am625 currently only work reliably with 25MHz. Until this issue is sorted out limit them to 25MHz on the affected boards (beagleplay and am625-sk). Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> --- arch/arm/dts/k3-am625-beagleplay.dts | 4 ++++ arch/arm/dts/k3-am625-sk.dts | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/arch/arm/dts/k3-am625-beagleplay.dts b/arch/arm/dts/k3-am625-beagleplay.dts index 60340ab8ca..73ac950414 100644 --- a/arch/arm/dts/k3-am625-beagleplay.dts +++ b/arch/arm/dts/k3-am625-beagleplay.dts @@ -29,3 +29,7 @@ AM62X_IOPAD(0x0224, PIN_INPUT, 0) /* (D22) MMC1_DAT3 */ AM62X_IOPAD(0x0240, PIN_INPUT, 0) /* (D17) MMC1_SDCD */ >; }; + +&sdhci0 { + max-frequency = <26000000>; +}; diff --git a/arch/arm/dts/k3-am625-sk.dts b/arch/arm/dts/k3-am625-sk.dts index 1982c34388..56d5681519 100644 --- a/arch/arm/dts/k3-am625-sk.dts +++ b/arch/arm/dts/k3-am625-sk.dts @@ -7,3 +7,7 @@ * DRAM size differs between board variants. Real size is read from DDRSS */ /delete-node/ &{/memory@80000000}; + +&sdhci0 { + max-frequency = <26000000>; +}; -- 2.39.5 ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 8/9] ARM: am625-sk: put environment on eMMC when booting from it 2025-02-05 9:48 [PATCH 0/9] ARM: K3 updates Sascha Hauer ` (6 preceding siblings ...) 2025-02-05 9:48 ` [PATCH 7/9] ARM: k3: limit eMMC frequency to 25MHz Sascha Hauer @ 2025-02-05 9:48 ` Sascha Hauer 2025-02-05 9:48 ` [PATCH 9/9] serial: omap: Use ttyS as Linux console name Sascha Hauer 8 siblings, 0 replies; 10+ messages in thread From: Sascha Hauer @ 2025-02-05 9:48 UTC (permalink / raw) To: open list:BAREBOX When booting from eMMC put the environment on the eMMC as well. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> --- arch/arm/boards/am625-sk/board.c | 5 +++++ arch/arm/dts/k3-am625-sk.dts | 15 +++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/arch/arm/boards/am625-sk/board.c b/arch/arm/boards/am625-sk/board.c index fd3bcdeac6..c716f30e69 100644 --- a/arch/arm/boards/am625-sk/board.c +++ b/arch/arm/boards/am625-sk/board.c @@ -11,6 +11,11 @@ static int am625_sk_probe(struct device *dev) { am625_enable_32k_crystal(); + k3_bbu_emmc_register("emmc", "/dev/mmc0", BBU_HANDLER_FLAG_DEFAULT); + + if (k3_boot_is_emmc()) + of_device_enable_path("/chosen/environment-emmc"); + return 0; } diff --git a/arch/arm/dts/k3-am625-sk.dts b/arch/arm/dts/k3-am625-sk.dts index 56d5681519..8d7a73babf 100644 --- a/arch/arm/dts/k3-am625-sk.dts +++ b/arch/arm/dts/k3-am625-sk.dts @@ -3,6 +3,16 @@ #include <arm64/ti/k3-am625-sk.dts> #include "k3-am625.dtsi" +/ { + chosen { + environment-emmc { + compatible = "barebox,environment"; + device-path = &env_emmc; + status = "disabled"; + }; + }; +}; + /* * DRAM size differs between board variants. Real size is read from DDRSS */ @@ -10,4 +20,9 @@ &sdhci0 { max-frequency = <26000000>; + + env_emmc: partition@e0000 { + label = "barebox-environment"; + reg = <0x0 0xe0000 0x0 0x20000>; + }; }; -- 2.39.5 ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 9/9] serial: omap: Use ttyS as Linux console name 2025-02-05 9:48 [PATCH 0/9] ARM: K3 updates Sascha Hauer ` (7 preceding siblings ...) 2025-02-05 9:48 ` [PATCH 8/9] ARM: am625-sk: put environment on eMMC when booting from it Sascha Hauer @ 2025-02-05 9:48 ` Sascha Hauer 8 siblings, 0 replies; 10+ messages in thread From: Sascha Hauer @ 2025-02-05 9:48 UTC (permalink / raw) To: open list:BAREBOX Traditionally Linux used ttyO as console name for Omap devices. This has been changed to ttyS in 2014. Since then ttyO gets translated to ttyS by the Kernel. Use ttyS directly to avoid the translation in the Kernel. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> --- drivers/serial/serial_ns16550.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/serial/serial_ns16550.c b/drivers/serial/serial_ns16550.c index 45341d1c9b..56a1c6c6b9 100644 --- a/drivers/serial/serial_ns16550.c +++ b/drivers/serial/serial_ns16550.c @@ -402,13 +402,13 @@ static struct ns16550_drvdata ns16550_drvdata = { static __maybe_unused struct ns16550_drvdata omap_drvdata = { .init_port = ns16550_omap_init_port, - .linux_console_name = "ttyO", + .linux_console_name = "ttyS", .linux_earlycon_name = "omap8250", }; static __maybe_unused struct ns16550_drvdata omap_clk48m_drvdata = { .init_port = ns16550_omap_init_port, - .linux_console_name = "ttyO", + .linux_console_name = "ttyS", .clk_default = 48000000, }; -- 2.39.5 ^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2025-02-05 9:49 UTC | newest] Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2025-02-05 9:48 [PATCH 0/9] ARM: K3 updates Sascha Hauer 2025-02-05 9:48 ` [PATCH 1/9] ARM: k3: Add function to enable 32k crystal Sascha Hauer 2025-02-05 9:48 ` [PATCH 2/9] ARM: k3: add function to detect eMMC boot Sascha Hauer 2025-02-05 9:48 ` [PATCH 3/9] ARM: k3: do not mount /boot when booting from eMMC Sascha Hauer 2025-02-05 9:48 ` [PATCH 4/9] ARM: k3: r5: add USB DFU and eMMC boot support Sascha Hauer 2025-02-05 9:48 ` [PATCH 5/9] ARM: am625-sk: enable 32k crystal Sascha Hauer 2025-02-05 9:48 ` [PATCH 6/9] mci: am654: parse generic mmc node properties Sascha Hauer 2025-02-05 9:48 ` [PATCH 7/9] ARM: k3: limit eMMC frequency to 25MHz Sascha Hauer 2025-02-05 9:48 ` [PATCH 8/9] ARM: am625-sk: put environment on eMMC when booting from it Sascha Hauer 2025-02-05 9:48 ` [PATCH 9/9] serial: omap: Use ttyS as Linux console name Sascha Hauer
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox