summaryrefslogtreecommitdiff
path: root/board
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2021-08-27 15:33:02 +0300
committerTom Rini <trini@konsulko.com>2021-08-27 15:33:02 +0300
commitb9cb74a5aa256fc34a1b2b9dd847a985b91f34f6 (patch)
treea618344b253ec3164848e797a2636bbd8f060223 /board
parent7bfa565453ec5f63668a3464da21629055c3053f (diff)
parent229cb5c6ba3469cbc4a0bcc69389fe61c51fd3b4 (diff)
downloadu-boot-b9cb74a5aa256fc34a1b2b9dd847a985b91f34f6.tar.xz
Merge tag 'xilinx-for-v2021.10-rc3' of https://gitlab.denx.de/u-boot/custodians/u-boot-microblaze
Xilinx changes for v2021.10-rc3 xilinx: - Disable CONFIG_ARCH_FIXUP_FDT_MEMORY - Print information about cpu via soc drivers and enable DISPLAY_CPUINFO - Wire infrastructure for DTB_RESELECT and MULTI_DTB_FIT zynq: - Wire single QSPI - Use power-source instead of io-standard properties - Enable nor on zc770-xm012 zynqmp: - Change handling around multi_boot() - Setup offset for u-boot.itb in spi - Generate run time dfu_alt_info for capsule update - Use explicit values for enums (zynqmp_firmware.h) - Enable RTC/SHA1/BUTTON/BUTTON_GPIO command - Disable WDT driver by default - Bind usb/scsi via preboot because of EFI - DT updates/fixes - Add soc driver - Fix SPL SPI boot mode versal: - Add soc driver sdhci: - Update tap delay programming for zynq_sdhci driver cmd: - Fix RTC uclass handling in date command - Update pwm help message - Update reset help message watchdog: - Fix wwdt compilation rtc: - Deal with seq alias in rtc uclass - Add zynqmp RTC driver fdt: - Add kernel-doc for fdt_fixup_memory_banks()
Diffstat (limited to 'board')
-rw-r--r--board/xilinx/common/board.c184
-rw-r--r--board/xilinx/zynqmp/Makefile2
-rw-r--r--board/xilinx/zynqmp/tap_delays.c101
-rw-r--r--board/xilinx/zynqmp/zynqmp.c74
4 files changed, 223 insertions, 138 deletions
diff --git a/board/xilinx/common/board.c b/board/xilinx/common/board.c
index 92b61d83ca..9006bd3b4d 100644
--- a/board/xilinx/common/board.c
+++ b/board/xilinx/common/board.c
@@ -18,6 +18,8 @@
#include <i2c_eeprom.h>
#include <net.h>
#include <generated/dt.h>
+#include <soc.h>
+#include <linux/ctype.h>
#include "fru.h"
@@ -67,7 +69,7 @@ struct xilinx_board_description {
};
static int highest_id = -1;
-static struct xilinx_board_description **board_info;
+static struct xilinx_board_description *board_info;
#define XILINX_I2C_DETECTION_BITS sizeof(struct fru_common_hdr)
@@ -167,7 +169,7 @@ static bool xilinx_detect_legacy(u8 *buffer)
static int xilinx_read_eeprom_fru(struct udevice *dev, char *name,
struct xilinx_board_description *desc)
{
- int ret, eeprom_size;
+ int i, ret, eeprom_size;
u8 *fru_content;
/* FIXME this is shortcut - if eeprom type is wrong it will fail */
@@ -184,21 +186,23 @@ static int xilinx_read_eeprom_fru(struct udevice *dev, char *name,
eeprom_size);
if (ret) {
debug("%s: I2C EEPROM read failed\n", __func__);
- free(fru_content);
- return ret;
+ goto end;
}
- printf("Xilinx I2C FRU format at %s:\n", name);
fru_capture((unsigned long)fru_content);
- ret = fru_display(0);
- if (ret) {
- printf("FRU format decoding failed.\n");
- return ret;
+ if (gd->flags & GD_FLG_RELOC || (_DEBUG && CONFIG_IS_ENABLED(DTB_RESELECT))) {
+ printf("Xilinx I2C FRU format at %s:\n", name);
+ ret = fru_display(0);
+ if (ret) {
+ printf("FRU format decoding failed.\n");
+ goto end;
+ }
}
if (desc->header == EEPROM_HEADER_MAGIC) {
debug("Information already filled\n");
- return -EINVAL;
+ ret = -EINVAL;
+ goto end;
}
/* It is clear that FRU was captured and structures were filled */
@@ -206,13 +210,19 @@ static int xilinx_read_eeprom_fru(struct udevice *dev, char *name,
sizeof(desc->manufacturer));
strncpy(desc->name, (char *)fru_data.brd.product_name,
sizeof(desc->name));
+ for (i = 0; i < sizeof(desc->name); i++) {
+ if (desc->name[i] == ' ')
+ desc->name[i] = '\0';
+ }
strncpy(desc->revision, (char *)fru_data.brd.rev,
sizeof(desc->revision));
strncpy(desc->serial, (char *)fru_data.brd.serial_number,
sizeof(desc->serial));
desc->header = EEPROM_HEADER_MAGIC;
- return 0;
+end:
+ free(fru_content);
+ return ret;
}
static bool xilinx_detect_fru(u8 *buffer)
@@ -275,7 +285,7 @@ static int xilinx_read_eeprom_single(char *name,
__maybe_unused int xilinx_read_eeprom(void)
{
- int id, ret;
+ int id;
char name_buf[8]; /* 8 bytes should be enough for nvmem+number */
struct xilinx_board_description *desc;
@@ -284,7 +294,7 @@ __maybe_unused int xilinx_read_eeprom(void)
if (highest_id < 0)
return -EINVAL;
- board_info = calloc(1, sizeof(desc) * highest_id);
+ board_info = calloc(1, sizeof(*desc) * (highest_id + 1));
if (!board_info)
return -ENOMEM;
@@ -295,21 +305,10 @@ __maybe_unused int xilinx_read_eeprom(void)
snprintf(name_buf, sizeof(name_buf), "nvmem%d", id);
/* Alloc structure */
- desc = board_info[id];
- if (!desc) {
- desc = calloc(1, sizeof(*desc));
- if (!desc)
- return -ENOMEM;
-
- board_info[id] = desc;
- }
+ desc = &board_info[id];
/* Ignoring return value for supporting multiple chips */
- ret = xilinx_read_eeprom_single(name_buf, desc);
- if (ret) {
- free(desc);
- board_info[id] = NULL;
- }
+ xilinx_read_eeprom_single(name_buf, desc);
}
/*
@@ -395,7 +394,7 @@ int board_late_init_xilinx(void)
ret |= env_set_addr("bootm_size", (void *)bootm_size);
for (id = 0; id <= highest_id; id++) {
- desc = board_info[id];
+ desc = &board_info[id];
if (desc && desc->header == EEPROM_HEADER_MAGIC) {
if (desc->manufacturer[0])
ret |= env_set_by_index("manufacturer", id,
@@ -431,12 +430,139 @@ int board_late_init_xilinx(void)
}
#endif
+static char *board_name = DEVICE_TREE;
+
int __maybe_unused board_fit_config_name_match(const char *name)
{
- debug("%s: Check %s, default %s\n", __func__, name, DEVICE_TREE);
+ debug("%s: Check %s, default %s\n", __func__, name, board_name);
- if (!strcmp(name, DEVICE_TREE))
+ if (!strcmp(name, board_name))
return 0;
return -1;
}
+
+#if defined(CONFIG_DISPLAY_CPUINFO) && !defined(CONFIG_ARCH_ZYNQ)
+int print_cpuinfo(void)
+{
+ struct udevice *soc;
+ char name[SOC_MAX_STR_SIZE];
+ int ret;
+
+ ret = soc_get(&soc);
+ if (ret) {
+ printf("CPU: UNKNOWN\n");
+ return 0;
+ }
+
+ ret = soc_get_family(soc, name, SOC_MAX_STR_SIZE);
+ if (ret)
+ printf("CPU: %s\n", name);
+
+ ret = soc_get_revision(soc, name, SOC_MAX_STR_SIZE);
+ if (ret)
+ printf("Silicon: %s\n", name);
+
+ return 0;
+}
+#endif
+
+#if CONFIG_IS_ENABLED(DTB_RESELECT)
+#define MAX_NAME_LENGTH 50
+
+char * __maybe_unused __weak board_name_decode(void)
+{
+ char *board_local_name;
+ struct xilinx_board_description *desc;
+ int i, id;
+
+ board_local_name = calloc(1, MAX_NAME_LENGTH);
+ if (!board_info)
+ return NULL;
+
+ for (id = 0; id <= highest_id; id++) {
+ desc = &board_info[id];
+
+ /* No board description */
+ if (!desc)
+ goto error;
+
+ /* Board is not detected */
+ if (desc->header != EEPROM_HEADER_MAGIC)
+ continue;
+
+ /* The first string should be soc name */
+ if (!id)
+ strcat(board_local_name, CONFIG_SYS_BOARD);
+
+ /*
+ * For two purpose here:
+ * soc_name- eg: zynqmp-
+ * and between base board and CC eg: ..revA-sck...
+ */
+ strcat(board_local_name, "-");
+
+ if (desc->name[0]) {
+ /* For DT composition name needs to be lowercase */
+ for (i = 0; i < sizeof(desc->name); i++)
+ desc->name[i] = tolower(desc->name[i]);
+
+ strcat(board_local_name, desc->name);
+ }
+ if (desc->revision[0]) {
+ strcat(board_local_name, "-rev");
+
+ /* And revision needs to be uppercase */
+ for (i = 0; i < sizeof(desc->revision); i++)
+ desc->revision[i] = toupper(desc->revision[i]);
+
+ strcat(board_local_name, desc->revision);
+ }
+ }
+
+ /*
+ * Longer strings will end up with buffer overflow and potential
+ * attacks that's why check it
+ */
+ if (strlen(board_local_name) >= MAX_NAME_LENGTH)
+ panic("Board name can't be determined\n");
+
+ if (strlen(board_local_name))
+ return board_local_name;
+
+error:
+ free(board_local_name);
+ return NULL;
+}
+
+bool __maybe_unused __weak board_detection(void)
+{
+ if (CONFIG_IS_ENABLED(DM_I2C) && CONFIG_IS_ENABLED(I2C_EEPROM)) {
+ int ret;
+
+ ret = xilinx_read_eeprom();
+ return !ret ? true : false;
+ }
+
+ return false;
+}
+
+int embedded_dtb_select(void)
+{
+ if (board_detection()) {
+ char *board_local_name;
+
+ board_local_name = board_name_decode();
+ if (board_local_name) {
+ board_name = board_local_name;
+ printf("Detected name: %s\n", board_name);
+
+ /* Time to change DTB on fly */
+ /* Both ways should work here */
+ /* fdtdec_resetup(&rescan); */
+ fdtdec_setup();
+ }
+ }
+ return 0;
+}
+#endif
diff --git a/board/xilinx/zynqmp/Makefile b/board/xilinx/zynqmp/Makefile
index 7d8277ca40..a914028753 100644
--- a/board/xilinx/zynqmp/Makefile
+++ b/board/xilinx/zynqmp/Makefile
@@ -44,8 +44,6 @@ $(obj)/pm_cfg_obj.o: $(shell cd $(srctree); readlink -f $(CONFIG_ZYNQMP_SPL_PM_C
endif
endif
-obj-$(CONFIG_MMC_SDHCI_ZYNQ) += tap_delays.o
-
ifndef CONFIG_SPL_BUILD
obj-$(CONFIG_CMD_ZYNQMP) += cmds.o
endif
diff --git a/board/xilinx/zynqmp/tap_delays.c b/board/xilinx/zynqmp/tap_delays.c
deleted file mode 100644
index d16bbb8eff..0000000000
--- a/board/xilinx/zynqmp/tap_delays.c
+++ /dev/null
@@ -1,101 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Xilinx ZynqMP SoC Tap Delay Programming
- *
- * Copyright (C) 2018 Xilinx, Inc.
- */
-
-#include <common.h>
-#include <zynqmp_tap_delay.h>
-#include <asm/arch/sys_proto.h>
-#include <linux/delay.h>
-#include <mmc.h>
-
-#define SD_DLL_CTRL 0xFF180358
-#define SD_ITAP_DLY 0xFF180314
-#define SD_OTAP_DLY 0xFF180318
-#define SD0_DLL_RST_MASK 0x00000004
-#define SD0_DLL_RST 0x00000004
-#define SD1_DLL_RST_MASK 0x00040000
-#define SD1_DLL_RST 0x00040000
-#define SD0_ITAPCHGWIN_MASK 0x00000200
-#define SD0_ITAPCHGWIN 0x00000200
-#define SD1_ITAPCHGWIN_MASK 0x02000000
-#define SD1_ITAPCHGWIN 0x02000000
-#define SD0_ITAPDLYENA_MASK 0x00000100
-#define SD0_ITAPDLYENA 0x00000100
-#define SD1_ITAPDLYENA_MASK 0x01000000
-#define SD1_ITAPDLYENA 0x01000000
-#define SD0_ITAPDLYSEL_MASK 0x000000FF
-#define SD1_ITAPDLYSEL_MASK 0x00FF0000
-#define SD0_OTAPDLYSEL_MASK 0x0000003F
-#define SD1_OTAPDLYSEL_MASK 0x003F0000
-
-void zynqmp_dll_reset(u8 deviceid)
-{
- /* Issue DLL Reset */
- if (deviceid == 0)
- zynqmp_mmio_write(SD_DLL_CTRL, SD0_DLL_RST_MASK,
- SD0_DLL_RST);
- else
- zynqmp_mmio_write(SD_DLL_CTRL, SD1_DLL_RST_MASK,
- SD1_DLL_RST);
-
- mdelay(1);
-
- /* Release DLL Reset */
- if (deviceid == 0)
- zynqmp_mmio_write(SD_DLL_CTRL, SD0_DLL_RST_MASK, 0x0);
- else
- zynqmp_mmio_write(SD_DLL_CTRL, SD1_DLL_RST_MASK, 0x0);
-}
-
-void arasan_zynqmp_set_in_tapdelay(u8 deviceid, u32 itap_delay)
-{
- if (deviceid == 0) {
- zynqmp_mmio_write(SD_DLL_CTRL, SD0_DLL_RST_MASK, SD0_DLL_RST);
-
- /* Program ITAP delay */
- zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPCHGWIN_MASK,
- SD0_ITAPCHGWIN);
- zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPDLYENA_MASK,
- SD0_ITAPDLYENA);
- zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPDLYSEL_MASK, itap_delay);
- zynqmp_mmio_write(SD_ITAP_DLY, SD0_ITAPCHGWIN_MASK, 0x0);
-
- zynqmp_mmio_write(SD_DLL_CTRL, SD0_DLL_RST_MASK, 0x0);
- } else {
- zynqmp_mmio_write(SD_DLL_CTRL, SD1_DLL_RST_MASK, SD1_DLL_RST);
-
- /* Program ITAP delay */
- zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPCHGWIN_MASK,
- SD1_ITAPCHGWIN);
- zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPDLYENA_MASK,
- SD1_ITAPDLYENA);
- zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPDLYSEL_MASK,
- (itap_delay << 16));
- zynqmp_mmio_write(SD_ITAP_DLY, SD1_ITAPCHGWIN_MASK, 0x0);
-
- zynqmp_mmio_write(SD_DLL_CTRL, SD1_DLL_RST_MASK, 0x0);
- }
-}
-
-void arasan_zynqmp_set_out_tapdelay(u8 deviceid, u32 otap_delay)
-{
- if (deviceid == 0) {
- zynqmp_mmio_write(SD_DLL_CTRL, SD0_DLL_RST_MASK, SD0_DLL_RST);
-
- /* Program OTAP delay */
- zynqmp_mmio_write(SD_OTAP_DLY, SD0_OTAPDLYSEL_MASK, otap_delay);
-
- zynqmp_mmio_write(SD_DLL_CTRL, SD0_DLL_RST_MASK, 0x0);
- } else {
- zynqmp_mmio_write(SD_DLL_CTRL, SD1_DLL_RST_MASK, SD1_DLL_RST);
-
- /* Program OTAP delay */
- zynqmp_mmio_write(SD_OTAP_DLY, SD1_OTAPDLYSEL_MASK,
- (otap_delay << 16));
-
- zynqmp_mmio_write(SD_DLL_CTRL, SD1_DLL_RST_MASK, 0x0);
- }
-}
diff --git a/board/xilinx/zynqmp/zynqmp.c b/board/xilinx/zynqmp/zynqmp.c
index 38c910fa5b..ea15e62eb2 100644
--- a/board/xilinx/zynqmp/zynqmp.c
+++ b/board/xilinx/zynqmp/zynqmp.c
@@ -8,6 +8,7 @@
#include <command.h>
#include <cpu_func.h>
#include <debug_uart.h>
+#include <dfu.h>
#include <env.h>
#include <env_internal.h>
#include <init.h>
@@ -19,6 +20,7 @@
#include <ahci.h>
#include <scsi.h>
#include <malloc.h>
+#include <memalign.h>
#include <wdt.h>
#include <asm/arch/clk.h>
#include <asm/arch/hardware.h>
@@ -346,13 +348,14 @@ int board_early_init_f(void)
static int multi_boot(void)
{
- u32 multiboot;
-
- multiboot = readl(&csu_base->multi_boot);
+ u32 multiboot = 0;
+ int ret;
- printf("Multiboot:\t%d\n", multiboot);
+ ret = zynqmp_mmio_read((ulong)&csu_base->multi_boot, &multiboot);
+ if (ret)
+ return -EINVAL;
- return 0;
+ return multiboot;
}
#define PS_SYSMON_ANALOG_BUS_VAL 0x3210
@@ -392,7 +395,7 @@ int board_init(void)
#endif
if (current_el() == 3)
- multi_boot();
+ printf("Multiboot:\t%d\n", multi_boot());
return 0;
}
@@ -467,6 +470,9 @@ ulong board_get_usable_ram_top(ulong total_size)
phys_addr_t reg;
struct lmb lmb;
+ if (!IS_ALIGNED((ulong)gd->fdt_blob, 0x8))
+ panic("Not 64bit aligned DT location: %p\n", gd->fdt_blob);
+
/* found enough not-reserved memory to relocated U-Boot */
lmb_init(&lmb);
lmb_add(&lmb, gd->ram_base, gd->ram_size);
@@ -515,6 +521,9 @@ static u8 __maybe_unused zynqmp_get_bootmode(void)
if (ret)
return -EINVAL;
+ debug("HW boot mode: %x\n", reg & BOOT_MODES_MASK);
+ debug("ALT boot mode: %x\n", reg >> BOOT_MODE_ALT_SHIFT);
+
if (reg >> BOOT_MODE_ALT_SHIFT)
reg >>= BOOT_MODE_ALT_SHIFT;
@@ -735,6 +744,7 @@ int board_late_init(void)
env_targets ? env_targets : "");
env_set("boot_targets", new_targets);
+ free(new_targets);
reset_reason();
@@ -816,3 +826,55 @@ enum env_location env_get_location(enum env_operation op, int prio)
return ENVL_NOWHERE;
}
}
+
+#if defined(CONFIG_SET_DFU_ALT_INFO)
+
+#define DFU_ALT_BUF_LEN SZ_1K
+
+void set_dfu_alt_info(char *interface, char *devstr)
+{
+ u8 multiboot;
+ int bootseq = 0;
+
+ ALLOC_CACHE_ALIGN_BUFFER(char, buf, DFU_ALT_BUF_LEN);
+
+ if (env_get("dfu_alt_info"))
+ return;
+
+ memset(buf, 0, sizeof(buf));
+
+ multiboot = multi_boot();
+ debug("Multiboot: %d\n", multiboot);
+
+ switch (zynqmp_get_bootmode()) {
+ case EMMC_MODE:
+ case SD_MODE:
+ case SD1_LSHFT_MODE:
+ case SD_MODE1:
+ bootseq = mmc_get_env_dev();
+ if (!multiboot)
+ snprintf(buf, DFU_ALT_BUF_LEN,
+ "mmc %d:1=boot.bin fat %d 1;"
+ "u-boot.itb fat %d 1",
+ bootseq, bootseq, bootseq);
+ else
+ snprintf(buf, DFU_ALT_BUF_LEN,
+ "mmc %d:1=boot%04d.bin fat %d 1;"
+ "u-boot.itb fat %d 1",
+ bootseq, multiboot, bootseq, bootseq);
+ break;
+ case QSPI_MODE_24BIT:
+ case QSPI_MODE_32BIT:
+ snprintf(buf, DFU_ALT_BUF_LEN,
+ "sf 0:0=boot.bin raw %x 0x1500000;"
+ "u-boot.itb raw 0x%x 0x500000",
+ multiboot * SZ_32K, CONFIG_SYS_SPI_U_BOOT_OFFS);
+ break;
+ default:
+ return;
+ }
+
+ env_set("dfu_alt_info", buf);
+ puts("DFU alt info setting: done\n");
+}
+#endif