提交 07394fb0 编写于 作者: T Tom Rini

Merge branch '2021-01-27-assorted-fixes-and-improvements'

- A wide variety of fixes throughout the tree.
......@@ -885,7 +885,7 @@ cmd_static_rela = \
tools/relocate-rela $(3) $(4) $$start $$end
else
quiet_cmd_static_rela =
cmd_static_rela = true
cmd_static_rela =
endif
# Always append INPUTS so that arch config.mk's can add custom ones
......@@ -1312,7 +1312,11 @@ endif
shell_cmd = { $(call echo-cmd,$(1)) $(cmd_$(1)); }
quiet_cmd_objcopy_uboot = OBJCOPY $@
ifdef cmd_static_rela
cmd_objcopy_uboot = $(cmd_objcopy) && $(call shell_cmd,static_rela,$<,$@,$(CONFIG_SYS_TEXT_BASE)) || { rm -f $@; false; }
else
cmd_objcopy_uboot = $(cmd_objcopy)
endif
u-boot-nodtb.bin: u-boot FORCE
$(call if_changed,objcopy_uboot)
......
......@@ -2770,13 +2770,6 @@ Low Level (hardware related) configuration options:
CONFIG_SYS_OR3_PRELIM, CONFIG_SYS_BR3_PRELIM:
Memory Controller Definitions: BR2/3 and OR2/3 (SDRAM)
- CONFIG_PCI_ENUM_ONLY
Only scan through and get the devices on the buses.
Don't do any setup work, presumably because someone or
something has already done it, and we don't need to do it
a second time. Useful for platforms that are pre-booted
by coreboot or similar.
- CONFIG_PCI_INDIRECT_BRIDGE:
Enable support for indirect PCI bridges.
......
......@@ -40,7 +40,7 @@ static int do_sleep(struct cmd_tbl *cmdtp, int flag, int argc,
while (get_timer(start) < delay) {
if (ctrlc())
return (-1);
return CMD_RET_FAILURE;
udelay(100);
}
......
......@@ -697,6 +697,16 @@ config BLOBLIST_ADDR
Sets the address of the bloblist, set up by the first part of U-Boot
which runs. Subsequent U-Boot stages typically use the same address.
config BLOBLIST_SIZE_RELOC
hex "Size of bloblist after relocation"
depends on BLOBLIST
default BLOBLIST_SIZE
help
Sets the size of the bloblist in bytes after relocation. Since U-Boot
has a lot more memory available then, it is possible to use a larger
size than the one set up by SPL. This bloblist is set up during the
relocation process.
endmenu
source "common/spl/Kconfig"
......
......@@ -164,9 +164,9 @@ static int passwd_abort_key(uint64_t etime)
};
char presskey[MAX_DELAY_STOP_STR];
u_int presskey_len = 0;
u_int presskey_max = 0;
u_int i;
int presskey_len = 0;
int presskey_max = 0;
int i;
# ifdef CONFIG_AUTOBOOT_DELAY_STR
if (delaykey[0].str == NULL)
......
......@@ -33,6 +33,12 @@ static const char *const tag_name[] = {
[BLOBLISTT_SPL_HANDOFF] = "SPL hand-off",
[BLOBLISTT_VBOOT_CTX] = "Chrome OS vboot context",
[BLOBLISTT_VBOOT_HANDOFF] = "Chrome OS vboot hand-off",
[BLOBLISTT_ACPI_GNVS] = "ACPI GNVS",
[BLOBLISTT_INTEL_VBT] = "Intel Video-BIOS table",
[BLOBLISTT_TPM2_TCG_LOG] = "TPM v2 log space",
[BLOBLISTT_TCPA_LOG] = "TPM log space",
[BLOBLISTT_ACPI_TABLES] = "ACPI tables for x86",
[BLOBLISTT_SMBIOS_TABLES] = "SMBIOS tables for x86",
};
const char *bloblist_tag_name(enum bloblist_tag_t tag)
......@@ -317,6 +323,15 @@ void bloblist_show_list(void)
}
}
void bloblist_reloc(void *to, uint to_size, void *from, uint from_size)
{
struct bloblist_hdr *hdr;
memcpy(to, from, from_size);
hdr = to;
hdr->size = to_size;
}
int bloblist_init(void)
{
bool expected;
......@@ -327,6 +342,8 @@ int bloblist_init(void)
* that runs
*/
expected = !u_boot_first_phase();
if (spl_prev_phase() == PHASE_TPL && !IS_ENABLED(CONFIG_TPL_BLOBLIST))
expected = false;
if (expected)
ret = bloblist_check(CONFIG_BLOBLIST_ADDR,
CONFIG_BLOBLIST_SIZE);
......
......@@ -568,9 +568,10 @@ static int reserve_bloblist(void)
{
#ifdef CONFIG_BLOBLIST
/* Align to a 4KB boundary for easier reading of addresses */
gd->start_addr_sp = ALIGN_DOWN(gd->start_addr_sp - CONFIG_BLOBLIST_SIZE,
0x1000);
gd->new_bloblist = map_sysmem(gd->start_addr_sp, CONFIG_BLOBLIST_SIZE);
gd->start_addr_sp = ALIGN_DOWN(gd->start_addr_sp -
CONFIG_BLOBLIST_SIZE_RELOC, 0x1000);
gd->new_bloblist = map_sysmem(gd->start_addr_sp,
CONFIG_BLOBLIST_SIZE_RELOC);
#endif
return 0;
......@@ -658,7 +659,8 @@ static int reloc_bloblist(void)
debug("Copying bloblist from %p to %p, size %x\n",
gd->bloblist, gd->new_bloblist, size);
memcpy(gd->new_bloblist, gd->bloblist, size);
bloblist_reloc(gd->new_bloblist, CONFIG_BLOBLIST_SIZE_RELOC,
gd->bloblist, size);
gd->bloblist = gd->new_bloblist;
}
#endif
......
......@@ -360,7 +360,7 @@ static int fit_config_verify_sig(const void *fit, int conf_noffset,
const void *sig_blob, int sig_offset)
{
int noffset;
char *err_msg = "";
char *err_msg = "No 'signature' subnode found";
int verified = 0;
int ret;
......
......@@ -186,7 +186,7 @@ config SPL_BOOTROM_SUPPORT
config SPL_BOOTCOUNT_LIMIT
bool "Support bootcount in SPL"
depends on SPL_ENV_SUPPORT
depends on SPL_ENV_SUPPORT && !TPL_BOOTCOUNT_LIMIT
help
On some boards, which use 'falcon' mode, it is necessary to check
and increment the number of boot attempts. Such boards do not
......@@ -1382,6 +1382,13 @@ config TPL_BOARD_INIT
spl_board_init() from board_init_r(). This function should be
provided by the board.
config TPL_BOOTCOUNT_LIMIT
bool "Support bootcount in TPL"
depends on TPL_ENV_SUPPORT
help
If this option is enabled, the TPL will support bootcount.
For example, it may be useful to choose the device to boot.
config TPL_LDSCRIPT
string "Linker script for the TPL stage"
depends on TPL
......
......@@ -734,7 +734,7 @@ void board_init_r(gd_t *dummy1, ulong dummy2)
debug("Failed to stash bootstage: err=%d\n", ret);
#endif
debug("loaded - jumping to U-Boot...\n");
debug("loaded - jumping to %s...\n", spl_phase_name(spl_next_phase()));
spl_board_prepare_for_boot();
jump_to_image_no_args(&spl_image);
}
......@@ -837,7 +837,9 @@ ulong spl_relocate_stack_gd(void)
#endif
}
#if defined(CONFIG_BOOTCOUNT_LIMIT) && !defined(CONFIG_SPL_BOOTCOUNT_LIMIT)
#if defined(CONFIG_BOOTCOUNT_LIMIT) && \
((!defined(CONFIG_TPL_BUILD) && !defined(CONFIG_SPL_BOOTCOUNT_LIMIT)) || \
(defined(CONFIG_TPL_BUILD) && !defined(CONFIG_TPL_BOOTCOUNT_LIMIT)))
void bootcount_store(ulong a)
{
}
......
Abracon ABX80X I2C ultra low power RTC/Alarm chip
The Abracon ABX80X family consist of the ab0801, ab0803, ab0804, ab0805, ab1801,
ab1803, ab1804 and ab1805. The ab0805 is the superset of ab080x and the ab1805
is the superset of ab180x.
Required properties:
- "compatible": should one of:
"abracon,abx80x"
"abracon,ab0801"
"abracon,ab0803"
"abracon,ab0804"
"abracon,ab0805"
"abracon,ab1801"
"abracon,ab1803"
"abracon,ab1804"
"abracon,ab1805"
"microcrystal,rv1805"
Using "abracon,abx80x" will enable chip autodetection.
- "reg": I2C bus address of the device
Optional properties:
The abx804 and abx805 have a trickle charger that is able to charge the
connected battery or supercap. Both the following properties have to be defined
and valid to enable charging:
- "abracon,tc-diode": should be "standard" (0.6V) or "schottky" (0.3V)
- "abracon,tc-resistor": should be <0>, <3>, <6> or <11>. 0 disables the output
resistor, the other values are in kOhm.
......@@ -69,6 +69,7 @@ endif
ifdef CONFIG_TPL_BUILD
obj-$(CONFIG_TPL_BOOTCOUNT_LIMIT) += bootcount/
obj-$(CONFIG_TPL_MPC8XXX_INIT_DDR_SUPPORT) += ddr/fsl/
endif
......
......@@ -10,6 +10,7 @@
#include <log.h>
#include <malloc.h>
#include <mapmem.h>
#include <mmc.h>
#include <sdhci.h>
#include <acpi/acpigen.h>
#include <acpi/acpi_device.h>
......@@ -17,6 +18,12 @@
#include <asm-generic/gpio.h>
#include <dm/acpi.h>
/* Type of MMC device */
enum {
TYPE_SD,
TYPE_EMMC,
};
struct pci_mmc_plat {
struct mmc_config cfg;
struct mmc mmc;
......@@ -34,8 +41,15 @@ static int pci_mmc_probe(struct udevice *dev)
struct pci_mmc_plat *plat = dev_get_plat(dev);
struct pci_mmc_priv *priv = dev_get_priv(dev);
struct sdhci_host *host = &priv->host;
struct blk_desc *desc;
int ret;
ret = mmc_of_parse(dev, &plat->cfg);
if (ret)
return ret;
desc = mmc_get_blk_desc(&plat->mmc);
desc->removable = !(plat->cfg.host_caps & MMC_CAP_NONREMOVABLE);
host->ioaddr = (void *)dm_pci_map_bar(dev, PCI_BASE_ADDRESS_0,
PCI_REGION_MEM);
host->name = dev->name;
......@@ -79,6 +93,8 @@ static int pci_mmc_acpi_fill_ssdt(const struct udevice *dev,
if (!dev_has_ofnode(dev))
return 0;
if (dev_get_driver_data(dev) == TYPE_EMMC)
return 0;
ret = gpio_get_acpi(&priv->cd_gpio, &gpio);
if (ret)
......@@ -122,7 +138,8 @@ struct acpi_ops pci_mmc_acpi_ops = {
};
static const struct udevice_id pci_mmc_match[] = {
{ .compatible = "intel,apl-sd" },
{ .compatible = "intel,apl-sd", .data = TYPE_SD },
{ .compatible = "intel,apl-emmc", .data = TYPE_EMMC },
{ }
};
......
......@@ -18,10 +18,10 @@
#define CONFIG_SYS_PCI_CACHE_LINE_SIZE 8
#endif
void dm_pciauto_setup_device(struct udevice *dev, int bars_num,
struct pci_region *mem,
struct pci_region *prefetch, struct pci_region *io,
bool enum_only)
static void dm_pciauto_setup_device(struct udevice *dev, int bars_num,
struct pci_region *mem,
struct pci_region *prefetch,
struct pci_region *io)
{
u32 bar_response;
pci_size_t bar_size;
......@@ -43,8 +43,7 @@ void dm_pciauto_setup_device(struct udevice *dev, int bars_num,
int ret = 0;
/* Tickle the BAR and get the response */
if (!enum_only)
dm_pci_write_config32(dev, bar, 0xffffffff);
dm_pci_write_config32(dev, bar, 0xffffffff);
dm_pci_read_config32(dev, bar, &bar_response);
/* If BAR is not implemented (or invalid) go to the next BAR */
......@@ -58,8 +57,7 @@ void dm_pciauto_setup_device(struct udevice *dev, int bars_num,
bar_size = bar_response & PCI_BASE_ADDRESS_IO_MASK;
bar_size &= ~(bar_size - 1);
if (!enum_only)
bar_res = io;
bar_res = io;
debug("PCI Autoconfig: BAR %d, I/O, size=0x%llx, ",
bar_nr, (unsigned long long)bar_size);
......@@ -69,10 +67,7 @@ void dm_pciauto_setup_device(struct udevice *dev, int bars_num,
u32 bar_response_upper;
u64 bar64;
if (!enum_only) {
dm_pci_write_config32(dev, bar + 4,
0xffffffff);
}
dm_pci_write_config32(dev, bar + 4, 0xffffffff);
dm_pci_read_config32(dev, bar + 4,
&bar_response_upper);
......@@ -81,33 +76,29 @@ void dm_pciauto_setup_device(struct udevice *dev, int bars_num,
bar_size = ~(bar64 & PCI_BASE_ADDRESS_MEM_MASK)
+ 1;
if (!enum_only)
found_mem64 = 1;
found_mem64 = 1;
} else {
bar_size = (u32)(~(bar_response &
PCI_BASE_ADDRESS_MEM_MASK) + 1);
}
if (!enum_only) {
if (prefetch && (bar_response &
PCI_BASE_ADDRESS_MEM_PREFETCH)) {
bar_res = prefetch;
} else {
bar_res = mem;
}
}
if (prefetch &&
(bar_response & PCI_BASE_ADDRESS_MEM_PREFETCH))
bar_res = prefetch;
else
bar_res = mem;
debug("PCI Autoconfig: BAR %d, %s, size=0x%llx, ",
bar_nr, bar_res == prefetch ? "Prf" : "Mem",
(unsigned long long)bar_size);
}
if (!enum_only) {
ret = pciauto_region_allocate(bar_res, bar_size,
&bar_value, found_mem64);
if (ret)
printf("PCI: Failed autoconfig bar %x\n", bar);
}
if (!enum_only && !ret) {
ret = pciauto_region_allocate(bar_res, bar_size,
&bar_value, found_mem64);
if (ret)
printf("PCI: Failed autoconfig bar %x\n", bar);
if (!ret) {
/* Write it out and update our limit */
dm_pci_write_config32(dev, bar, (u32)bar_value);
......@@ -135,28 +126,24 @@ void dm_pciauto_setup_device(struct udevice *dev, int bars_num,
bar_nr++;
}
if (!enum_only) {
/* Configure the expansion ROM address */
dm_pci_read_config8(dev, PCI_HEADER_TYPE, &header_type);
header_type &= 0x7f;
if (header_type != PCI_HEADER_TYPE_CARDBUS) {
rom_addr = (header_type == PCI_HEADER_TYPE_NORMAL) ?
PCI_ROM_ADDRESS : PCI_ROM_ADDRESS1;
dm_pci_write_config32(dev, rom_addr, 0xfffffffe);
dm_pci_read_config32(dev, rom_addr, &bar_response);
if (bar_response) {
bar_size = -(bar_response & ~1);
debug("PCI Autoconfig: ROM, size=%#x, ",
(unsigned int)bar_size);
if (pciauto_region_allocate(mem, bar_size,
&bar_value,
false) == 0) {
dm_pci_write_config32(dev, rom_addr,
bar_value);
}
cmdstat |= PCI_COMMAND_MEMORY;
debug("\n");
/* Configure the expansion ROM address */
dm_pci_read_config8(dev, PCI_HEADER_TYPE, &header_type);
header_type &= 0x7f;
if (header_type != PCI_HEADER_TYPE_CARDBUS) {
rom_addr = (header_type == PCI_HEADER_TYPE_NORMAL) ?
PCI_ROM_ADDRESS : PCI_ROM_ADDRESS1;
dm_pci_write_config32(dev, rom_addr, 0xfffffffe);
dm_pci_read_config32(dev, rom_addr, &bar_response);
if (bar_response) {
bar_size = -(bar_response & ~1);
debug("PCI Autoconfig: ROM, size=%#x, ",
(unsigned int)bar_size);
if (pciauto_region_allocate(mem, bar_size, &bar_value,
false) == 0) {
dm_pci_write_config32(dev, rom_addr, bar_value);
}
cmdstat |= PCI_COMMAND_MEMORY;
debug("\n");
}
}
......@@ -319,15 +306,10 @@ int dm_pciauto_config_device(struct udevice *dev)
struct pci_region *pci_io;
unsigned int sub_bus = PCI_BUS(dm_pci_get_bdf(dev));
unsigned short class;
bool enum_only = false;
struct udevice *ctlr = pci_get_controller(dev);
struct pci_controller *ctlr_hose = dev_get_uclass_priv(ctlr);
int ret;
#ifdef CONFIG_PCI_ENUM_ONLY
enum_only = true;
#endif
pci_mem = ctlr_hose->pci_mem;
pci_prefetch = ctlr_hose->pci_prefetch;
pci_io = ctlr_hose->pci_io;
......@@ -339,8 +321,7 @@ int dm_pciauto_config_device(struct udevice *dev)
debug("PCI Autoconfig: Found P2P bridge, device %d\n",
PCI_DEV(dm_pci_get_bdf(dev)));
dm_pciauto_setup_device(dev, 2, pci_mem, pci_prefetch, pci_io,
enum_only);
dm_pciauto_setup_device(dev, 2, pci_mem, pci_prefetch, pci_io);
ret = dm_pci_hose_probe_bus(dev);
if (ret < 0)
......@@ -353,8 +334,7 @@ int dm_pciauto_config_device(struct udevice *dev)
* just do a minimal setup of the bridge,
* let the OS take care of the rest
*/
dm_pciauto_setup_device(dev, 0, pci_mem, pci_prefetch, pci_io,
enum_only);
dm_pciauto_setup_device(dev, 0, pci_mem, pci_prefetch, pci_io);
debug("PCI Autoconfig: Found P2CardBus bridge, device %d\n",
PCI_DEV(dm_pci_get_bdf(dev)));
......@@ -378,8 +358,7 @@ int dm_pciauto_config_device(struct udevice *dev)
*/
debug("PCI Autoconfig: Broken bridge found, only minimal config\n");
dm_pciauto_setup_device(dev, 0, hose->pci_mem,
hose->pci_prefetch, hose->pci_io,
enum_only);
hose->pci_prefetch, hose->pci_io);
break;
#endif
......@@ -388,8 +367,7 @@ int dm_pciauto_config_device(struct udevice *dev)
/* fall through */
default:
dm_pciauto_setup_device(dev, 6, pci_mem, pci_prefetch, pci_io,
enum_only);
dm_pciauto_setup_device(dev, 6, pci_mem, pci_prefetch, pci_io);
break;
}
......
......@@ -36,13 +36,11 @@ void pciauto_setup_device(struct pci_controller *hose,
pci_size_t bar_size;
u16 cmdstat = 0;
int bar, bar_nr = 0;
#ifndef CONFIG_PCI_ENUM_ONLY
u8 header_type;
int rom_addr;
pci_addr_t bar_value;
struct pci_region *bar_res;
int found_mem64 = 0;
#endif
u16 class;
pci_hose_read_config_word(hose, dev, PCI_COMMAND, &cmdstat);
......@@ -51,26 +49,20 @@ void pciauto_setup_device(struct pci_controller *hose,
for (bar = PCI_BASE_ADDRESS_0;
bar < PCI_BASE_ADDRESS_0 + (bars_num * 4); bar += 4) {
/* Tickle the BAR and get the response */
#ifndef CONFIG_PCI_ENUM_ONLY
pci_hose_write_config_dword(hose, dev, bar, 0xffffffff);
#endif
pci_hose_read_config_dword(hose, dev, bar, &bar_response);
/* If BAR is not implemented go to the next BAR */
if (!bar_response)
continue;
#ifndef CONFIG_PCI_ENUM_ONLY
found_mem64 = 0;
#endif
/* Check the BAR type and set our address mask */
if (bar_response & PCI_BASE_ADDRESS_SPACE) {
bar_size = ((~(bar_response & PCI_BASE_ADDRESS_IO_MASK))
& 0xffff) + 1;
#ifndef CONFIG_PCI_ENUM_ONLY
bar_res = io;
#endif
debug("PCI Autoconfig: BAR %d, I/O, size=0x%llx, ",
bar_nr, (unsigned long long)bar_size);
......@@ -80,23 +72,18 @@ void pciauto_setup_device(struct pci_controller *hose,
u32 bar_response_upper;
u64 bar64;
#ifndef CONFIG_PCI_ENUM_ONLY
pci_hose_write_config_dword(hose, dev, bar + 4,
0xffffffff);
#endif
pci_hose_read_config_dword(hose, dev, bar + 4,
&bar_response_upper);
bar64 = ((u64)bar_response_upper << 32) | bar_response;
bar_size = ~(bar64 & PCI_BASE_ADDRESS_MEM_MASK) + 1;
#ifndef CONFIG_PCI_ENUM_ONLY
found_mem64 = 1;
#endif
} else {
bar_size = (u32)(~(bar_response & PCI_BASE_ADDRESS_MEM_MASK) + 1);
}
#ifndef CONFIG_PCI_ENUM_ONLY
if (prefetch && (bar_response & PCI_BASE_ADDRESS_MEM_PREFETCH))
bar_res = prefetch;
else
......@@ -105,10 +92,8 @@ void pciauto_setup_device(struct pci_controller *hose,
debug("PCI Autoconfig: BAR %d, %s, size=0x%llx, ",
bar_nr, bar_res == prefetch ? "Prf" : "Mem",
(unsigned long long)bar_size);
#endif
}
#ifndef CONFIG_PCI_ENUM_ONLY
if (pciauto_region_allocate(bar_res, bar_size,
&bar_value, found_mem64) == 0) {
/* Write it out and update our limit */
......@@ -129,7 +114,6 @@ void pciauto_setup_device(struct pci_controller *hose,
}
}
#endif
cmdstat |= (bar_response & PCI_BASE_ADDRESS_SPACE) ?
PCI_COMMAND_IO : PCI_COMMAND_MEMORY;
......@@ -138,7 +122,6 @@ void pciauto_setup_device(struct pci_controller *hose,
bar_nr++;
}
#ifndef CONFIG_PCI_ENUM_ONLY
/* Configure the expansion ROM address */
pci_hose_read_config_byte(hose, dev, PCI_HEADER_TYPE, &header_type);
header_type &= 0x7f;
......@@ -160,7 +143,6 @@ void pciauto_setup_device(struct pci_controller *hose,
debug("\n");
}
}
#endif
/* PCI_COMMAND_IO must be set for VGA device */
pci_hose_read_config_word(hose, dev, PCI_CLASS_DEVICE, &class);
......
......@@ -166,4 +166,13 @@ config RTC_STM32
help
Enable STM32 RTC driver. This driver supports the rtc that is present
on some STM32 SoCs.
config RTC_ABX80X
bool "Enable Abracon ABx80x RTC driver"
depends on DM_RTC
help
If you say yes here you get support for Abracon AB080X and AB180X
families of ultra-low-power battery- and capacitor-backed real-time
clock chips.
endmenu
......@@ -55,3 +55,4 @@ obj-$(CONFIG_RTC_S35392A) += s35392a.o
obj-$(CONFIG_RTC_STM32) += stm32_rtc.o
obj-$(CONFIG_SANDBOX) += sandbox_rtc.o
obj-$(CONFIG_RTC_X1205) += x1205.o
obj-$(CONFIG_RTC_ABX80X) += abx80x.o
// SPDX-License-Identifier: GPL-2.0
/*
* A driver for the I2C members of the Abracon AB x8xx RTC family,
* and compatible: AB 1805 and AB 0805
*
* Copyright 2014-2015 Macq S.A.
* Copyright 2020 Linaro
*
* Author: Philippe De Muyter <phdm@macqel.be>
* Author: Alexandre Belloni <alexandre.belloni@bootlin.com>
* Author: Ying-Chun Liu (PaulLiu) <paul.liu@linaro.org>
*
*/
#include <common.h>
#include <dm.h>
#include <i2c.h>
#include <rtc.h>
#include <log.h>
#define ABX8XX_REG_HTH 0x00
#define ABX8XX_REG_SC 0x01
#define ABX8XX_REG_MN 0x02
#define ABX8XX_REG_HR 0x03
#define ABX8XX_REG_DA 0x04
#define ABX8XX_REG_MO 0x05
#define ABX8XX_REG_YR 0x06
#define ABX8XX_REG_WD 0x07
#define ABX8XX_REG_AHTH 0x08
#define ABX8XX_REG_ASC 0x09
#define ABX8XX_REG_AMN 0x0a
#define ABX8XX_REG_AHR 0x0b
#define ABX8XX_REG_ADA 0x0c
#define ABX8XX_REG_AMO 0x0d
#define ABX8XX_REG_AWD 0x0e
#define ABX8XX_REG_STATUS 0x0f
#define ABX8XX_STATUS_AF BIT(2)
#define ABX8XX_STATUS_BLF BIT(4)
#define ABX8XX_STATUS_WDT BIT(6)
#define ABX8XX_REG_CTRL1 0x10
#define ABX8XX_CTRL_WRITE BIT(0)
#define ABX8XX_CTRL_ARST BIT(2)
#define ABX8XX_CTRL_12_24 BIT(6)
#define ABX8XX_REG_CTRL2 0x11
#define ABX8XX_CTRL2_RSVD BIT(5)
#define ABX8XX_REG_IRQ 0x12
#define ABX8XX_IRQ_AIE BIT(2)
#define ABX8XX_IRQ_IM_1_4 (0x3 << 5)
#define ABX8XX_REG_CD_TIMER_CTL 0x18
#define ABX8XX_REG_OSC 0x1c
#define ABX8XX_OSC_FOS BIT(3)
#define ABX8XX_OSC_BOS BIT(4)
#define ABX8XX_OSC_ACAL_512 BIT(5)
#define ABX8XX_OSC_ACAL_1024 BIT(6)
#define ABX8XX_OSC_OSEL BIT(7)
#define ABX8XX_REG_OSS 0x1d
#define ABX8XX_OSS_OF BIT(1)
#define ABX8XX_OSS_OMODE BIT(4)
#define ABX8XX_REG_WDT 0x1b
#define ABX8XX_WDT_WDS BIT(7)
#define ABX8XX_WDT_BMB_MASK 0x7c
#define ABX8XX_WDT_BMB_SHIFT 2
#define ABX8XX_WDT_MAX_TIME (ABX8XX_WDT_BMB_MASK >> ABX8XX_WDT_BMB_SHIFT)
#define ABX8XX_WDT_WRB_MASK 0x03
#define ABX8XX_WDT_WRB_1HZ 0x02
#define ABX8XX_REG_CFG_KEY 0x1f
#define ABX8XX_CFG_KEY_OSC 0xa1
#define ABX8XX_CFG_KEY_MISC 0x9d
#define ABX8XX_REG_ID0 0x28
#define ABX8XX_REG_OUT_CTRL 0x30
#define ABX8XX_OUT_CTRL_EXDS BIT(4)
#define ABX8XX_REG_TRICKLE 0x20
#define ABX8XX_TRICKLE_CHARGE_ENABLE 0xa0
#define ABX8XX_TRICKLE_STANDARD_DIODE 0x8
#define ABX8XX_TRICKLE_SCHOTTKY_DIODE 0x4
static u8 trickle_resistors[] = {0, 3, 6, 11};
enum abx80x_chip {AB0801, AB0803, AB0804, AB0805,
AB1801, AB1803, AB1804, AB1805, RV1805, ABX80X};
struct abx80x_cap {
u16 pn;
bool has_tc;
bool has_wdog;
};
static struct abx80x_cap abx80x_caps[] = {
[AB0801] = {.pn = 0x0801},
[AB0803] = {.pn = 0x0803},
[AB0804] = {.pn = 0x0804, .has_tc = true, .has_wdog = true},
[AB0805] = {.pn = 0x0805, .has_tc = true, .has_wdog = true},
[AB1801] = {.pn = 0x1801},
[AB1803] = {.pn = 0x1803},
[AB1804] = {.pn = 0x1804, .has_tc = true, .has_wdog = true},
[AB1805] = {.pn = 0x1805, .has_tc = true, .has_wdog = true},
[RV1805] = {.pn = 0x1805, .has_tc = true, .has_wdog = true},
[ABX80X] = {.pn = 0}
};
static int abx80x_rtc_read8(struct udevice *dev, unsigned int reg)
{
int ret = 0;
u8 buf;
if (reg > 0xff)
return -EINVAL;
ret = dm_i2c_read(dev, reg, &buf, sizeof(buf));
if (ret < 0)
return ret;
return buf;
}
static int abx80x_rtc_write8(struct udevice *dev, unsigned int reg, int val)
{
u8 buf = (u8)val;
if (reg > 0xff)
return -EINVAL;
return dm_i2c_write(dev, reg, &buf, sizeof(buf));
}
static int abx80x_is_rc_mode(struct udevice *dev)
{
int flags = 0;
flags = dm_i2c_reg_read(dev, ABX8XX_REG_OSS);
if (flags < 0) {
log_err("Failed to read autocalibration attribute\n");
return flags;
}
return (flags & ABX8XX_OSS_OMODE) ? 1 : 0;
}
static int abx80x_enable_trickle_charger(struct udevice *dev, u8 trickle_cfg)
{
int err;
/*
* Write the configuration key register to enable access to the Trickle
* register
*/
err = dm_i2c_reg_write(dev, ABX8XX_REG_CFG_KEY, ABX8XX_CFG_KEY_MISC);
if (err < 0) {
log_err("Unable to write configuration key\n");
return -EIO;
}
err = dm_i2c_reg_write(dev, ABX8XX_REG_TRICKLE,
ABX8XX_TRICKLE_CHARGE_ENABLE | trickle_cfg);
if (err < 0) {
log_err("Unable to write trickle register\n");
return -EIO;
}
return 0;
}
static int abx80x_rtc_read_time(struct udevice *dev, struct rtc_time *tm)
{
unsigned char buf[8];
int err, flags, rc_mode = 0;
/* Read the Oscillator Failure only in XT mode */
rc_mode = abx80x_is_rc_mode(dev);
if (rc_mode < 0)
return rc_mode;
if (!rc_mode) {
flags = dm_i2c_reg_read(dev, ABX8XX_REG_OSS);
if (flags < 0) {
log_err("Unable to read oscillator status.\n");
return flags;
}
if (flags & ABX8XX_OSS_OF)
log_debug("Oscillator fail, data is not accurate.\n");
}
err = dm_i2c_read(dev, ABX8XX_REG_HTH,
buf, sizeof(buf));
if (err < 0) {
log_err("Unable to read date\n");
return -EIO;
}
tm->tm_sec = bcd2bin(buf[ABX8XX_REG_SC] & 0x7F);
tm->tm_min = bcd2bin(buf[ABX8XX_REG_MN] & 0x7F);
tm->tm_hour = bcd2bin(buf[ABX8XX_REG_HR] & 0x3F);
tm->tm_wday = buf[ABX8XX_REG_WD] & 0x7;
tm->tm_mday = bcd2bin(buf[ABX8XX_REG_DA] & 0x3F);
tm->tm_mon = bcd2bin(buf[ABX8XX_REG_MO] & 0x1F);
tm->tm_year = bcd2bin(buf[ABX8XX_REG_YR]) + 2000;
return 0;
}
static int abx80x_rtc_set_time(struct udevice *dev, const struct rtc_time *tm)
{
unsigned char buf[8];
int err, flags;
if (tm->tm_year < 2000)
return -EINVAL;
buf[ABX8XX_REG_HTH] = 0;
buf[ABX8XX_REG_SC] = bin2bcd(tm->tm_sec);
buf[ABX8XX_REG_MN] = bin2bcd(tm->tm_min);
buf[ABX8XX_REG_HR] = bin2bcd(tm->tm_hour);
buf[ABX8XX_REG_DA] = bin2bcd(tm->tm_mday);
buf[ABX8XX_REG_MO] = bin2bcd(tm->tm_mon);
buf[ABX8XX_REG_YR] = bin2bcd(tm->tm_year - 2000);
buf[ABX8XX_REG_WD] = tm->tm_wday;
err = dm_i2c_write(dev, ABX8XX_REG_HTH,
buf, sizeof(buf));
if (err < 0) {
log_err("Unable to write to date registers\n");
return -EIO;
}
/* Clear the OF bit of Oscillator Status Register */
flags = dm_i2c_reg_read(dev, ABX8XX_REG_OSS);
if (flags < 0) {
log_err("Unable to read oscillator status.\n");
return flags;
}
err = dm_i2c_reg_write(dev, ABX8XX_REG_OSS,
flags & ~ABX8XX_OSS_OF);
if (err < 0) {
log_err("Unable to write oscillator status register\n");
return err;
}
return 0;
}
static int abx80x_rtc_set_autocalibration(struct udevice *dev,
int autocalibration)
{
int retval, flags = 0;
if (autocalibration != 0 && autocalibration != 1024 &&
autocalibration != 512) {
log_err("autocalibration value outside permitted range\n");
return -EINVAL;
}
flags = dm_i2c_reg_read(dev, ABX8XX_REG_OSC);
if (flags < 0)
return flags;
if (autocalibration == 0) {
flags &= ~(ABX8XX_OSC_ACAL_512 | ABX8XX_OSC_ACAL_1024);
} else if (autocalibration == 1024) {
/* 1024 autocalibration is 0x10 */
flags |= ABX8XX_OSC_ACAL_1024;
flags &= ~(ABX8XX_OSC_ACAL_512);
} else {
/* 512 autocalibration is 0x11 */
flags |= (ABX8XX_OSC_ACAL_1024 | ABX8XX_OSC_ACAL_512);
}
/* Unlock write access to Oscillator Control Register */
retval = dm_i2c_reg_write(dev, ABX8XX_REG_CFG_KEY,
ABX8XX_CFG_KEY_OSC);
if (retval < 0) {
log_err("Failed to write CONFIG_KEY register\n");
return retval;
}
retval = dm_i2c_reg_write(dev, ABX8XX_REG_OSC, flags);
return retval;
}
static int abx80x_rtc_get_autocalibration(struct udevice *dev)
{
int flags = 0, autocalibration;
flags = dm_i2c_reg_read(dev, ABX8XX_REG_OSC);
if (flags < 0)
return flags;
if (flags & ABX8XX_OSC_ACAL_512)
autocalibration = 512;
else if (flags & ABX8XX_OSC_ACAL_1024)
autocalibration = 1024;
else
autocalibration = 0;
return autocalibration;
}
static struct rtc_time default_tm = { 0, 0, 0, 1, 1, 2000, 6, 0, 0 };
static int abx80x_rtc_reset(struct udevice *dev)
{
int ret = 0;
int autocalib = abx80x_rtc_get_autocalibration(dev);
if (autocalib != 0)
abx80x_rtc_set_autocalibration(dev, 0);
ret = abx80x_rtc_set_time(dev, &default_tm);
if (ret != 0) {
log_err("cannot set time to default_tm. error %d\n", ret);
return ret;
}
return ret;
}
static const struct rtc_ops abx80x_rtc_ops = {
.get = abx80x_rtc_read_time,
.set = abx80x_rtc_set_time,
.reset = abx80x_rtc_reset,
.read8 = abx80x_rtc_read8,
.write8 = abx80x_rtc_write8
};
static int abx80x_dt_trickle_cfg(struct udevice *dev)
{
const char *diode;
int trickle_cfg = 0;
int i, ret = 0;
u32 tmp;
diode = ofnode_read_string(dev_ofnode(dev), "abracon,tc-diode");
if (!diode)
return ret;
if (!strcmp(diode, "standard")) {
trickle_cfg |= ABX8XX_TRICKLE_STANDARD_DIODE;
} else if (!strcmp(diode, "schottky")) {
trickle_cfg |= ABX8XX_TRICKLE_SCHOTTKY_DIODE;
} else {
log_err("Invalid tc-diode value: %s\n", diode);
return -EINVAL;
}
ret = ofnode_read_u32(dev_ofnode(dev), "abracon,tc-resistor", &tmp);
if (ret)
return ret;
for (i = 0; i < sizeof(trickle_resistors); i++)
if (trickle_resistors[i] == tmp)
break;
if (i == sizeof(trickle_resistors)) {
log_err("Invalid tc-resistor value: %u\n", tmp);
return -EINVAL;
}
return (trickle_cfg | i);
}
static int abx80x_probe(struct udevice *dev)
{
int i, data, err, trickle_cfg = -EINVAL;
unsigned char buf[7];
unsigned int part = dev->driver_data;
unsigned int partnumber;
unsigned int majrev, minrev;
unsigned int lot;
unsigned int wafer;
unsigned int uid;
err = dm_i2c_read(dev, ABX8XX_REG_ID0, buf, sizeof(buf));
if (err < 0) {
log_err("Unable to read partnumber\n");
return -EIO;
}
partnumber = (buf[0] << 8) | buf[1];
majrev = buf[2] >> 3;
minrev = buf[2] & 0x7;
lot = ((buf[4] & 0x80) << 2) | ((buf[6] & 0x80) << 1) | buf[3];
uid = ((buf[4] & 0x7f) << 8) | buf[5];
wafer = (buf[6] & 0x7c) >> 2;
log_debug("model %04x, revision %u.%u, lot %x, wafer %x, uid %x\n",
partnumber, majrev, minrev, lot, wafer, uid);
data = dm_i2c_reg_read(dev, ABX8XX_REG_CTRL1);
if (data < 0) {
log_err("Unable to read control register\n");
return -EIO;
}
err = dm_i2c_reg_write(dev, ABX8XX_REG_CTRL1,
((data & ~(ABX8XX_CTRL_12_24 |
ABX8XX_CTRL_ARST)) |
ABX8XX_CTRL_WRITE));
if (err < 0) {
log_err("Unable to write control register\n");
return -EIO;
}
/* Configure RV1805 specifics */
if (part == RV1805) {
/*
* Avoid accidentally entering test mode. This can happen
* on the RV1805 in case the reserved bit 5 in control2
* register is set. RV-1805-C3 datasheet indicates that
* the bit should be cleared in section 11h - Control2.
*/
data = dm_i2c_reg_read(dev, ABX8XX_REG_CTRL2);
if (data < 0) {
log_err("Unable to read control2 register\n");
return -EIO;
}
err = dm_i2c_reg_write(dev, ABX8XX_REG_CTRL2,
data & ~ABX8XX_CTRL2_RSVD);
if (err < 0) {
log_err("Unable to write control2 register\n");
return -EIO;
}
/*
* Avoid extra power leakage. The RV1805 uses smaller
* 10pin package and the EXTI input is not present.
* Disable it to avoid leakage.
*/
data = dm_i2c_reg_read(dev, ABX8XX_REG_OUT_CTRL);
if (data < 0) {
log_err("Unable to read output control register\n");
return -EIO;
}
/*
* Write the configuration key register to enable access to
* the config2 register
*/
err = dm_i2c_reg_write(dev, ABX8XX_REG_CFG_KEY,
ABX8XX_CFG_KEY_MISC);
if (err < 0) {
log_err("Unable to write configuration key\n");
return -EIO;
}
err = dm_i2c_reg_write(dev, ABX8XX_REG_OUT_CTRL,
data | ABX8XX_OUT_CTRL_EXDS);
if (err < 0) {
log_err("Unable to write output control register\n");
return -EIO;
}
}
/* part autodetection */
if (part == ABX80X) {
for (i = 0; abx80x_caps[i].pn; i++)
if (partnumber == abx80x_caps[i].pn)
break;
if (abx80x_caps[i].pn == 0) {
log_err("Unknown part: %04x\n", partnumber);
return -EINVAL;
}
part = i;
}
if (partnumber != abx80x_caps[part].pn) {
log_err("partnumber mismatch %04x != %04x\n",
partnumber, abx80x_caps[part].pn);
return -EINVAL;
}
if (abx80x_caps[part].has_tc)
trickle_cfg = abx80x_dt_trickle_cfg(dev);
if (trickle_cfg > 0) {
log_debug("Enabling trickle charger: %02x\n", trickle_cfg);
abx80x_enable_trickle_charger(dev, trickle_cfg);
}
err = dm_i2c_reg_write(dev, ABX8XX_REG_CD_TIMER_CTL, BIT(2));
if (err)
return err;
return 0;
}
static const struct udevice_id abx80x_of_match[] = {
{
.compatible = "abracon,abx80x",
.data = ABX80X
},
{
.compatible = "abracon,ab0801",
.data = AB0801
},
{
.compatible = "abracon,ab0803",
.data = AB0803
},
{
.compatible = "abracon,ab0804",
.data = AB0804
},
{
.compatible = "abracon,ab0805",
.data = AB0805
},
{
.compatible = "abracon,ab1801",
.data = AB1801
},
{
.compatible = "abracon,ab1803",
.data = AB1803
},
{
.compatible = "abracon,ab1804",
.data = AB1804
},
{
.compatible = "abracon,ab1805",
.data = AB1805
},
{
.compatible = "microcrystal,rv1805",
.data = RV1805
},
{ }
};
U_BOOT_DRIVER(abx80x_rtc) = {
.name = "rtc-abx80x",
.id = UCLASS_RTC,
.probe = abx80x_probe,
.of_match = abx80x_of_match,
.ops = &abx80x_rtc_ops,
};
......@@ -290,6 +290,16 @@ int video_sync_copy(struct udevice *dev, void *from, void *to)
return 0;
}
int video_sync_copy_all(struct udevice *dev)
{
struct video_priv *priv = dev_get_uclass_priv(dev);
video_sync_copy(dev, priv->fb, priv->fb + priv->fb_size);
return 0;
}
#endif
/* Set up the colour map */
......
......@@ -70,6 +70,20 @@ int binman_entry_find(const char *name, struct binman_entry *entry);
*/
ofnode binman_section_find_node(const char *name);
/**
* binman_select_subnode() - Select a subnode to use to find entries
*
* Normally binman selects the top-level node for future entry requests, such as
* binman_entry_find(). This function allows a subnode to be chosen instead.
*
* @name: Name of subnode, typically a section. This must be in the top-level
* binman node
* @return 0 if OK, -EINVAL if there is no /binman node, -ECHILD if multiple
* images are being used but the first image is not available, -ENOENT if
* the requested subnode cannot be found
*/
int binman_select_subnode(const char *name);
/**
* binman_init() - Set up the binman symbol information
*
......
......@@ -242,6 +242,16 @@ void bloblist_show_list(void);
*/
const char *bloblist_tag_name(enum bloblist_tag_t tag);
/**
* bloblist_reloc() - Relocate the bloblist and optionally resize it
*
* @to: Pointer to new bloblist location (must not overlap old location)
* @to:size: New size for bloblist (must be larger than from_size)
* @from: Pointer to bloblist to relocate
* @from_size: Size of bloblist to relocate
*/
void bloblist_reloc(void *to, uint to_size, void *from, uint from_size);
/**
* bloblist_init() - Init the bloblist system with a single bloblist
*
......
......@@ -69,7 +69,7 @@ void bootcount_store(ulong);
*/
ulong bootcount_load(void);
#if defined(CONFIG_SPL_BOOTCOUNT_LIMIT) || defined(CONFIG_BOOTCOUNT_LIMIT)
#if defined(CONFIG_SPL_BOOTCOUNT_LIMIT) || defined(CONFIG_TPL_BOOTCOUNT_LIMIT) || defined(CONFIG_BOOTCOUNT_LIMIT)
#if !defined(CONFIG_SYS_BOOTCOUNT_LE) && !defined(CONFIG_SYS_BOOTCOUNT_BE)
# if __BYTE_ORDER == __LITTLE_ENDIAN
......@@ -130,7 +130,7 @@ static inline void bootcount_inc(void)
#ifndef CONFIG_SPL_BUILD
/* Only increment bootcount when no bootcount support in SPL */
#ifndef CONFIG_SPL_BOOTCOUNT_LIMIT
#if !defined(CONFIG_SPL_BOOTCOUNT_LIMIT) && !defined(CONFIG_TPL_BOOTCOUNT_LIMIT)
bootcount_store(++bootcount);
#endif
env_set_ulong("bootcount", bootcount);
......@@ -140,5 +140,5 @@ static inline void bootcount_inc(void)
#else
static inline int bootcount_error(void) { return 0; }
static inline void bootcount_inc(void) {}
#endif /* CONFIG_SPL_BOOTCOUNT_LIMIT || CONFIG_BOOTCOUNT_LIMIT */
#endif /* CONFIG_SPL_BOOTCOUNT_LIMIT || CONFIG_TPL_BOOTCOUNT_LIMIT || CONFIG_BOOTCOUNT_LIMIT */
#endif /* _BOOTCOUNT_H__ */
......@@ -11,8 +11,8 @@
* http://infocenter.arm.com/help/topic/com.arm.doc.den0028a/index.html
*/
#define ARM_SMCCC_STD_CALL 0
#define ARM_SMCCC_FAST_CALL 1
#define ARM_SMCCC_STD_CALL 0UL
#define ARM_SMCCC_FAST_CALL 1UL
#define ARM_SMCCC_TYPE_SHIFT 31
#define ARM_SMCCC_SMC_32 0
......
......@@ -58,6 +58,7 @@ static inline bool u_boot_first_phase(void)
}
enum u_boot_phase {
PHASE_NONE, /* Invalid phase, signifying before U-Boot */
PHASE_TPL, /* Running in TPL */
PHASE_SPL, /* Running in SPL */
PHASE_BOARD_F, /* Running in U-Boot before relocation */
......@@ -123,6 +124,58 @@ static inline enum u_boot_phase spl_phase(void)
#endif
}
/**
* spl_prev_phase() - Figure out the previous U-Boot phase
*
* @return the previous phase from this one, e.g. if called in SPL this returns
* PHASE_TPL, if TPL is enabled
*/
static inline enum u_boot_phase spl_prev_phase(void)
{
#ifdef CONFIG_TPL_BUILD
return PHASE_NONE;
#elif defined(CONFIG_SPL_BUILD)
return IS_ENABLED(CONFIG_TPL) ? PHASE_TPL : PHASE_NONE;
#else
return IS_ENABLED(CONFIG_SPL) ? PHASE_SPL : PHASE_NONE;
#endif
}
/**
* spl_next_phase() - Figure out the next U-Boot phase
*
* @return the next phase from this one, e.g. if called in TPL this returns
* PHASE_SPL
*/
static inline enum u_boot_phase spl_next_phase(void)
{
#ifdef CONFIG_TPL_BUILD
return PHASE_SPL;
#else
return PHASE_BOARD_F;
#endif
}
/**
* spl_phase_name() - Get the name of the current phase
*
* @return phase name
*/
static inline const char *spl_phase_name(enum u_boot_phase phase)
{
switch (phase) {
case PHASE_TPL:
return "TPL";
case PHASE_SPL:
return "SPL";
case PHASE_BOARD_F:
case PHASE_BOARD_R:
return "U-Boot";
default:
return "phase?";
}
}
/* A string name for SPL or TPL */
#ifdef CONFIG_SPL_BUILD
# ifdef CONFIG_TPL_BUILD
......
......@@ -23,6 +23,7 @@ struct uuid {
#define UUID_STR_FORMAT_GUID BIT(0)
#define UUID_STR_UPPER_CASE BIT(1)
/* Use UUID_STR_LEN + 1 for string space */
#define UUID_STR_LEN 36
#define UUID_BIN_LEN sizeof(struct uuid)
......
......@@ -246,11 +246,25 @@ void video_set_default_colors(struct udevice *dev, bool invert);
* frame buffer start
*/
int video_sync_copy(struct udevice *dev, void *from, void *to);
/**
* video_sync_copy_all() - Sync the entire framebuffer to the copy
*
* @dev: Vidconsole device being updated
* @return 0 (always)
*/
int video_sync_copy_all(struct udevice *dev);
#else
static inline int video_sync_copy(struct udevice *dev, void *from, void *to)
{
return 0;
}
static inline int video_sync_copy_all(struct udevice *dev)
{
return 0;
}
#endif
#ifndef CONFIG_DM_VIDEO
......
......@@ -92,7 +92,9 @@ obj-y += display_options.o
CFLAGS_display_options.o := $(if $(BUILD_TAG),-DBUILD_TAG='"$(BUILD_TAG)"')
obj-$(CONFIG_BCH) += bch.o
obj-$(CONFIG_MMC_SPI) += crc7.o
#ifndef CONFIG_TPL_BUILD
obj-y += crc32.o
#endif
obj-$(CONFIG_CRC32C) += crc32c.o
obj-y += ctype.o
obj-y += div64.o
......
......@@ -30,6 +30,34 @@ struct binman_info {
static struct binman_info *binman;
/**
* find_image_node() - Find the top-level binman node
*
* Finds the binman node which can be used to load entries. The correct node
* depends on whether multiple-images is in use.
*
* @nodep: Returns the node found, on success
* @return 0 if OK, , -EINVAL if there is no /binman node, -ECHILD if multiple
* images are being used but the first image is not available
*/
static int find_image_node(ofnode *nodep)
{
ofnode node;
node = ofnode_path("/binman");
if (!ofnode_valid(node))
return log_msg_ret("binman node", -EINVAL);
if (ofnode_read_bool(node, "multiple-images")) {
node = ofnode_first_subnode(node);
if (!ofnode_valid(node))
return log_msg_ret("first image", -ECHILD);
}
*nodep = node;
return 0;
}
static int binman_entry_find_internal(ofnode node, const char *name,
struct binman_entry *entry)
{
......@@ -88,21 +116,34 @@ int binman_get_rom_offset(void)
return binman->rom_offset;
}
int binman_select_subnode(const char *name)
{
ofnode node;
int ret;
ret = find_image_node(&node);
if (ret)
return log_msg_ret("main", -ENOENT);
node = ofnode_find_subnode(node, name);
if (!ofnode_valid(node))
return log_msg_ret("node", -ENOENT);
binman->image = node;
log_debug("binman: Selected image subnode '%s'\n",
ofnode_get_name(binman->image));
return 0;
}
int binman_init(void)
{
int ret;
binman = malloc(sizeof(struct binman_info));
if (!binman)
return log_msg_ret("space for binman", -ENOMEM);
binman->image = ofnode_path("/binman");
if (!ofnode_valid(binman->image))
return log_msg_ret("binman node", -EINVAL);
if (ofnode_read_bool(binman->image, "multiple-images")) {
ofnode node = ofnode_first_subnode(binman->image);
if (!ofnode_valid(node))
return log_msg_ret("first image", -ENOENT);
binman->image = node;
}
ret = find_image_node(&binman->image);
if (ret)
return log_msg_ret("node", -ENOENT);
binman_set_rom_offset(ROM_OFFSET_NONE);
return 0;
......
......@@ -169,11 +169,10 @@ int print_buffer(ulong addr, const void *data, uint width, uint count,
x = lb.us[i] = *(volatile uint16_t *)data;
else
x = lb.uc[i] = *(volatile uint8_t *)data;
#if defined(CONFIG_SPL_BUILD)
printf(" %x", (uint)x);
#else
printf(" %0*lx", width * 2, x);
#endif
if (CONFIG_IS_ENABLED(USE_TINY_PRINTF))
printf(" %x", (uint)x);
else
printf(" %0*lx", width * 2, x);
data += width;
}
......
......@@ -600,7 +600,8 @@ int fdtdec_prepare_fdt(void)
#ifdef CONFIG_SPL_BUILD
puts("Missing DTB\n");
#else
puts("No valid device tree binary found - please append one to U-Boot binary, use u-boot-dtb.bin or define CONFIG_OF_EMBED. For sandbox, use -d <file.dtb>\n");
printf("No valid device tree binary found at %p\n",
gd->fdt_blob);
# ifdef DEBUG
if (gd->fdt_blob) {
printf("fdt_blob=%p\n", gd->fdt_blob);
......@@ -1252,7 +1253,7 @@ __weak void *board_fdt_blob_setup(void)
void *fdt_blob = NULL;
#ifdef CONFIG_SPL_BUILD
/* FDT is at end of BSS unless it is in a different memory region */
if (IS_ENABLED(CONFIG_SPL_SEPARATE_BSS))
if (CONFIG_IS_ENABLED(SEPARATE_BSS))
fdt_blob = (ulong *)&_image_binary_end;
else
fdt_blob = (ulong *)&__bss_end;
......
......@@ -522,10 +522,10 @@ int rsa_verify_hash(struct image_sign_info *info,
return ret;
/* No luck, so try each of the keys in turn */
for (ndepth = 0, noffset = fdt_next_node(info->fit, sig_node,
for (ndepth = 0, noffset = fdt_next_node(blob, sig_node,
&ndepth);
(noffset >= 0) && (ndepth > 0);
noffset = fdt_next_node(info->fit, noffset, &ndepth)) {
noffset = fdt_next_node(blob, noffset, &ndepth)) {
if (ndepth == 1 && noffset != node) {
ret = rsa_verify_with_keynode(info, hash,
sig, sig_len,
......
......@@ -487,7 +487,7 @@ static int eth_pre_unbind(struct udevice *dev)
static bool eth_dev_get_mac_address(struct udevice *dev, u8 mac[ARP_HLEN])
{
#if IS_ENABLED(CONFIG_OF_CONTROL)
#if CONFIG_IS_ENABLED(OF_CONTROL)
const uint8_t *p;
p = dev_read_u8_array_ptr(dev, "mac-address", ARP_HLEN);
......
......@@ -1222,7 +1222,6 @@ CONFIG_PCI_CLK_FREQ
CONFIG_PCI_CONFIG_HOST_BRIDGE
CONFIG_PCI_EHCI_DEVICE
CONFIG_PCI_EHCI_DEVNO
CONFIG_PCI_ENUM_ONLY
CONFIG_PCI_FIXUP_DEV
CONFIG_PCI_GT64120
CONFIG_PCI_INDIRECT_BRIDGE
......
......@@ -347,6 +347,42 @@ static int bloblist_test_align(struct unit_test_state *uts)
}
BLOBLIST_TEST(bloblist_test_align, 0);
/* Test relocation of a bloblist */
static int bloblist_test_reloc(struct unit_test_state *uts)
{
const uint large_size = TEST_BLOBLIST_SIZE;
const uint small_size = 0x20;
void *old_ptr, *new_ptr;
void *blob1, *blob2;
ulong new_addr;
ulong new_size;
ut_assertok(bloblist_new(TEST_ADDR, TEST_BLOBLIST_SIZE, 0));
old_ptr = map_sysmem(TEST_ADDR, TEST_BLOBLIST_SIZE);
/* Add one blob and then one that won't fit */
blob1 = bloblist_add(TEST_TAG, small_size, 0);
ut_assertnonnull(blob1);
blob2 = bloblist_add(TEST_TAG2, large_size, 0);
ut_assertnull(blob2);
/* Relocate the bloblist somewhere else, a bit larger */
new_addr = TEST_ADDR + TEST_BLOBLIST_SIZE;
new_size = TEST_BLOBLIST_SIZE + 0x100;
new_ptr = map_sysmem(new_addr, TEST_BLOBLIST_SIZE);
bloblist_reloc(new_ptr, new_size, old_ptr, TEST_BLOBLIST_SIZE);
gd->bloblist = new_ptr;
/* Check the old blob is there and that we can now add the bigger one */
ut_assertnonnull(bloblist_find(TEST_TAG, small_size));
ut_assertnull(bloblist_find(TEST_TAG2, small_size));
blob2 = bloblist_add(TEST_TAG2, large_size, 0);
ut_assertnonnull(blob2);
return 0;
}
BLOBLIST_TEST(bloblist_test_reloc, 0);
int do_ut_bloblist(struct cmd_tbl *cmdtp, int flag, int argc,
char *const argv[])
{
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册