summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-rw-r--r--common/Kconfig8
-rw-r--r--common/Makefile1
-rw-r--r--common/bloblist.c13
-rw-r--r--common/board_f.c19
-rw-r--r--common/board_info.c8
-rw-r--r--common/board_r.c16
-rw-r--r--common/console.c6
-rw-r--r--common/hash.c8
-rw-r--r--common/init/handoff.c12
-rw-r--r--common/malloc_simple.c3
-rw-r--r--common/memtop.c171
-rw-r--r--common/spl/Kconfig2
-rw-r--r--common/spl/Kconfig.vpl17
-rw-r--r--common/spl/spl.c15
-rw-r--r--common/spl/spl_atf.c36
-rw-r--r--common/spl/spl_fit.c12
-rw-r--r--common/spl/spl_legacy.c8
-rw-r--r--common/spl/spl_mmc.c6
-rw-r--r--common/usb_onboard_hub.c200
19 files changed, 486 insertions, 75 deletions
diff --git a/common/Kconfig b/common/Kconfig
index e8d89bf6eb9..0e8c44f3f74 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -845,6 +845,14 @@ config HASH
and the algorithms it supports are defined in common/hash.c. See
also CMD_HASH for command-line access.
+config HASH_CRC8
+ bool "Make crc8 available via the hash API"
+ depends on HASH && CRC8
+ help
+ Most times, the crc8() function is called directly. To make it also
+ available via the hash API, e.g. in hash_block(), enable this
+ option.
+
config AVB_VERIFY
bool "Build Android Verified Boot operations"
depends on LIBAVB
diff --git a/common/Makefile b/common/Makefile
index 2ee5ef9cc6e..35991562a12 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -7,6 +7,7 @@
ifndef CONFIG_XPL_BUILD
obj-y += init/
obj-y += main.o
+obj-y += memtop.o
obj-y += exports.o
obj-y += cli_getch.o cli_simple.o cli_readline.o
obj-$(CONFIG_HUSH_OLD_PARSER) += cli_hush.o
diff --git a/common/bloblist.c b/common/bloblist.c
index ec6ff7a5a93..110bb9dc44a 100644
--- a/common/bloblist.c
+++ b/common/bloblist.c
@@ -576,14 +576,17 @@ int bloblist_maybe_init(void)
int bloblist_check_reg_conv(ulong rfdt, ulong rzero, ulong rsig)
{
- ulong version = BLOBLIST_REGCONV_VER;
+ u64 version = BLOBLIST_REGCONV_VER;
ulong sigval;
- sigval = (IS_ENABLED(CONFIG_64BIT)) ?
- ((BLOBLIST_MAGIC & ((1UL << BLOBLIST_REGCONV_SHIFT_64) - 1)) |
- ((version & BLOBLIST_REGCONV_MASK) << BLOBLIST_REGCONV_SHIFT_64)) :
- ((BLOBLIST_MAGIC & ((1UL << BLOBLIST_REGCONV_SHIFT_32) - 1)) |
+ if ((IS_ENABLED(CONFIG_64BIT) && !IS_ENABLED(CONFIG_SPL_BUILD)) ||
+ (IS_ENABLED(CONFIG_SPL_64BIT) && IS_ENABLED(CONFIG_SPL_BUILD))) {
+ sigval = ((BLOBLIST_MAGIC & ((1ULL << BLOBLIST_REGCONV_SHIFT_64) - 1)) |
+ ((version & BLOBLIST_REGCONV_MASK) << BLOBLIST_REGCONV_SHIFT_64));
+ } else {
+ sigval = ((BLOBLIST_MAGIC & ((1UL << BLOBLIST_REGCONV_SHIFT_32) - 1)) |
((version & BLOBLIST_REGCONV_MASK) << BLOBLIST_REGCONV_SHIFT_32));
+ }
if (rzero || rsig != sigval ||
rfdt != (ulong)bloblist_find(BLOBLISTT_CONTROL_FDT, 0)) {
diff --git a/common/board_f.c b/common/board_f.c
index 98dc2591e1d..54c48d42ee9 100644
--- a/common/board_f.c
+++ b/common/board_f.c
@@ -305,6 +305,17 @@ static int setup_mon_len(void)
return 0;
}
+static int setup_spl_handoff(void)
+{
+#if CONFIG_IS_ENABLED(HANDOFF)
+ gd->spl_handoff = bloblist_find(BLOBLISTT_U_BOOT_SPL_HANDOFF,
+ sizeof(struct spl_handoff));
+ debug("Found SPL hand-off info %p\n", gd->spl_handoff);
+#endif
+
+ return 0;
+}
+
__weak int arch_cpu_init(void)
{
return 0;
@@ -637,13 +648,6 @@ __weak int arch_setup_bdinfo(void)
int setup_bdinfo(void)
{
- struct bd_info *bd = gd->bd;
-
- if (IS_ENABLED(CONFIG_SYS_HAS_SRAM)) {
- bd->bi_sramstart = CONFIG_SYS_SRAM_BASE; /* start of SRAM */
- bd->bi_sramsize = CONFIG_SYS_SRAM_SIZE; /* size of SRAM */
- }
-
return arch_setup_bdinfo();
}
@@ -880,6 +884,7 @@ static const init_fnc_t init_sequence_f[] = {
initf_bootstage, /* uses its own timer, so does not need DM */
event_init,
bloblist_maybe_init,
+ setup_spl_handoff,
#if defined(CONFIG_CONSOLE_RECORD_INIT_F)
console_record_init,
#endif
diff --git a/common/board_info.c b/common/board_info.c
index 33c260b404e..dc26e1a33dd 100644
--- a/common/board_info.c
+++ b/common/board_info.c
@@ -18,9 +18,9 @@ static const struct to_show {
const char *name;
enum sysinfo_id id;
} to_show[] = {
- { "Manufacturer", SYSINFO_ID_BOARD_MANUFACTURER},
- { "Prior-stage version", SYSINFO_ID_PRIOR_STAGE_VERSION },
- { "Prior-stage date", SYSINFO_ID_PRIOR_STAGE_DATE },
+ { "Manufacturer", SYSID_BOARD_MANUFACTURER},
+ { "Prior-stage version", SYSID_PRIOR_STAGE_VERSION },
+ { "Prior-stage date", SYSID_PRIOR_STAGE_DATE },
{ /* sentinel */ }
};
@@ -39,7 +39,7 @@ static int try_sysinfo(void)
if (ret)
return ret;
- ret = sysinfo_get_str(dev, SYSINFO_ID_BOARD_MODEL, sizeof(str), str);
+ ret = sysinfo_get_str(dev, SYSID_BOARD_MODEL, sizeof(str), str);
if (ret)
return ret;
printf("Model: %s\n", str);
diff --git a/common/board_r.c b/common/board_r.c
index 62228a723e1..f63c6aed4d5 100644
--- a/common/board_r.c
+++ b/common/board_r.c
@@ -152,6 +152,15 @@ static int initr_reloc_global_data(void)
*/
gd->env_addr += gd->reloc_off;
#endif
+
+ /*
+ * For CONFIG_OF_EMBED case the FDT is embedded into ELF, available by
+ * __dtb_dt_begin. After U-Boot ELF self-relocation to RAM top address
+ * it is worth to update fdt_blob in global_data
+ */
+ if (IS_ENABLED(CONFIG_OF_EMBED))
+ fdtdec_setup_embed();
+
#ifdef CONFIG_EFI_LOADER
/*
* On the ARM architecture gd is mapped to a fixed register (r9 or x18).
@@ -287,13 +296,10 @@ static int initr_announce(void)
return 0;
}
-static int initr_binman(void)
+static int __maybe_unused initr_binman(void)
{
int ret;
- if (!CONFIG_IS_ENABLED(BINMAN_FDT))
- return 0;
-
ret = binman_init();
if (ret)
printf("binman_init failed:%d\n", ret);
@@ -635,7 +641,9 @@ static init_fnc_t init_sequence_r[] = {
#ifdef CONFIG_EFI_LOADER
efi_memory_init,
#endif
+#ifdef CONFIG_BINMAN_FDT
initr_binman,
+#endif
#ifdef CONFIG_FSP_VERSION2
arch_fsp_init_r,
#endif
diff --git a/common/console.c b/common/console.c
index 22224701e45..863ac6aa9dc 100644
--- a/common/console.c
+++ b/common/console.c
@@ -745,11 +745,7 @@ void puts(const char *s)
}
if (IS_ENABLED(CONFIG_DEBUG_UART) && !(gd->flags & GD_FLG_SERIAL_READY)) {
- while (*s) {
- int ch = *s++;
-
- printch(ch);
- }
+ printascii(s);
return;
}
diff --git a/common/hash.c b/common/hash.c
index db6925d6782..8dd9da85768 100644
--- a/common/hash.c
+++ b/common/hash.c
@@ -304,6 +304,14 @@ static struct hash_algo hash_algo[] = {
.hash_update = hash_update_crc16_ccitt,
.hash_finish = hash_finish_crc16_ccitt,
},
+#if CONFIG_IS_ENABLED(CRC8) && IS_ENABLED(CONFIG_HASH_CRC8)
+ {
+ .name = "crc8",
+ .digest_size = 1,
+ .chunk_size = CHUNKSZ_CRC32,
+ .hash_func_ws = crc8_wd_buf,
+ },
+#endif
#if CONFIG_IS_ENABLED(CRC32)
{
.name = "crc32",
diff --git a/common/init/handoff.c b/common/init/handoff.c
index 86c020ee0b9..a7cd065fb38 100644
--- a/common/init/handoff.c
+++ b/common/init/handoff.c
@@ -5,7 +5,6 @@
* Copyright 2018 Google, Inc
*/
-#include <bloblist.h>
#include <handoff.h>
#include <asm/global_data.h>
@@ -39,14 +38,3 @@ void handoff_load_dram_banks(struct spl_handoff *ho)
bd->bi_dram[i].size = ho->ram_bank[i].size;
}
}
-
-struct spl_handoff *handoff_get(void)
-{
- struct spl_handoff *handoff;
-
- handoff = bloblist_find(BLOBLISTT_U_BOOT_SPL_HANDOFF,
- sizeof(struct spl_handoff));
- debug("Found SPL hand-off info %p\n", handoff);
-
- return handoff;
-}
diff --git a/common/malloc_simple.c b/common/malloc_simple.c
index 5a8ec538f8f..f0f90a095bd 100644
--- a/common/malloc_simple.c
+++ b/common/malloc_simple.c
@@ -26,7 +26,8 @@ static void *alloc_simple(size_t bytes, int align)
log_debug("size=%lx, ptr=%lx, limit=%x: ", (ulong)bytes, new_ptr,
gd->malloc_limit);
if (new_ptr > gd->malloc_limit) {
- log_err("alloc space exhausted\n");
+ log_err("alloc space exhausted ptr %lx limit %x\n", new_ptr,
+ gd->malloc_limit);
return NULL;
}
diff --git a/common/memtop.c b/common/memtop.c
new file mode 100644
index 00000000000..bff27d8211e
--- /dev/null
+++ b/common/memtop.c
@@ -0,0 +1,171 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2024, Linaro Limited
+ */
+
+#include <fdt_support.h>
+#include <fdtdec.h>
+#include <memtop.h>
+
+#include <asm/types.h>
+
+#define MEM_RGN_COUNT 16
+
+struct region {
+ phys_addr_t base;
+ phys_size_t size;
+};
+
+struct mem_region {
+ struct region rgn[MEM_RGN_COUNT];
+ uint count;
+};
+
+static void add_mem_region(struct mem_region *mem_rgn, phys_addr_t base,
+ phys_size_t size)
+{
+ long i;
+
+ for (i = mem_rgn->count; i >= 0; i--) {
+ if (i && base < mem_rgn->rgn[i - 1].base) {
+ mem_rgn->rgn[i] = mem_rgn->rgn[i - 1];
+ } else {
+ mem_rgn->rgn[i].base = base;
+ mem_rgn->rgn[i].size = size;
+ break;
+ }
+ }
+
+ mem_rgn->count++;
+}
+
+static void mem_regions_init(struct mem_region *mem)
+{
+ uint i;
+
+ mem->count = 0;
+ for (i = 0; i < MEM_RGN_COUNT; i++) {
+ mem->rgn[i].base = 0;
+ mem->rgn[i].size = 0;
+ }
+}
+
+static int fdt_add_reserved_regions(struct mem_region *free_mem,
+ struct mem_region *reserved_mem,
+ void *fdt_blob)
+{
+ u64 addr, size;
+ int i, total, ret;
+ int nodeoffset, subnode;
+ struct fdt_resource res;
+
+ if (fdt_check_header(fdt_blob) != 0)
+ return -1;
+
+ /* process memreserve sections */
+ total = fdt_num_mem_rsv(fdt_blob);
+ assert_noisy(total < MEM_RGN_COUNT);
+ for (i = 0; i < total; i++) {
+ if (fdt_get_mem_rsv(fdt_blob, i, &addr, &size) != 0)
+ continue;
+ add_mem_region(reserved_mem, addr, size);
+ }
+
+ i = 0;
+ /* process reserved-memory */
+ nodeoffset = fdt_subnode_offset(fdt_blob, 0, "reserved-memory");
+ if (nodeoffset >= 0) {
+ subnode = fdt_first_subnode(fdt_blob, nodeoffset);
+ while (subnode >= 0) {
+ /* check if this subnode has a reg property */
+ ret = fdt_get_resource(fdt_blob, subnode, "reg", 0,
+ &res);
+ if (!ret && fdtdec_get_is_enabled(fdt_blob, subnode)) {
+ addr = res.start;
+ size = res.end - res.start + 1;
+ assert_noisy(i < MEM_RGN_COUNT);
+ add_mem_region(reserved_mem, addr, size);
+ }
+
+ subnode = fdt_next_subnode(fdt_blob, subnode);
+ ++i;
+ }
+ }
+
+ return 0;
+}
+
+static long addrs_overlap(phys_addr_t base1, phys_size_t size1,
+ phys_addr_t base2, phys_size_t size2)
+{
+ const phys_addr_t base1_end = base1 + size1 - 1;
+ const phys_addr_t base2_end = base2 + size2 - 1;
+
+ return ((base1 <= base2_end) && (base2 <= base1_end));
+}
+
+static long region_overlap_check(struct mem_region *mem_rgn, phys_addr_t base,
+ phys_size_t size)
+{
+ unsigned long i;
+ struct region *rgn = mem_rgn->rgn;
+
+ for (i = 0; i < mem_rgn->count; i++) {
+ phys_addr_t rgnbase = rgn[i].base;
+ phys_size_t rgnsize = rgn[i].size;
+
+ if (addrs_overlap(base, size, rgnbase, rgnsize))
+ break;
+ }
+
+ return (i < mem_rgn->count) ? i : -1;
+}
+
+static phys_addr_t find_ram_top(struct mem_region *free_mem,
+ struct mem_region *reserved_mem, phys_size_t size)
+{
+ long i, rgn;
+ phys_addr_t base = 0;
+ phys_addr_t res_base;
+
+ for (i = free_mem->count - 1; i >= 0; i--) {
+ phys_addr_t rgnbase = free_mem->rgn[i].base;
+ phys_size_t rgnsize = free_mem->rgn[i].size;
+
+ if (rgnsize < size)
+ continue;
+
+ base = rgnbase + rgnsize - size;
+ while (base && rgnbase <= base) {
+ rgn = region_overlap_check(reserved_mem, base, size);
+ if (rgn < 0)
+ return base;
+
+ res_base = reserved_mem->rgn[rgn].base;
+ if (res_base < size)
+ break;
+ base = res_base - size;
+ }
+ }
+
+ return 0;
+}
+
+phys_addr_t get_mem_top(phys_addr_t ram_start, phys_size_t ram_size,
+ phys_size_t size, void *fdt)
+{
+ int i;
+ struct mem_region free_mem;
+ struct mem_region reserved_mem;
+
+ mem_regions_init(&free_mem);
+ mem_regions_init(&reserved_mem);
+
+ add_mem_region(&free_mem, ram_start, ram_size);
+
+ i = fdt_add_reserved_regions(&free_mem, &reserved_mem, fdt);
+ if (i < 0)
+ return 0;
+
+ return find_ram_top(&free_mem, &reserved_mem, size);
+}
diff --git a/common/spl/Kconfig b/common/spl/Kconfig
index 045fcac10a5..4e56d9909c8 100644
--- a/common/spl/Kconfig
+++ b/common/spl/Kconfig
@@ -462,6 +462,7 @@ config SPL_CUSTOM_SYS_MALLOC_ADDR
config SPL_SYS_MALLOC_SIZE
hex "Size of the SPL malloc pool"
depends on SPL_SYS_MALLOC
+ default 0x180000 if BIOSEMU && RISCV
default 0x100000
config SPL_READ_ONLY
@@ -750,6 +751,7 @@ config SPL_FS_LOAD_PAYLOAD_NAME
depends on SPL_FS_EXT4 || SPL_FS_FAT || SPL_FS_SQUASHFS || SPL_SEMIHOSTING
default "tispl.bin" if SYS_K3_SPL_ATF
default "u-boot.itb" if SPL_LOAD_FIT
+ default "linux.itb" if SPL_LOAD_FIT_OPENSBI_OS_BOOT
default "u-boot.img"
help
Filename to read to load U-Boot when reading from filesystem.
diff --git a/common/spl/Kconfig.vpl b/common/spl/Kconfig.vpl
index d06f36d4ee4..eb57dfabea5 100644
--- a/common/spl/Kconfig.vpl
+++ b/common/spl/Kconfig.vpl
@@ -222,12 +222,29 @@ config VPL_SPI_FLASH_SUPPORT
lines). This enables the drivers in drivers/mtd/spi as part of a
VPL build. This normally requires VPL_SPI_SUPPORT.
+config VPL_SYS_MALLOC_SIMPLE
+ bool "Only use malloc_simple functions in the VPL"
+ default y
+ help
+ Say Y here to only use the *_simple malloc functions from
+ malloc_simple.c, rather then using the versions from dlmalloc.c;
+ this will make the VPL binary smaller at the cost of more heap
+ usage as the *_simple malloc functions do not re-use free-ed mem.
+
config VPL_TEXT_BASE
hex "VPL Text Base"
default 0x0
help
The address in memory that VPL will be running from.
+config VPL_MAX_SIZE
+ hex "Maximum size (in bytes) for the VPL stage"
+ default 0x2e000 if ROCKCHIP_RK3399
+ default 0x0
+ help
+ The maximum size (in bytes) of the TPL stage. This size is determined
+ by the amount of internal SRAM memory.
+
config VPL_BINMAN_SYMBOLS
bool "Declare binman symbols in VPL"
depends on VPL_FRAMEWORK && BINMAN
diff --git a/common/spl/spl.c b/common/spl/spl.c
index 1ceb63daf31..ad31a2f8b6c 100644
--- a/common/spl/spl.c
+++ b/common/spl/spl.c
@@ -631,10 +631,13 @@ static int boot_from_devices(struct spl_image_info *spl_image,
"Unsupported Boot Device!\n");
}
}
- if (loader &&
- !spl_load_image(spl_image, loader)) {
- spl_image->boot_device = bootdev;
- return 0;
+ if (loader) {
+ ret = spl_load_image(spl_image, loader);
+ if (!ret) {
+ spl_image->boot_device = bootdev;
+ return 0;
+ }
+ printf("Error: %d\n", ret);
}
}
}
@@ -833,7 +836,7 @@ void board_init_r(gd_t *dummy1, ulong dummy2)
*/
void preloader_console_init(void)
{
-#ifdef CONFIG_SPL_SERIAL
+#if CONFIG_IS_ENABLED(SERIAL)
gd->baudrate = CONFIG_BAUDRATE;
serial_init(); /* serial communications setup */
@@ -892,7 +895,7 @@ __weak void spl_relocate_stack_check(void)
*/
ulong spl_relocate_stack_gd(void)
{
-#ifdef CONFIG_SPL_STACK_R
+#if CONFIG_IS_ENABLED(STACK_R)
gd_t *new_gd;
ulong ptr = CONFIG_SPL_STACK_R_ADDR;
diff --git a/common/spl/spl_atf.c b/common/spl/spl_atf.c
index 0397b86a33b..8bc5db77395 100644
--- a/common/spl/spl_atf.c
+++ b/common/spl/spl_atf.c
@@ -41,9 +41,9 @@ struct bl2_to_bl31_params_mem_v2 {
struct entry_point_info bl31_ep_info;
};
-struct bl31_params *bl2_plat_get_bl31_params_default(uintptr_t bl32_entry,
- uintptr_t bl33_entry,
- uintptr_t fdt_addr)
+struct bl31_params *bl2_plat_get_bl31_params_default(ulong bl32_entry,
+ ulong bl33_entry,
+ ulong fdt_addr)
{
static struct bl2_to_bl31_params_mem bl31_params_mem;
struct bl31_params *bl2_to_bl31_params;
@@ -100,17 +100,17 @@ struct bl31_params *bl2_plat_get_bl31_params_default(uintptr_t bl32_entry,
return bl2_to_bl31_params;
}
-__weak struct bl31_params *bl2_plat_get_bl31_params(uintptr_t bl32_entry,
- uintptr_t bl33_entry,
- uintptr_t fdt_addr)
+__weak struct bl31_params *bl2_plat_get_bl31_params(ulong bl32_entry,
+ ulong bl33_entry,
+ ulong fdt_addr)
{
return bl2_plat_get_bl31_params_default(bl32_entry, bl33_entry,
fdt_addr);
}
-struct bl_params *bl2_plat_get_bl31_params_v2_default(uintptr_t bl32_entry,
- uintptr_t bl33_entry,
- uintptr_t fdt_addr)
+struct bl_params *bl2_plat_get_bl31_params_v2_default(ulong bl32_entry,
+ ulong bl33_entry,
+ ulong fdt_addr)
{
static struct bl2_to_bl31_params_mem_v2 bl31_params_mem;
struct bl_params *bl_params;
@@ -173,9 +173,9 @@ struct bl_params *bl2_plat_get_bl31_params_v2_default(uintptr_t bl32_entry,
return bl_params;
}
-__weak struct bl_params *bl2_plat_get_bl31_params_v2(uintptr_t bl32_entry,
- uintptr_t bl33_entry,
- uintptr_t fdt_addr)
+__weak struct bl_params *bl2_plat_get_bl31_params_v2(ulong bl32_entry,
+ ulong bl33_entry,
+ ulong fdt_addr)
{
return bl2_plat_get_bl31_params_v2_default(bl32_entry, bl33_entry,
fdt_addr);
@@ -188,8 +188,8 @@ static inline void raw_write_daif(unsigned int daif)
typedef void __noreturn (*atf_entry_t)(struct bl31_params *params, void *plat_params);
-static void __noreturn bl31_entry(uintptr_t bl31_entry, uintptr_t bl32_entry,
- uintptr_t bl33_entry, uintptr_t fdt_addr)
+static void __noreturn bl31_entry(ulong bl31_entry, ulong bl32_entry,
+ ulong bl33_entry, ulong fdt_addr)
{
atf_entry_t atf_entry = (atf_entry_t)bl31_entry;
void *bl31_params;
@@ -238,7 +238,7 @@ static int spl_fit_images_find(void *blob, int os)
return -FDT_ERR_NOTFOUND;
}
-uintptr_t spl_fit_images_get_entry(void *blob, int node)
+ulong spl_fit_images_get_entry(void *blob, int node)
{
ulong val;
int ret;
@@ -253,10 +253,10 @@ uintptr_t spl_fit_images_get_entry(void *blob, int node)
void __noreturn spl_invoke_atf(struct spl_image_info *spl_image)
{
- uintptr_t bl32_entry = 0;
- uintptr_t bl33_entry = CONFIG_TEXT_BASE;
+ ulong bl32_entry = 0;
+ ulong bl33_entry = CONFIG_TEXT_BASE;
void *blob = spl_image->fdt_addr;
- uintptr_t platform_param = (uintptr_t)blob;
+ ulong platform_param = (ulong)blob;
int node;
/*
diff --git a/common/spl/spl_fit.c b/common/spl/spl_fit.c
index 3160f573bfb..ac8462577ff 100644
--- a/common/spl/spl_fit.c
+++ b/common/spl/spl_fit.c
@@ -190,7 +190,7 @@ static int get_aligned_image_size(struct spl_load_info *info, int data_size,
/**
* load_simple_fit(): load the image described in a certain FIT node
* @info: points to information about the device to load data from
- * @sector: the start sector of the FIT image on the device
+ * @fit_offset: the offset of the FIT image on the device
* @ctx: points to the FIT context structure
* @node: offset of the DT node describing the image to load (relative
* to @fit)
@@ -243,11 +243,14 @@ static int load_simple_fit(struct spl_load_info *info, ulong fit_offset,
if (!fit_image_get_data_position(fit, node, &offset)) {
external_data = true;
} else if (!fit_image_get_data_offset(fit, node, &offset)) {
+ log_debug("read offset %x = offset from fit %lx\n",
+ offset, (ulong)offset + ctx->ext_data_offset);
offset += ctx->ext_data_offset;
external_data = true;
}
if (external_data) {
+ ulong read_offset;
void *src_ptr;
/* External data */
@@ -270,6 +273,10 @@ static int load_simple_fit(struct spl_load_info *info, ulong fit_offset,
overhead = get_aligned_image_overhead(info, offset);
size = get_aligned_image_size(info, length, offset);
+ read_offset = fit_offset + get_aligned_image_offset(info,
+ offset);
+ log_debug("reading from offset %x / %lx size %lx to %p: ",
+ offset, read_offset, size, src_ptr);
if (info->read(info,
fit_offset +
@@ -336,6 +343,7 @@ static int load_simple_fit(struct spl_load_info *info, ulong fit_offset,
else
image_info->entry_point = FDT_ERROR;
}
+ log_debug("- done loading\n");
upl_add_image(fit, node, load_addr, length);
@@ -862,7 +870,7 @@ int spl_load_fit_image(struct spl_image_info *spl_image,
{
struct bootm_headers images;
const char *fit_uname_config = NULL;
- uintptr_t fdt_hack;
+ ulong fdt_hack;
const char *uname;
ulong fw_data = 0, dt_data = 0, img_data = 0;
ulong fw_len = 0, dt_len = 0, img_len = 0;
diff --git a/common/spl/spl_legacy.c b/common/spl/spl_legacy.c
index 9252b3a3de0..b3efb3e630e 100644
--- a/common/spl/spl_legacy.c
+++ b/common/spl/spl_legacy.c
@@ -16,11 +16,11 @@
#define LZMA_LEN (1 << 20)
-static void spl_parse_legacy_validate(uintptr_t start, uintptr_t size)
+static void spl_parse_legacy_validate(ulong start, ulong size)
{
- uintptr_t spl_start = (uintptr_t)_start;
- uintptr_t spl_end = (uintptr_t)&_image_binary_end;
- uintptr_t end = start + size;
+ ulong spl_start = (ulong)_start;
+ ulong spl_end = (ulong)&_image_binary_end;
+ ulong end = start + size;
if ((start >= spl_start && start < spl_end) ||
(end > spl_start && end <= spl_end) ||
diff --git a/common/spl/spl_mmc.c b/common/spl/spl_mmc.c
index 1f696593216..fe4230170a0 100644
--- a/common/spl/spl_mmc.c
+++ b/common/spl/spl_mmc.c
@@ -81,8 +81,10 @@ static int spl_mmc_find_device(struct mmc **mmcp, int mmc_dev)
struct uclass *uc;
log_debug("Selecting MMC dev %d; seqs:\n", mmc_dev);
- uclass_id_foreach_dev(UCLASS_MMC, dev, uc)
- log_debug("%d: %s\n", dev_seq(dev), dev->name);
+ if (_LOG_DEBUG) {
+ uclass_id_foreach_dev(UCLASS_MMC, dev, uc)
+ log_debug("%d: %s\n", dev_seq(dev), dev->name);
+ }
ret = mmc_init_device(mmc_dev);
#else
ret = mmc_initialize(NULL);
diff --git a/common/usb_onboard_hub.c b/common/usb_onboard_hub.c
index 68a04ac0412..7fe62b043e6 100644
--- a/common/usb_onboard_hub.c
+++ b/common/usb_onboard_hub.c
@@ -7,37 +7,208 @@
* Mostly inspired by Linux kernel v6.1 onboard_usb_hub driver
*/
+#include <asm/gpio.h>
#include <dm.h>
#include <dm/device_compat.h>
+#include <i2c.h>
+#include <linux/delay.h>
#include <power/regulator.h>
+#define USB5744_COMMAND_ATTACH 0x0056
+#define USB5744_COMMAND_ATTACH_LSB 0xAA
+#define USB5744_CONFIG_REG_ACCESS 0x0037
+#define USB5744_CONFIG_REG_ACCESS_LSB 0x99
+
struct onboard_hub {
struct udevice *vdd;
+ struct gpio_desc *reset_gpio;
+};
+
+struct onboard_hub_data {
+ unsigned long reset_us;
+ unsigned long power_on_delay_us;
+ int (*init)(struct udevice *dev);
};
+static int usb5744_i2c_init(struct udevice *dev)
+{
+ /*
+ * Prevent the MCU from the putting the HUB in suspend mode through register write.
+ * The BYPASS_UDC_SUSPEND bit (Bit 3) of the RuntimeFlags2 register at address
+ * 0x411D controls this aspect of the hub.
+ * Format to write to hub registers via SMBus- 2D 00 00 05 00 01 41 1D 08
+ * Byte 0: Address of slave 2D
+ * Byte 1: Memory address 00
+ * Byte 2: Memory address 00
+ * Byte 3: Number of bytes to write to memory
+ * Byte 4: Write configuration register (00)
+ * Byte 5: Write the number of data bytes (01- 1 data byte)
+ * Byte 6: LSB of register address 0x41
+ * Byte 7: MSB of register address 0x1D
+ * Byte 8: value to be written to the register
+ */
+ u8 data_buf[8] = {0x0, 0x5, 0x0, 0x1, 0x41, 0x1D, 0x08};
+ u8 config_reg_access_buf = USB5744_CONFIG_REG_ACCESS;
+ struct udevice *i2c_bus = NULL, *i2c_dev;
+ struct ofnode_phandle_args phandle;
+ u8 buf = USB5744_COMMAND_ATTACH;
+ struct dm_i2c_chip *i2c_chip;
+ int ret, slave_addr;
+
+ ret = dev_read_phandle_with_args(dev, "i2c-bus", NULL, 0, 0, &phandle);
+ if (ret) {
+ dev_err(dev, "i2c-bus not specified\n");
+ return ret;
+ }
+
+ ret = device_get_global_by_ofnode(ofnode_get_parent(phandle.node), &i2c_bus);
+ if (ret) {
+ dev_err(dev, "Failed to get i2c node, err: %d\n", ret);
+ return ret;
+ }
+
+ ret = ofnode_read_u32(phandle.node, "reg", &slave_addr);
+ if (ret)
+ return ret;
+
+ ret = i2c_get_chip(i2c_bus, slave_addr, 1, &i2c_dev);
+ if (ret) {
+ dev_err(dev, "%s: can't find i2c chip device for addr 0x%x\n", __func__,
+ slave_addr);
+ return ret;
+ }
+
+ i2c_chip = dev_get_parent_plat(i2c_dev);
+ if (!i2c_chip) {
+ dev_err(dev, "parent platform data not found\n");
+ return -EINVAL;
+ }
+
+ i2c_chip->flags &= ~DM_I2C_CHIP_WR_ADDRESS;
+ /* SMBus write command */
+ ret = dm_i2c_write(i2c_dev, 0, (uint8_t *)&data_buf, 8);
+ if (ret) {
+ dev_err(dev, "data_buf i2c_write failed, err:%d\n", ret);
+ return ret;
+ }
+
+ /* Configuration register access command */
+ ret = dm_i2c_write(i2c_dev, USB5744_CONFIG_REG_ACCESS_LSB,
+ &config_reg_access_buf, 2);
+ if (ret) {
+ dev_err(dev, "config_reg_access i2c_write failed, err: %d\n", ret);
+ return ret;
+ }
+
+ /* USB Attach with SMBus */
+ ret = dm_i2c_write(i2c_dev, USB5744_COMMAND_ATTACH_LSB, &buf, 2);
+ if (ret) {
+ dev_err(dev, "usb_attach i2c_write failed, err: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+int usb_onboard_hub_reset(struct udevice *dev)
+{
+ struct onboard_hub_data *data =
+ (struct onboard_hub_data *)dev_get_driver_data(dev);
+ struct onboard_hub *hub = dev_get_priv(dev);
+ int ret;
+
+ hub->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_IS_OUT);
+
+ /* property is optional, don't return error! */
+ if (!hub->reset_gpio)
+ return 0;
+
+ ret = dm_gpio_set_value(hub->reset_gpio, 1);
+ if (ret)
+ return ret;
+
+ udelay(data->reset_us);
+
+ ret = dm_gpio_set_value(hub->reset_gpio, 0);
+ if (ret)
+ return ret;
+
+ udelay(data->power_on_delay_us);
+
+ return 0;
+}
+
static int usb_onboard_hub_probe(struct udevice *dev)
{
+ struct onboard_hub_data *data =
+ (struct onboard_hub_data *)dev_get_driver_data(dev);
struct onboard_hub *hub = dev_get_priv(dev);
int ret;
ret = device_get_supply_regulator(dev, "vdd-supply", &hub->vdd);
- if (ret) {
+ if (ret && ret != -ENOENT) {
dev_err(dev, "can't get vdd-supply: %d\n", ret);
return ret;
}
- ret = regulator_set_enable_if_allowed(hub->vdd, true);
+ if (hub->vdd) {
+ ret = regulator_set_enable_if_allowed(hub->vdd, true);
+ if (ret && ret != -ENOSYS) {
+ dev_err(dev, "can't enable vdd-supply: %d\n", ret);
+ return ret;
+ }
+ }
+
+ ret = usb_onboard_hub_reset(dev);
if (ret)
- dev_err(dev, "can't enable vdd-supply: %d\n", ret);
+ return ret;
+ if (data->init) {
+ ret = data->init(dev);
+ if (ret) {
+ dev_err(dev, "onboard i2c init failed: %d\n", ret);
+ goto err;
+ }
+ }
+ return 0;
+err:
+ dm_gpio_set_value(hub->reset_gpio, 0);
return ret;
}
+static int usb_onboard_hub_bind(struct udevice *dev)
+{
+ struct ofnode_phandle_args phandle;
+ const void *fdt = gd->fdt_blob;
+ int ret, off;
+
+ ret = dev_read_phandle_with_args(dev, "peer-hub", NULL, 0, 0, &phandle);
+ if (ret == -ENOENT) {
+ dev_dbg(dev, "peer-hub property not present\n");
+ return 0;
+ }
+
+ if (ret) {
+ dev_err(dev, "peer-hub not specified\n");
+ return ret;
+ }
+
+ off = ofnode_to_offset(phandle.node);
+ ret = fdt_node_check_compatible(fdt, off, "usb424,5744");
+ if (!ret)
+ return 0;
+
+ return -ENODEV;
+}
+
static int usb_onboard_hub_remove(struct udevice *dev)
{
struct onboard_hub *hub = dev_get_priv(dev);
int ret;
+ if (hub->reset_gpio)
+ dm_gpio_free(hub->reset_gpio->dev, hub->reset_gpio);
+
ret = regulator_set_enable_if_allowed(hub->vdd, false);
if (ret)
dev_err(dev, "can't disable vdd-supply: %d\n", ret);
@@ -45,15 +216,34 @@ static int usb_onboard_hub_remove(struct udevice *dev)
return ret;
}
+static const struct onboard_hub_data usb2514_data = {
+ .power_on_delay_us = 500,
+ .reset_us = 1,
+};
+
+static const struct onboard_hub_data usb5744_data = {
+ .init = usb5744_i2c_init,
+ .power_on_delay_us = 1000,
+ .reset_us = 5,
+};
+
static const struct udevice_id usb_onboard_hub_ids[] = {
/* Use generic usbVID,PID dt-bindings (usb-device.yaml) */
- { .compatible = "usb424,2514" }, /* USB2514B USB 2.0 */
- { }
+ { .compatible = "usb424,2514", /* USB2514B USB 2.0 */
+ .data = (ulong)&usb2514_data,
+ }, {
+ .compatible = "usb424,2744", /* USB2744 USB 2.0 */
+ .data = (ulong)&usb5744_data,
+ }, {
+ .compatible = "usb424,5744", /* USB5744 USB 3.0 */
+ .data = (ulong)&usb5744_data,
+ }
};
U_BOOT_DRIVER(usb_onboard_hub) = {
.name = "usb_onboard_hub",
.id = UCLASS_USB_HUB,
+ .bind = usb_onboard_hub_bind,
.probe = usb_onboard_hub_probe,
.remove = usb_onboard_hub_remove,
.of_match = usb_onboard_hub_ids,