Xilinx changes for v2020.10-rc3

- Fix fdtfile variable setup
 - Fix bootm_*/fdt_high/initrd_high variables handling
 - Fix Kconfig dependencies for Xilinx drivers
 - Fix booting u-boot from lowest memory
 - Fix firmware payload argument count for Versal
 - Fix dfu configurations
 - Fix mio_bank property handling
 - Fix and align code around ID detection
 - Start to use ENV_VARS_UBOOT_RUNTIME_CONFIG
 - Simplify logic around reading MAC from eeprom
 - Decrease malloc length for zynqmp mini qspi
 - Enable preboot for ZynqMP and Versal
 
 i2c:
 - Fix i2c eeprom partitions handling
 
 mmc:
 - Fix logic around HS mode enabling and use proper functions
 -----BEGIN PGP SIGNATURE-----
 
 iF0EABECAB0WIQQbPNTMvXmYlBPRwx7KSWXLKUoMIQUCXz6IMgAKCRDKSWXLKUoM
 IfV4AKCbILpxWM+wyIornyU02CE9VO9j9wCggpoxmxJJfPlgGBn2ssiDh8pYKM8=
 =dIwc
 -----END PGP SIGNATURE-----

Merge tag 'xilinx-for-v2020.10-rc3' of https://gitlab.denx.de/u-boot/custodians/u-boot-microblaze

Xilinx changes for v2020.10-rc3

- Fix fdtfile variable setup
- Fix bootm_*/fdt_high/initrd_high variables handling
- Fix Kconfig dependencies for Xilinx drivers
- Fix booting u-boot from lowest memory
- Fix firmware payload argument count for Versal
- Fix dfu configurations
- Fix mio_bank property handling
- Fix and align code around ID detection
- Start to use ENV_VARS_UBOOT_RUNTIME_CONFIG
- Simplify logic around reading MAC from eeprom
- Decrease malloc length for zynqmp mini qspi
- Enable preboot for ZynqMP and Versal

i2c:
- Fix i2c eeprom partitions handling

mmc:
- Fix logic around HS mode enabling and use proper functions
This commit is contained in:
Tom Rini 2020-08-20 14:46:43 -04:00
commit 2e6132d835
57 changed files with 458 additions and 242 deletions

View File

@ -1085,6 +1085,7 @@ config ARCH_VERSAL
select DM_SERIAL
select OF_CONTROL
imply BOARD_LATE_INIT
imply ENV_VARS_UBOOT_RUNTIME_CONFIG
config ARCH_VF610
bool "Freescale Vybrid"
@ -1120,6 +1121,7 @@ config ARCH_ZYNQ
imply CMD_CLK
imply CMD_DM
imply CMD_SPL
imply ENV_VARS_UBOOT_RUNTIME_CONFIG
imply FAT_WRITE
config ARCH_ZYNQMP_R5
@ -1159,6 +1161,7 @@ config ARCH_ZYNQMP
select ZYNQMP_IPI
imply BOARD_LATE_INIT
imply CMD_DM
imply ENV_VARS_UBOOT_RUNTIME_CONFIG
imply FAT_WRITE
imply MP
imply DM_USB_GADGET
@ -1962,6 +1965,7 @@ source "board/vscom/baltos/Kconfig"
source "board/xilinx/Kconfig"
source "board/xilinx/zynq/Kconfig"
source "board/xilinx/zynqmp/Kconfig"
source "board/xilinx/versal/Kconfig"
source "board/phytium/durian/Kconfig"
source "board/xen/xenguest_arm64/Kconfig"

View File

@ -51,7 +51,7 @@
/* microSD card slot */
&sdhci1 {
status = "okay";
xlnx,mio_bank = <1>;
xlnx,mio-bank = <1>;
clock-frequency = <199998000>;
max-frequency = <50000000>;
no-1-8-v;

View File

@ -51,6 +51,6 @@
/* Micron MTFC8GAKAJCN-4M 8 GB eMMC */
&sdhci0 {
status = "okay";
xlnx,mio_bank = <0>;
xlnx,mio-bank = <0>;
clock-frequency = <199998000>;
};

View File

@ -24,15 +24,15 @@
&eeprom {
partitions {
compatible = "fixed-partitions";
#address-cells = <1>;
#size-cells = <1>;
vpd {
offset = <0>;
size = <1022>;
vpd@0 {
reg = <0 1022>;
};
bootcount: bootcount {
offset = <1022>;
size = <2>;
bootcount: bootcount@1022 {
reg = <1022 2>;
};
};
};

View File

@ -23,15 +23,15 @@
&eeprom {
partitions {
compatible = "fixed-partitions";
#address-cells = <1>;
#size-cells = <1>;
vpd {
offset = <0>;
size = <1022>;
vpd@0 {
reg = <0 1022>;
};
bootcount: bootcount {
offset = <1022>;
size = <2>;
reg = <1022 2>;
};
};
};

View File

@ -43,7 +43,7 @@
clocks = <&clk25 &clk25>;
xlnx,device_id = <0>;
no-1-8-v;
xlnx,mio_bank = <0>;
xlnx,mio-bank = <0>;
#stream-id-cells = <1>;
};
};

View File

@ -43,7 +43,7 @@
clocks = <&clk25 &clk25>;
xlnx,device_id = <1>;
no-1-8-v;
xlnx,mio_bank = <0>;
xlnx,mio-bank = <0>;
#stream-id-cells = <1>;
};
};

View File

@ -131,7 +131,7 @@
status = "okay";
no-1-8-v;
disable-wp;
xlnx,mio_bank = <1>;
xlnx,mio-bank = <1>;
};
&gem0 {

View File

@ -70,7 +70,7 @@
non-removable;
disable-wp;
bus-width = <8>;
xlnx,mio_bank = <0>;
xlnx,mio-bank = <0>;
};
&uart0 { /* uart0 MIO38-39 */

View File

@ -89,7 +89,7 @@
non-removable;
disable-wp;
bus-width = <8>;
xlnx,mio_bank = <0>; /* FIXME tap delay */
xlnx,mio-bank = <0>; /* FIXME tap delay */
};
&uart0 { /* uart0 MIO38-39 */
@ -106,7 +106,7 @@
status = "disable";
no-1-8-v;
disable-wp;
xlnx,mio_bank = <1>;
xlnx,mio-bank = <1>;
};
&gem0 {

View File

@ -85,7 +85,7 @@
non-removable;
disable-wp;
bus-width = <8>;
xlnx,mio_bank = <0>; /* FIXME tap delay */
xlnx,mio-bank = <0>; /* FIXME tap delay */
};
&uart0 { /* uart0 MIO38-39 */
@ -102,7 +102,7 @@
status = "disable";
no-1-8-v;
disable-wp;
xlnx,mio_bank = <1>;
xlnx,mio-bank = <1>;
};
&gem0 {

View File

@ -85,7 +85,7 @@
non-removable;
disable-wp;
bus-width = <8>;
xlnx,mio_bank = <0>; /* FIXME tap delay */
xlnx,mio-bank = <0>; /* FIXME tap delay */
};
&uart0 { /* uart0 MIO38-39 */
@ -102,7 +102,7 @@
status = "disable";
no-1-8-v;
disable-wp;
xlnx,mio_bank = <1>;
xlnx,mio-bank = <1>;
};
&gem0 {

View File

@ -50,7 +50,7 @@
non-removable;
disable-wp;
bus-width = <8>;
xlnx,mio_bank = <0>;
xlnx,mio-bank = <0>;
};
&uart0 { /* uart0 MIO38-39 */
@ -67,7 +67,7 @@
status = "okay";
no-1-8-v;
disable-wp;
xlnx,mio_bank = <1>;
xlnx,mio-bank = <1>;
};
&gem0 {

View File

@ -97,13 +97,13 @@
non-removable;
disable-wp; /* We don't have a write-protect detection */
bus-width = <8>;
xlnx,mio_bank = <0>;
xlnx,mio-bank = <0>;
};
/* SD1 with level shifter */
&sdhci1 {
status = "okay";
xlnx,mio_bank = <1>;
xlnx,mio-bank = <1>;
disable-wp; /* We don't have a write-protect detection */
bus-width = <4>;
};

View File

@ -148,7 +148,7 @@
&sdhci0 {
status = "okay";
bus-width = <8>;
xlnx,mio_bank = <0>;
xlnx,mio-bank = <0>;
};
/* SD1 with level shifter */
@ -158,7 +158,7 @@
* This property should be removed for supporting UHS mode
*/
no-1-8-v;
xlnx,mio_bank = <1>;
xlnx,mio-bank = <1>;
};
&uart0 {

View File

@ -259,13 +259,13 @@
status = "okay";
no-1-8-v;
disable-wp;
xlnx,mio_bank = <0>;
xlnx,mio-bank = <0>;
};
&sdhci1 {
status = "okay";
bus-width = <0x4>;
xlnx,mio_bank = <0>;
xlnx,mio-bank = <0>;
non-removable;
disable-wp;
cap-power-off-card;

View File

@ -660,7 +660,7 @@
* removed for supporting UHS mode
*/
no-1-8-v;
xlnx,mio_bank = <1>;
xlnx,mio-bank = <1>;
};
&serdes {

View File

@ -249,7 +249,7 @@
&sdhci1 {
status = "okay";
no-1-8-v;
xlnx,mio_bank = <1>;
xlnx,mio-bank = <1>;
disable-wp;
};

View File

@ -262,7 +262,7 @@
&sdhci1 {
status = "okay";
no-1-8-v;
xlnx,mio_bank = <1>;
xlnx,mio-bank = <1>;
disable-wp;
};

View File

@ -657,7 +657,7 @@
* This property should be removed for supporting UHS mode
*/
no-1-8-v;
xlnx,mio_bank = <1>;
xlnx,mio-bank = <1>;
};
&serdes {

View File

@ -568,7 +568,7 @@
* This property should be removed for supporting UHS mode
*/
no-1-8-v;
xlnx,mio_bank = <1>;
xlnx,mio-bank = <1>;
};
&serdes {

View File

@ -80,5 +80,5 @@
* removed for supporting UHS mode
*/
no-1-8-v;
xlnx,mio_bank = <1>;
xlnx,mio-bank = <1>;
};

View File

@ -245,5 +245,5 @@
* This property should be removed for supporting UHS mode
*/
no-1-8-v;
xlnx,mio_bank = <1>;
xlnx,mio-bank = <1>;
};

View File

@ -565,7 +565,7 @@
* This property should be removed for supporting UHS mode
*/
no-1-8-v;
xlnx,mio_bank = <1>;
xlnx,mio-bank = <1>;
};
&serdes {

View File

@ -569,7 +569,7 @@
* This property should be removed for supporting UHS mode
*/
no-1-8-v;
xlnx,mio_bank = <1>;
xlnx,mio-bank = <1>;
};
&serdes {

View File

@ -8,7 +8,5 @@ enum {
TCM_SPLIT,
};
#define PAYLOAD_ARG_CNT 4U
void tcm_init(u8 mode);
void mem_map_fill(void);

View File

@ -7,8 +7,6 @@
#ifndef _ASM_ARCH_SYS_PROTO_H
#define _ASM_ARCH_SYS_PROTO_H
#define PAYLOAD_ARG_CNT 5
#define ZYNQMP_CSU_SILICON_VER_MASK 0xF
#define KEY_PTR_LEN 32
@ -51,7 +49,6 @@ int zynqmp_mmio_read(const u32 address, u32 *value);
void initialize_tcm(bool mode);
void mem_map_fill(void);
int chip_id(unsigned char id);
#if defined(CONFIG_SYS_MEM_RSVD_FOR_MMU) || defined(CONFIG_DEFINE_TCM_OCM_MMAP)
void tcm_init(u8 mode);
#endif

View File

@ -415,6 +415,14 @@
reg = <0x2c>;
compatible = "i2c-eeprom";
sandbox,emul = <&emul_eeprom>;
partitions {
compatible = "fixed-partitions";
#address-cells = <1>;
#size-cells = <1>;
bootcount_i2c: bootcount@10 {
reg = <10 2>;
};
};
};
rtc_0: rtc@43 {
@ -462,6 +470,11 @@
offset = <0x13>;
};
bootcount {
compatible = "u-boot,bootcount-i2c-eeprom";
i2c-eeprom = <&bootcount_i2c>;
};
adc@0 {
compatible = "sandbox,adc";
vdd-supply = <&buck2>;

View File

@ -13,11 +13,10 @@
#include <linux/sizes.h>
#include "board.h"
#if defined(CONFIG_ZYNQ_GEM_I2C_MAC_OFFSET)
int zynq_board_read_rom_ethaddr(unsigned char *ethaddr)
{
int ret = -EINVAL;
#if defined(CONFIG_ZYNQ_GEM_I2C_MAC_OFFSET)
struct udevice *dev;
ofnode eeprom;
@ -37,10 +36,10 @@ int zynq_board_read_rom_ethaddr(unsigned char *ethaddr)
debug("%s: I2C EEPROM MAC address read failed\n", __func__);
else
debug("%s: I2C EEPROM MAC %pM\n", __func__, ethaddr);
#endif
return ret;
}
#endif
#if defined(CONFIG_OF_BOARD) || defined(CONFIG_OF_SEPARATE)
void *board_fdt_blob_setup(void)
@ -78,13 +77,19 @@ void *board_fdt_blob_setup(void)
int board_late_init_xilinx(void)
{
ulong initrd_hi;
u32 ret = 0;
phys_size_t bootm_size = gd->ram_size;
env_set_hex("script_offset_f", CONFIG_BOOT_SCRIPT_OFFSET);
if (CONFIG_IS_ENABLED(ARCH_ZYNQ))
bootm_size = min(bootm_size, (phys_size_t)(SZ_512M + SZ_256M));
initrd_hi = gd->start_addr_sp - CONFIG_STACK_SIZE;
initrd_hi = round_down(initrd_hi, SZ_16M);
env_set_addr("initrd_high", (void *)initrd_hi);
ret |= env_set_hex("script_offset_f", CONFIG_BOOT_SCRIPT_OFFSET);
ret |= env_set_addr("bootm_low", (void *)gd->ram_base);
ret |= env_set_addr("bootm_size", (void *)bootm_size);
if (ret)
printf("%s: Saving run time variables FAILED\n", __func__);
return 0;
}

View File

@ -0,0 +1,14 @@
# Copyright (c) 2020, Xilinx, Inc.
#
# SPDX-License-Identifier: GPL-2.0
if ARCH_VERSAL
config CMD_VERSAL
bool "Enable Versal specific commands"
default y
depends on ZYNQMP_FIRMWARE
help
Enable Versal specific commands.
endif

View File

@ -5,4 +5,5 @@
#
obj-y := board.o
obj-$(CONFIG_CMD_VERSAL) += cmds.o
obj-y += ../common/board.o

View File

@ -116,6 +116,9 @@ int board_late_init(void)
return 0;
}
if (!CONFIG_IS_ENABLED(ENV_VARS_UBOOT_RUNTIME_CONFIG))
return 0;
bootmode = versal_get_bootmode();
puts("Bootmode: ");
@ -229,7 +232,7 @@ int dram_init_banksize(void)
int dram_init(void)
{
if (fdtdec_setup_mem_size_base() != 0)
if (fdtdec_setup_mem_size_base_lowest() != 0)
return -EINVAL;
return 0;

105
board/xilinx/versal/cmds.c Normal file
View File

@ -0,0 +1,105 @@
// SPDX-License-Identifier: GPL-2.0
/*
* (C) Copyright 2020 Xilinx, Inc.
* Michal Simek <michal.simek@xilinx.com>
*/
#include <cpu_func.h>
#include <command.h>
#include <common.h>
#include <log.h>
#include <memalign.h>
#include <versalpl.h>
#include <zynqmp_firmware.h>
static int do_versal_load_pdi(struct cmd_tbl *cmdtp, int flag, int argc,
char * const argv[])
{
u32 buf_lo, buf_hi;
u32 ret_payload[PAYLOAD_ARG_CNT];
ulong addr, *pdi_buf;
size_t len;
int ret;
if (argc != cmdtp->maxargs) {
debug("pdi_load: incorrect parameters passed\n");
return CMD_RET_USAGE;
}
addr = simple_strtol(argv[2], NULL, 16);
if (!addr) {
debug("pdi_load: zero pdi_data address\n");
return CMD_RET_USAGE;
}
len = simple_strtoul(argv[3], NULL, 16);
if (!len) {
debug("pdi_load: zero size\n");
return CMD_RET_USAGE;
}
pdi_buf = (ulong *)ALIGN((ulong)addr, ARCH_DMA_MINALIGN);
if ((ulong)addr != (ulong)pdi_buf) {
memcpy((void *)pdi_buf, (void *)addr, len);
debug("Pdi addr:0x%lx aligned to 0x%lx\n",
addr, (ulong)pdi_buf);
}
flush_dcache_range((ulong)pdi_buf, (ulong)pdi_buf + len);
buf_lo = lower_32_bits((ulong)pdi_buf);
buf_hi = upper_32_bits((ulong)pdi_buf);
ret = xilinx_pm_request(VERSAL_PM_LOAD_PDI, VERSAL_PM_PDI_TYPE, buf_lo,
buf_hi, 0, ret_payload);
if (ret)
printf("PDI load failed with err: 0x%08x\n", ret);
return ret;
}
static struct cmd_tbl cmd_versal_sub[] = {
U_BOOT_CMD_MKENT(loadpdi, 4, 1, do_versal_load_pdi, "", ""),
};
/**
* do_versal - Handle the "versal" command-line command
* @cmdtp: Command data struct pointer
* @flag: Command flag
* @argc: Command-line argument count
* @argv: Array of command-line arguments
*
* Processes the versal specific commands
*
* Return: return 0 on success, Error value if command fails.
* CMD_RET_USAGE incase of incorrect/missing parameters.
*/
static int do_versal(struct cmd_tbl *cmdtp, int flag, int argc,
char *const argv[])
{
struct cmd_tbl *c;
int ret = CMD_RET_USAGE;
if (argc < 2)
return CMD_RET_USAGE;
c = find_cmd_tbl(argv[1], &cmd_versal_sub[0],
ARRAY_SIZE(cmd_versal_sub));
if (c)
ret = c->cmd(c, flag, argc, argv);
return cmd_process_error(c, ret);
}
#ifdef CONFIG_SYS_LONGHELP
static char versal_help_text[] =
"loadpdi addr len - Load pdi image\n"
"load pdi image at ddr address 'addr' with pdi image size 'len'\n"
;
#endif
U_BOOT_CMD(versal, 4, 1, do_versal,
"versal sub-system",
versal_help_text
)

View File

@ -6,6 +6,7 @@
#include <common.h>
#include <init.h>
#include <log.h>
#include <dm/uclass.h>
#include <env.h>
#include <fdtdec.h>
@ -33,6 +34,14 @@ int board_late_init(void)
char *new_targets;
char *env_targets;
if (!(gd->flags & GD_FLG_ENV_DEFAULT)) {
debug("Saved variables - Skipping\n");
return 0;
}
if (!CONFIG_IS_ENABLED(ENV_VARS_UBOOT_RUNTIME_CONFIG))
return 0;
switch ((zynq_slcr_get_boot_mode()) & ZYNQ_BM_MASK) {
case ZYNQ_BM_QSPI:
mode = "qspi";

View File

@ -197,67 +197,6 @@ static const struct {
};
#endif
int chip_id(unsigned char id)
{
struct pt_regs regs;
int val = -EINVAL;
if (current_el() != 3) {
regs.regs[0] = ZYNQMP_SIP_SVC_CSU_DMA_CHIPID;
regs.regs[1] = 0;
regs.regs[2] = 0;
regs.regs[3] = 0;
smc_call(&regs);
/*
* SMC returns:
* regs[0][31:0] = status of the operation
* regs[0][63:32] = CSU.IDCODE register
* regs[1][31:0] = CSU.version register
* regs[1][63:32] = CSU.IDCODE2 register
*/
switch (id) {
case IDCODE:
regs.regs[0] = upper_32_bits(regs.regs[0]);
regs.regs[0] &= ZYNQMP_CSU_IDCODE_DEVICE_CODE_MASK |
ZYNQMP_CSU_IDCODE_SVD_MASK;
regs.regs[0] >>= ZYNQMP_CSU_IDCODE_SVD_SHIFT;
val = regs.regs[0];
break;
case VERSION:
regs.regs[1] = lower_32_bits(regs.regs[1]);
regs.regs[1] &= ZYNQMP_CSU_SILICON_VER_MASK;
val = regs.regs[1];
break;
case IDCODE2:
regs.regs[1] = lower_32_bits(regs.regs[1]);
regs.regs[1] >>= ZYNQMP_CSU_VERSION_EMPTY_SHIFT;
val = regs.regs[1];
break;
default:
printf("%s, Invalid Req:0x%x\n", __func__, id);
}
} else {
switch (id) {
case IDCODE:
val = readl(ZYNQMP_CSU_IDCODE_ADDR);
val &= ZYNQMP_CSU_IDCODE_DEVICE_CODE_MASK |
ZYNQMP_CSU_IDCODE_SVD_MASK;
val >>= ZYNQMP_CSU_IDCODE_SVD_SHIFT;
break;
case VERSION:
val = readl(ZYNQMP_CSU_VER_ADDR);
val &= ZYNQMP_CSU_SILICON_VER_MASK;
break;
default:
printf("%s, Invalid Req:0x%x\n", __func__, id);
}
}
return val;
}
#define ZYNQMP_VERSION_SIZE 9
#define ZYNQMP_PL_STATUS_BIT 9
#define ZYNQMP_IPDIS_VCU_BIT 8
@ -274,9 +213,28 @@ static char *zynqmp_get_silicon_idcode_name(void)
u32 i, id, ver, j;
char *buf;
static char name[ZYNQMP_VERSION_SIZE];
u32 ret_payload[PAYLOAD_ARG_CNT];
id = chip_id(IDCODE);
ver = chip_id(IDCODE2);
xilinx_pm_request(PM_GET_CHIPID, 0, 0, 0, 0, ret_payload);
/*
* Firmware returns:
* payload[0][31:0] = status of the operation
* payload[1]] = IDCODE
* payload[2][19:0] = Version
* payload[2][28:20] = EXTENDED_IDCODE
* payload[2][29] = PL_INIT
*/
/* Get IDCODE field */
id = ret_payload[1];
id &= ZYNQMP_CSU_IDCODE_DEVICE_CODE_MASK | ZYNQMP_CSU_IDCODE_SVD_MASK;
id >>= ZYNQMP_CSU_IDCODE_SVD_SHIFT;
/* Shift silicon version info */
ver = ret_payload[2] >> ZYNQMP_CSU_VERSION_EMPTY_SHIFT;
debug("%s, ID: 0x%0X, Ver: 0x%0X\r\n", __func__, id, ver);
for (i = 0; i < ARRAY_SIZE(zynqmp_devices); i++) {
if (zynqmp_devices[i].id == id) {
@ -387,12 +345,10 @@ int board_init(void)
#if defined(CONFIG_FPGA) && defined(CONFIG_FPGA_ZYNQMPPL) && \
!defined(CONFIG_SPL_BUILD) || (defined(CONFIG_SPL_FPGA_SUPPORT) && \
defined(CONFIG_SPL_BUILD))
if (current_el() != 3) {
zynqmppl.name = zynqmp_get_silicon_idcode_name();
printf("Chip ID:\t%s\n", zynqmppl.name);
fpga_init();
fpga_add(fpga_xilinx, &zynqmppl);
}
zynqmppl.name = zynqmp_get_silicon_idcode_name();
printf("Chip ID:\t%s\n", zynqmppl.name);
fpga_init();
fpga_add(fpga_xilinx, &zynqmppl);
#endif
if (current_el() == 3)
@ -541,23 +497,30 @@ static int set_fdtfile(void)
char *compatible, *fdtfile;
const char *suffix = ".dtb";
const char *vendor = "xilinx/";
int fdt_compat_len;
if (env_get("fdtfile"))
return 0;
compatible = (char *)fdt_getprop(gd->fdt_blob, 0, "compatible", NULL);
if (compatible) {
compatible = (char *)fdt_getprop(gd->fdt_blob, 0, "compatible",
&fdt_compat_len);
if (compatible && fdt_compat_len) {
char *name;
debug("Compatible: %s\n", compatible);
/* Discard vendor prefix */
strsep(&compatible, ",");
name = strchr(compatible, ',');
if (!name)
return -EINVAL;
fdtfile = calloc(1, strlen(vendor) + strlen(compatible) +
name++;
fdtfile = calloc(1, strlen(vendor) + strlen(name) +
strlen(suffix) + 1);
if (!fdtfile)
return -ENOMEM;
sprintf(fdtfile, "%s%s%s", vendor, compatible, suffix);
sprintf(fdtfile, "%s%s%s", vendor, name, suffix);
env_set("fdtfile", fdtfile);
free(fdtfile);
@ -605,6 +568,9 @@ int board_late_init(void)
return 0;
}
if (!CONFIG_IS_ENABLED(ENV_VARS_UBOOT_RUNTIME_CONFIG))
return 0;
ret = set_fdtfile();
if (ret)
return ret;

View File

@ -119,6 +119,7 @@ CONFIG_DM_BOOTCOUNT=y
CONFIG_DM_BOOTCOUNT_RTC=y
CONFIG_BUTTON=y
CONFIG_BUTTON_GPIO=y
CONFIG_DM_BOOTCOUNT_I2C_EEPROM=y
CONFIG_CLK=y
CONFIG_CLK_COMPOSITE_CCF=y
CONFIG_SANDBOX_CLK_CCF=y

View File

@ -9,6 +9,7 @@ CONFIG_DISTRO_DEFAULTS=y
CONFIG_FIT=y
CONFIG_FIT_VERBOSE=y
CONFIG_BOOTDELAY=5
CONFIG_USE_PREBOOT=y
# CONFIG_DISPLAY_CPUINFO is not set
CONFIG_BOARD_EARLY_INIT_R=y
CONFIG_SYS_PROMPT="Versal> "
@ -43,6 +44,9 @@ CONFIG_FPGA_VERSALPL=y
CONFIG_DM_I2C=y
CONFIG_SYS_I2C_CADENCE=y
CONFIG_MISC=y
CONFIG_I2C_EEPROM=y
CONFIG_SYS_I2C_EEPROM_ADDR=0x0
CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW=0x0
CONFIG_MMC_IO_VOLTAGE=y
CONFIG_MMC_UHS_SUPPORT=y
CONFIG_MMC_HS400_SUPPORT=y

View File

@ -15,6 +15,7 @@ CONFIG_FIT=y
CONFIG_FIT_VERBOSE=y
CONFIG_SPL_LOAD_FIT=y
CONFIG_SPL_LOAD_FIT_ADDRESS=0x10000000
CONFIG_USE_PREBOOT=y
# CONFIG_DISPLAY_CPUINFO is not set
CONFIG_BOARD_EARLY_INIT_F=y
CONFIG_BOARD_EARLY_INIT_R=y
@ -65,6 +66,7 @@ CONFIG_SPL_DM_SEQ_ALIAS=y
CONFIG_SCSI_AHCI=y
CONFIG_SATA_CEVA=y
CONFIG_CLK_ZYNQMP=y
CONFIG_DFU_TFTP=y
CONFIG_DFU_RAM=y
CONFIG_USB_FUNCTION_FASTBOOT=y
CONFIG_FASTBOOT_FLASH=y

View File

@ -68,23 +68,6 @@
#define CLOCK_NODE_TYPE_DIV 4
#define CLOCK_NODE_TYPE_GATE 6
enum pm_query_id {
PM_QID_INVALID,
PM_QID_CLOCK_GET_NAME,
PM_QID_CLOCK_GET_TOPOLOGY,
PM_QID_CLOCK_GET_FIXEDFACTOR_PARAMS,
PM_QID_CLOCK_GET_PARENTS,
PM_QID_CLOCK_GET_ATTRIBUTES,
PM_QID_PINCTRL_GET_NUM_PINS,
PM_QID_PINCTRL_GET_NUM_FUNCTIONS,
PM_QID_PINCTRL_GET_NUM_FUNCTION_GROUPS,
PM_QID_PINCTRL_GET_FUNCTION_NAME,
PM_QID_PINCTRL_GET_FUNCTION_GROUPS,
PM_QID_PINCTRL_GET_PIN_GROUPS,
PM_QID_CLOCK_GET_NUM_CLOCKS,
PM_QID_CLOCK_GET_MAX_DIVISOR,
};
enum clk_type {
CLK_TYPE_OUTPUT,
CLK_TYPE_EXTERNAL,

View File

@ -37,6 +37,7 @@ static int ipi_req(const u32 *req, size_t req_len, u32 *res, size_t res_maxlen)
if (!(zynqmp_power.tx_chan.dev) || !(&zynqmp_power.rx_chan.dev))
return -EINVAL;
debug("%s, Sending IPI message with ID: 0x%0x\n", __func__, req[0]);
msg.buf = (u32 *)req;
msg.len = req_len;
ret = mbox_send(&zynqmp_power.tx_chan, &msg);
@ -54,14 +55,6 @@ static int ipi_req(const u32 *req, size_t req_len, u32 *res, size_t res_maxlen)
return ret;
}
static int send_req(const u32 *req, size_t req_len, u32 *res, size_t res_maxlen)
{
if (IS_ENABLED(CONFIG_SPL_BUILD) || current_el() == 3)
return ipi_req(req, req_len, res, res_maxlen);
return xilinx_pm_request(req[0], 0, 0, 0, 0, res);
}
unsigned int zynqmp_firmware_version(void)
{
int ret;
@ -74,9 +67,9 @@ unsigned int zynqmp_firmware_version(void)
* asking PMUFW again.
**/
if (pm_api_version == ZYNQMP_PM_VERSION_INVALID) {
const u32 request[] = { PM_GET_API_VERSION };
ret = send_req(request, ARRAY_SIZE(request), ret_payload, 2);
ret = xilinx_pm_request(PM_GET_API_VERSION, 0, 0, 0, 0,
ret_payload);
if (ret)
panic("PMUFW is not found - Please load it!\n");
@ -97,16 +90,13 @@ unsigned int zynqmp_firmware_version(void)
*/
void zynqmp_pmufw_load_config_object(const void *cfg_obj, size_t size)
{
const u32 request[] = {
PM_SET_CONFIGURATION,
(u32)((u64)cfg_obj)
};
u32 response = 0;
int err;
u32 ret_payload[PAYLOAD_ARG_CNT];
printf("Loading new PMUFW cfg obj (%ld bytes)\n", size);
err = send_req(request, ARRAY_SIZE(request), &response, 1);
err = xilinx_pm_request(PM_SET_CONFIGURATION, (u32)(u64)cfg_obj, 0, 0,
0, ret_payload);
if (err == XST_PM_NO_ACCESS) {
printf("PMUFW no permission to change config object\n");
return;
@ -115,10 +105,10 @@ void zynqmp_pmufw_load_config_object(const void *cfg_obj, size_t size)
if (err)
printf("Cannot load PMUFW configuration object (%d)\n", err);
if (response)
printf("PMUFW returned 0x%08x status!\n", response);
if (ret_payload[0])
printf("PMUFW returned 0x%08x status!\n", ret_payload[0]);
if ((err || response) && IS_ENABLED(CONFIG_SPL_BUILD))
if ((err || ret_payload[0]) && IS_ENABLED(CONFIG_SPL_BUILD))
panic("PMUFW config object loading failed in EL3\n");
}
@ -164,32 +154,44 @@ U_BOOT_DRIVER(zynqmp_power) = {
int __maybe_unused xilinx_pm_request(u32 api_id, u32 arg0, u32 arg1, u32 arg2,
u32 arg3, u32 *ret_payload)
{
/*
* Added SIP service call Function Identifier
* Make sure to stay in x0 register
*/
struct pt_regs regs;
debug("%s at EL%d, API ID: 0x%0x\n", __func__, current_el(), api_id);
if (current_el() == 3) {
printf("%s: Can't call SMC from EL3 context\n", __func__);
if (IS_ENABLED(CONFIG_SPL_BUILD) || current_el() == 3) {
#if defined(CONFIG_ZYNQMP_IPI)
/*
* Use fixed payload and arg size as the EL2 call. The firmware
* is capable to handle PMUFW_PAYLOAD_ARG_CNT bytes but the
* firmware API is limited by the SMC call size
*/
u32 regs[] = {api_id, arg0, arg1, arg2, arg3};
ipi_req(regs, PAYLOAD_ARG_CNT, ret_payload, PAYLOAD_ARG_CNT);
#else
return -EPERM;
#endif
} else {
/*
* Added SIP service call Function Identifier
* Make sure to stay in x0 register
*/
struct pt_regs regs;
regs.regs[0] = PM_SIP_SVC | api_id;
regs.regs[1] = ((u64)arg1 << 32) | arg0;
regs.regs[2] = ((u64)arg3 << 32) | arg2;
smc_call(&regs);
if (ret_payload) {
ret_payload[0] = (u32)regs.regs[0];
ret_payload[1] = upper_32_bits(regs.regs[0]);
ret_payload[2] = (u32)regs.regs[1];
ret_payload[3] = upper_32_bits(regs.regs[1]);
ret_payload[4] = (u32)regs.regs[2];
}
}
regs.regs[0] = PM_SIP_SVC | api_id;
regs.regs[1] = ((u64)arg1 << 32) | arg0;
regs.regs[2] = ((u64)arg3 << 32) | arg2;
smc_call(&regs);
if (ret_payload) {
ret_payload[0] = (u32)regs.regs[0];
ret_payload[1] = upper_32_bits(regs.regs[0]);
ret_payload[2] = (u32)regs.regs[1];
ret_payload[3] = upper_32_bits(regs.regs[1]);
ret_payload[4] = (u32)regs.regs[2];
}
return regs.regs[0];
return (ret_payload) ? ret_payload[0] : 0;
}
static const struct udevice_id zynqmp_firmware_ids[] = {

View File

@ -32,7 +32,7 @@ static int versal_load(xilinx_desc *desc, const void *buf, size_t bsize,
ulong bin_buf;
int ret;
u32 buf_lo, buf_hi;
u32 ret_payload[5];
u32 ret_payload[PAYLOAD_ARG_CNT];
bin_buf = versal_align_dma_buffer((ulong *)buf, bsize);

View File

@ -381,8 +381,8 @@ config MVEBU_GPIO
config ZYNQ_GPIO
bool "Zynq GPIO driver"
depends on DM_GPIO && (ARCH_ZYNQ || ARCH_ZYNQMP || ARCH_VERSAL)
default y
depends on DM_GPIO
default y if ARCH_ZYNQ || ARCH_ZYNQMP || ARCH_VERSAL
help
Supports GPIO access on Zynq SoC.

View File

@ -88,7 +88,7 @@ config SYS_I2C_FSL
config SYS_I2C_CADENCE
tristate "Cadence I2C Controller"
depends on DM_I2C && (ARCH_ZYNQ || ARM64)
depends on DM_I2C
help
Say yes here to select Cadence I2C Host Controller. This controller is
e.g. used by Xilinx Zynq.

View File

@ -24,10 +24,12 @@
struct ipi_int_regs {
u32 trig; /* 0x0 */
u32 obs; /* 0x4 */
u32 ist; /* 0x8 */
u32 imr; /* 0xC */
u32 ier; /* 0x10 */
u32 idr; /* 0x14 */
u32 dummy0;
u32 dummy1;
u32 isr; /* 0x10 */
u32 imr; /* 0x14 */
u32 ier; /* 0x18 */
u32 idr; /* 0x1C */
};
#define ipi_int_apu ((struct ipi_int_regs *)IPI_INT_REG_BASE_APU)
@ -66,6 +68,10 @@ static int zynqmp_ipi_recv(struct mbox_chan *chan, void *data)
struct zynqmp_ipi *zynqmp = dev_get_priv(chan->dev);
u32 *mbx = (u32 *)zynqmp->local_res_regs;
/*
* PMU Firmware does not trigger IPI interrupt for API call responses so
* there is no need to check ISR flags
*/
for (size_t i = 0; i < msg->len; i++)
msg->buf[i] = readl(&mbx[i]);

View File

@ -301,19 +301,20 @@ static int i2c_eeprom_partition_probe(struct udevice *dev)
static int i2c_eeprom_partition_ofdata_to_platdata(struct udevice *dev)
{
struct i2c_eeprom_partition *priv = dev_get_priv(dev);
u32 offset, size;
u32 reg[2];
int ret;
ret = dev_read_u32(dev, "offset", &offset);
ret = dev_read_u32_array(dev, "reg", reg, 2);
if (ret)
return ret;
ret = dev_read_u32(dev, "size", &size);
if (ret)
return ret;
if (!reg[1])
return -EINVAL;
priv->offset = offset;
priv->size = size;
priv->offset = reg[0];
priv->size = reg[1];
debug("%s: base %x, size %x\n", __func__, priv->offset, priv->size);
return 0;
}

View File

@ -653,7 +653,6 @@ config TEGRA124_MMC_DISABLE_EXT_LOOPBACK
config MMC_SDHCI_ZYNQ
bool "Arasan SDHCI controller support"
depends on ARCH_ZYNQ || ARCH_ZYNQMP || ARCH_VERSAL
depends on DM_MMC && OF_CONTROL && BLK
depends on MMC_SDHCI
help

View File

@ -748,9 +748,9 @@ int sdhci_setup_cfg(struct mmc_config *cfg, struct sdhci_host *host,
"sdhci-caps-mask", 0);
dt_caps = dev_read_u64_default(host->mmc->dev,
"sdhci-caps", 0);
caps = ~(u32)dt_caps_mask &
caps = ~lower_32_bits(dt_caps_mask) &
sdhci_readl(host, SDHCI_CAPABILITIES);
caps |= (u32)dt_caps;
caps |= lower_32_bits(dt_caps);
#else
caps = sdhci_readl(host, SDHCI_CAPABILITIES);
#endif
@ -793,9 +793,9 @@ int sdhci_setup_cfg(struct mmc_config *cfg, struct sdhci_host *host,
/* Check whether the clock multiplier is supported or not */
if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300) {
#if CONFIG_IS_ENABLED(DM_MMC)
caps_1 = ~(u32)(dt_caps_mask >> 32) &
caps_1 = ~upper_32_bits(dt_caps_mask) &
sdhci_readl(host, SDHCI_CAPABILITIES_1);
caps_1 |= (u32)(dt_caps >> 32);
caps_1 |= upper_32_bits(dt_caps);
#else
caps_1 = sdhci_readl(host, SDHCI_CAPABILITIES_1);
#endif
@ -843,7 +843,10 @@ int sdhci_setup_cfg(struct mmc_config *cfg, struct sdhci_host *host,
if (host->quirks & SDHCI_QUIRK_BROKEN_VOLTAGE)
cfg->voltages |= host->voltages;
cfg->host_caps |= MMC_MODE_HS | MMC_MODE_HS_52MHz | MMC_MODE_4BIT;
if (caps & SDHCI_CAN_DO_HISPD)
cfg->host_caps |= MMC_MODE_HS | MMC_MODE_HS_52MHz;
cfg->host_caps |= MMC_MODE_4BIT;
/* Since Host Controller Version3.0 */
if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300) {

View File

@ -276,7 +276,7 @@ static int arasan_sdhci_ofdata_to_platdata(struct udevice *dev)
return PTR_ERR(priv->host->ioaddr);
priv->deviceid = dev_read_u32_default(dev, "xlnx,device_id", -1);
priv->bank = dev_read_u32_default(dev, "xlnx,mio_bank", -1);
priv->bank = dev_read_u32_default(dev, "xlnx,mio-bank", 0);
return 0;
}

View File

@ -519,7 +519,7 @@ config TULIP
This driver supports DEC DC2114x Fast ethernet chips.
config XILINX_AXIEMAC
depends on DM_ETH && (MICROBLAZE || ARCH_ZYNQ || ARCH_ZYNQMP)
depends on DM_ETH
select PHYLIB
select MII
bool "Xilinx AXI Ethernet"
@ -527,7 +527,7 @@ config XILINX_AXIEMAC
This MAC is present in Xilinx Microblaze, Zynq and ZynqMP SoCs.
config XILINX_EMACLITE
depends on DM_ETH && (MICROBLAZE || ARCH_ZYNQ || ARCH_ZYNQMP || MIPS)
depends on DM_ETH
select PHYLIB
select MII
bool "Xilinx Ethernetlite"
@ -535,7 +535,7 @@ config XILINX_EMACLITE
This MAC is present in Xilinx Microblaze, Zynq and ZynqMP SoCs.
config ZYNQ_GEM
depends on DM_ETH && (ARCH_ZYNQ || ARCH_ZYNQMP || ARCH_VERSAL)
depends on DM_ETH
select PHYLIB
bool "Xilinx Ethernet GEM"
help

View File

@ -54,7 +54,7 @@
#define DFU_ALT_INFO_RAM \
"dfu_ram_info=" \
"setenv dfu_alt_info " \
"Image ram $kernel_addr_r $kernel_size_r\\\\;" \
"Image ram 80000 $kernel_size_r\\\\;" \
"system.dtb ram $fdt_addr_r $fdt_size_r\0" \
"dfu_ram=run dfu_ram_info && dfu 0 ram 0\0" \
"thor_ram=run dfu_ram_info && thordown 0 ram 0\0"
@ -79,7 +79,6 @@
#define CONFIG_CLOCKS
#define ENV_MEM_LAYOUT_SETTINGS \
"fdt_high=10000000\0" \
"fdt_addr_r=0x40000000\0" \
"fdt_size_r=0x400000\0" \
"pxefile_addr_r=0x10000000\0" \

View File

@ -58,10 +58,12 @@
#define DFU_ALT_INFO_RAM \
"dfu_ram_info=" \
"setenv dfu_alt_info " \
"Image ram $kernel_addr $kernel_size\\\\;" \
"system.dtb ram $fdt_addr $fdt_size\0" \
"Image ram 80000 $kernel_size_r\\\\;" \
"system.dtb ram $fdt_addr_r $fdt_size_r\0" \
"dfu_ram=run dfu_ram_info && dfu 0 ram 0\0" \
"thor_ram=run dfu_ram_info && thordown 0 ram 0\0"
"thor_ram=run dfu_ram_info && thordown 0 ram 0\0" \
"dfu_ram_tftp=run dfu_ram_info && setenv updatefile boot && " \
"setenv loadaddr 10000000 && dfu tftp ram 0\0"
#define DFU_ALT_INFO \
DFU_ALT_INFO_RAM
@ -99,10 +101,11 @@
#define CONFIG_CLOCKS
#define ENV_MEM_LAYOUT_SETTINGS \
"fdt_high=10000000\0" \
"fdt_addr_r=0x40000000\0" \
"fdt_size_r=0x400000\0" \
"pxefile_addr_r=0x10000000\0" \
"kernel_addr_r=0x18000000\0" \
"kernel_size_r=0x10000000\0" \
"scriptaddr=0x20000000\0" \
"ramdisk_addr_r=0x02100000\0" \
"script_size_f=0x80000\0" \

View File

@ -13,6 +13,6 @@
#include <configs/xilinx_zynqmp_mini.h>
#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_TEXT_BASE + 0x20000)
#define CONFIG_SYS_MALLOC_LEN 0x2000
#define CONFIG_SYS_MALLOC_LEN 0x1a00
#endif /* __CONFIG_ZYNQMP_MINI_QSPI_H */

View File

@ -196,7 +196,6 @@
/* Default environment */
#ifndef CONFIG_EXTRA_ENV_SETTINGS
#define CONFIG_EXTRA_ENV_SETTINGS \
"fdt_high=0x20000000\0" \
"scriptaddr=0x20000\0" \
"script_size_f=0x40000\0" \
"fdt_addr_r=0x1f00000\0" \

View File

@ -926,6 +926,23 @@ int fdtdec_decode_display_timing(const void *blob, int node, int index,
*/
int fdtdec_setup_mem_size_base(void);
/**
* fdtdec_setup_mem_size_base_lowest() - decode and setup gd->ram_size and
* gd->ram_start by lowest available memory base
*
* Decode the /memory 'reg' property to determine the lowest start of the memory
* bank bank and populate the global data with it.
*
* This function should be called from a boards dram_init(). This helper
* function allows for boards to query the device tree for DRAM size and start
* address instead of hard coding the value in the case where the memory size
* and start address cannot be detected automatically.
*
* @return 0 if OK, -EINVAL if the /memory node or reg property is missing or
* invalid
*/
int fdtdec_setup_mem_size_base_lowest(void);
/**
* fdtdec_setup_memory_banksize() - decode and populate gd->bd->bi_dram
*

View File

@ -62,6 +62,23 @@ enum pm_api_id {
PM_API_MAX,
};
enum pm_query_id {
PM_QID_INVALID = 0,
PM_QID_CLOCK_GET_NAME = 1,
PM_QID_CLOCK_GET_TOPOLOGY = 2,
PM_QID_CLOCK_GET_FIXEDFACTOR_PARAMS = 3,
PM_QID_CLOCK_GET_PARENTS = 4,
PM_QID_CLOCK_GET_ATTRIBUTES = 5,
PM_QID_PINCTRL_GET_NUM_PINS = 6,
PM_QID_PINCTRL_GET_NUM_FUNCTIONS = 7,
PM_QID_PINCTRL_GET_NUM_FUNCTION_GROUPS = 8,
PM_QID_PINCTRL_GET_FUNCTION_NAME = 9,
PM_QID_PINCTRL_GET_FUNCTION_GROUPS = 10,
PM_QID_PINCTRL_GET_PIN_GROUPS = 11,
PM_QID_CLOCK_GET_NUM_CLOCKS = 12,
PM_QID_CLOCK_GET_MAX_DIVISOR = 13,
};
#define PM_SIP_SVC 0xc2000000
#define ZYNQMP_PM_VERSION_MAJOR 1
@ -77,6 +94,15 @@ enum pm_api_id {
#define PMUFW_V1_0 ((1 << ZYNQMP_PM_VERSION_MAJOR_SHIFT) | 0)
/*
* Return payload size
* Not every firmware call expects the same amount of return bytes, however the
* firmware driver always copies 5 bytes from RX buffer to the ret_payload
* buffer. Therefore allocating with this defined value is recommended to avoid
* overflows.
*/
#define PAYLOAD_ARG_CNT 5U
unsigned int zynqmp_firmware_version(void);
void zynqmp_pmufw_load_config_object(const void *cfg_obj, size_t size);
int xilinx_pm_request(u32 api_id, u32 arg0, u32 arg1, u32 arg2,

View File

@ -24,6 +24,7 @@
#include <asm/sections.h>
#include <linux/ctype.h>
#include <linux/lzo.h>
#include <linux/ioport.h>
DECLARE_GLOBAL_DATA_PTR;
@ -1032,16 +1033,17 @@ int fdtdec_decode_display_timing(const void *blob, int parent, int index,
int fdtdec_setup_mem_size_base(void)
{
int ret, mem;
struct fdt_resource res;
int ret;
ofnode mem;
struct resource res;
mem = fdt_path_offset(gd->fdt_blob, "/memory");
if (mem < 0) {
mem = ofnode_path("/memory");
if (!ofnode_valid(mem)) {
debug("%s: Missing /memory node\n", __func__);
return -EINVAL;
}
ret = fdt_get_resource(gd->fdt_blob, mem, "reg", 0, &res);
ret = ofnode_read_resource(mem, 0, &res);
if (ret != 0) {
debug("%s: Unable to decode first memory bank\n", __func__);
return -EINVAL;
@ -1057,42 +1059,42 @@ int fdtdec_setup_mem_size_base(void)
#if defined(CONFIG_NR_DRAM_BANKS)
static int get_next_memory_node(const void *blob, int mem)
ofnode get_next_memory_node(ofnode mem)
{
do {
mem = fdt_node_offset_by_prop_value(gd->fdt_blob, mem,
"device_type", "memory", 7);
} while (!fdtdec_get_is_enabled(blob, mem));
mem = ofnode_by_prop_value(mem, "device_type", "memory", 7);
} while (!ofnode_is_available(mem));
return mem;
}
int fdtdec_setup_memory_banksize(void)
{
int bank, ret, mem, reg = 0;
struct fdt_resource res;
int bank, ret, reg = 0;
struct resource res;
ofnode mem = ofnode_null();
mem = get_next_memory_node(gd->fdt_blob, -1);
if (mem < 0) {
mem = get_next_memory_node(mem);
if (!ofnode_valid(mem)) {
debug("%s: Missing /memory node\n", __func__);
return -EINVAL;
}
for (bank = 0; bank < CONFIG_NR_DRAM_BANKS; bank++) {
ret = fdt_get_resource(gd->fdt_blob, mem, "reg", reg++, &res);
if (ret == -FDT_ERR_NOTFOUND) {
ret = ofnode_read_resource(mem, reg++, &res);
if (ret < 0) {
reg = 0;
mem = get_next_memory_node(gd->fdt_blob, mem);
if (mem == -FDT_ERR_NOTFOUND)
mem = get_next_memory_node(mem);
if (ofnode_valid(mem))
break;
ret = fdt_get_resource(gd->fdt_blob, mem, "reg", reg++, &res);
if (ret == -FDT_ERR_NOTFOUND)
ret = ofnode_read_resource(mem, reg++, &res);
if (ret < 0)
break;
}
if (ret != 0) {
if (ret != 0)
return -EINVAL;
}
gd->bd->bi_dram[bank].start = (phys_addr_t)res.start;
gd->bd->bi_dram[bank].size =
@ -1106,6 +1108,52 @@ int fdtdec_setup_memory_banksize(void)
return 0;
}
int fdtdec_setup_mem_size_base_lowest(void)
{
int bank, ret, reg = 0;
struct resource res;
unsigned long base;
phys_size_t size;
ofnode mem = ofnode_null();
gd->ram_base = (unsigned long)~0;
mem = get_next_memory_node(mem);
if (!ofnode_valid(mem)) {
debug("%s: Missing /memory node\n", __func__);
return -EINVAL;
}
for (bank = 0; bank < CONFIG_NR_DRAM_BANKS; bank++) {
ret = ofnode_read_resource(mem, reg++, &res);
if (ret < 0) {
reg = 0;
mem = get_next_memory_node(mem);
if (ofnode_valid(mem))
break;
ret = ofnode_read_resource(mem, reg++, &res);
if (ret < 0)
break;
}
if (ret != 0)
return -EINVAL;
base = (unsigned long)res.start;
size = (phys_size_t)(res.end - res.start + 1);
if (gd->ram_base > base && size) {
gd->ram_base = base;
gd->ram_size = size;
debug("%s: Initial DRAM base %lx size %lx\n",
__func__, base, (unsigned long)size);
}
}
return 0;
}
#endif
#if CONFIG_IS_ENABLED(MULTI_DTB_FIT)

View File

@ -25,6 +25,14 @@ static int dm_test_bootcount(struct unit_test_state *uts)
ut_assertok(dm_bootcount_get(dev, &val));
ut_assert(val == 0xab);
ut_assertok(uclass_get_device(UCLASS_BOOTCOUNT, 1, &dev));
ut_assertok(dm_bootcount_set(dev, 0));
ut_assertok(dm_bootcount_get(dev, &val));
ut_assert(val == 0);
ut_assertok(dm_bootcount_set(dev, 0xab));
ut_assertok(dm_bootcount_get(dev, &val));
ut_assert(val == 0xab);
return 0;
}