diff options
author | Tom Rini <trini@konsulko.com> | 2021-08-27 08:33:02 -0400 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2021-08-27 08:33:02 -0400 |
commit | b9cb74a5aa256fc34a1b2b9dd847a985b91f34f6 (patch) | |
tree | a618344b253ec3164848e797a2636bbd8f060223 /board | |
parent | 7bfa565453ec5f63668a3464da21629055c3053f (diff) | |
parent | 229cb5c6ba3469cbc4a0bcc69389fe61c51fd3b4 (diff) | |
download | u-boot-b9cb74a5aa256fc34a1b2b9dd847a985b91f34f6.zip u-boot-b9cb74a5aa256fc34a1b2b9dd847a985b91f34f6.tar.gz u-boot-b9cb74a5aa256fc34a1b2b9dd847a985b91f34f6.tar.bz2 |
Merge tag 'xilinx-for-v2021.10-rc3' of https://gitlab.denx.de/u-boot/custodians/u-boot-microblazeWIP/27Aug2021
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.c | 184 | ||||
-rw-r--r-- | board/xilinx/zynqmp/Makefile | 2 | ||||
-rw-r--r-- | board/xilinx/zynqmp/tap_delays.c | 101 | ||||
-rw-r--r-- | board/xilinx/zynqmp/zynqmp.c | 74 |
4 files changed, 223 insertions, 138 deletions
diff --git a/board/xilinx/common/board.c b/board/xilinx/common/board.c index 92b61d8..9006bd3 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 7d8277c..a914028 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 d16bbb8..0000000 --- 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 38c910f..ea15e62 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 |