diff options
author | Tom Rini <trini@konsulko.com> | 2020-09-24 08:33:47 -0400 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2020-09-24 08:33:47 -0400 |
commit | 67ece26d8b5d4bfa4fda8c456261c465d0815d7d (patch) | |
tree | 58d6f1e224c68b9b7b710f63087cb4468394aba7 /board/xilinx/zynqmp | |
parent | e119de72e3ae3accf831b5541d83d5c2faf031ff (diff) | |
parent | 4ab3817ff16a154981f9394a2c4a0f8f6a72713b (diff) | |
download | u-boot-67ece26d8b5d4bfa4fda8c456261c465d0815d7d.tar.gz u-boot-67ece26d8b5d4bfa4fda8c456261c465d0815d7d.tar.xz u-boot-67ece26d8b5d4bfa4fda8c456261c465d0815d7d.zip |
Merge tag 'xilinx-for-v2021.01' of https://gitlab.denx.de/u-boot/custodians/u-boot-microblaze into next
Xilinx changes for v2021.01
arm64:
- Support for bigger U-Boot images compiled with PIE
microblaze:
- Extend support for LE/BE systems
zynqmp:
- Refactor silicon ID detection code with using firmware interface
- Add support for saving variables based on bootmode
zynqmp-r5:
- Fix MPU mapping and defconfig setting.
xilinx:
- Minor driver changes: names alignment
- Enable UBIFS
- Minor DT and macros fixes
- Fix boot with appended DT
- Fix distro boot
cmd:
- pxe: Add fixing for platforms with manual relocation support
clk:
- fixed_rate: Add DM flag to support early boot on r5
fpga:
- zynqmppl: Use only firmware interface and enable SPL build
serial:
- uartlite: Enable for ARM systems and support endians
mmc:
- zynq: Fix indentation
net:
- gem: Support for multiple phys
- emac: Fix 64bit support and enable it for arm64
kconfig:
- Setup default values for Xilinx platforms
- Fix dependecies for Xilinx drivers
- Source board Kconfig only when platform is enabled
- Fix FPGA Kconfig entry with SPL
- Change some defconfig values
bindings:
- Add binding doc for vsc8531
Diffstat (limited to 'board/xilinx/zynqmp')
-rw-r--r-- | board/xilinx/zynqmp/zynqmp.c | 386 |
1 files changed, 202 insertions, 184 deletions
diff --git a/board/xilinx/zynqmp/zynqmp.c b/board/xilinx/zynqmp/zynqmp.c index bcfd56a912..28f067a251 100644 --- a/board/xilinx/zynqmp/zynqmp.c +++ b/board/xilinx/zynqmp/zynqmp.c @@ -9,6 +9,7 @@ #include <cpu_func.h> #include <debug_uart.h> #include <env.h> +#include <env_internal.h> #include <init.h> #include <log.h> #include <net.h> @@ -38,181 +39,156 @@ #include "pm_cfg_obj.h" +#define ZYNQMP_VERSION_SIZE 7 +#define EFUSE_VCU_DIS_MASK 0x100 +#define EFUSE_VCU_DIS_SHIFT 8 +#define EFUSE_GPU_DIS_MASK 0x20 +#define EFUSE_GPU_DIS_SHIFT 5 +#define IDCODE2_PL_INIT_MASK 0x200 +#define IDCODE2_PL_INIT_SHIFT 9 + DECLARE_GLOBAL_DATA_PTR; -#if defined(CONFIG_FPGA) && defined(CONFIG_FPGA_ZYNQMPPL) && \ - !defined(CONFIG_SPL_BUILD) +#if CONFIG_IS_ENABLED(FPGA) && defined(CONFIG_FPGA_ZYNQMPPL) static xilinx_desc zynqmppl = XILINX_ZYNQMP_DESC; +enum { + ZYNQMP_VARIANT_EG = BIT(0U), + ZYNQMP_VARIANT_EV = BIT(1U), + ZYNQMP_VARIANT_CG = BIT(2U), + ZYNQMP_VARIANT_DR = BIT(3U), +}; + static const struct { u32 id; - u32 ver; - char *name; - bool evexists; + u8 device; + u8 variants; } zynqmp_devices[] = { { - .id = 0x10, - .name = "3eg", - }, - { - .id = 0x10, - .ver = 0x2c, - .name = "3cg", - }, - { - .id = 0x11, - .name = "2eg", - }, - { - .id = 0x11, - .ver = 0x2c, - .name = "2cg", + .id = 0x04711093, + .device = 2, + .variants = ZYNQMP_VARIANT_EG | ZYNQMP_VARIANT_CG, }, { - .id = 0x20, - .name = "5ev", - .evexists = 1, + .id = 0x04710093, + .device = 3, + .variants = ZYNQMP_VARIANT_EG | ZYNQMP_VARIANT_CG, }, { - .id = 0x20, - .ver = 0x100, - .name = "5eg", - .evexists = 1, + .id = 0x04721093, + .device = 4, + .variants = ZYNQMP_VARIANT_EG | ZYNQMP_VARIANT_CG | + ZYNQMP_VARIANT_EV, }, { - .id = 0x20, - .ver = 0x12c, - .name = "5cg", - .evexists = 1, + .id = 0x04720093, + .device = 5, + .variants = ZYNQMP_VARIANT_EG | ZYNQMP_VARIANT_CG | + ZYNQMP_VARIANT_EV, }, { - .id = 0x21, - .name = "4ev", - .evexists = 1, + .id = 0x04739093, + .device = 6, + .variants = ZYNQMP_VARIANT_EG | ZYNQMP_VARIANT_CG, }, { - .id = 0x21, - .ver = 0x100, - .name = "4eg", - .evexists = 1, + .id = 0x04730093, + .device = 7, + .variants = ZYNQMP_VARIANT_EG | ZYNQMP_VARIANT_CG | + ZYNQMP_VARIANT_EV, }, { - .id = 0x21, - .ver = 0x12c, - .name = "4cg", - .evexists = 1, + .id = 0x04738093, + .device = 9, + .variants = ZYNQMP_VARIANT_EG, }, { - .id = 0x30, - .name = "7ev", - .evexists = 1, + .id = 0x04740093, + .device = 11, + .variants = ZYNQMP_VARIANT_EG, }, { - .id = 0x30, - .ver = 0x100, - .name = "7eg", - .evexists = 1, + .id = 0x04750093, + .device = 15, + .variants = ZYNQMP_VARIANT_EG, }, { - .id = 0x30, - .ver = 0x12c, - .name = "7cg", - .evexists = 1, + .id = 0x04759093, + .device = 17, + .variants = ZYNQMP_VARIANT_EG, }, { - .id = 0x38, - .name = "9eg", + .id = 0x04758093, + .device = 19, + .variants = ZYNQMP_VARIANT_EG, }, { - .id = 0x38, - .ver = 0x2c, - .name = "9cg", + .id = 0x047E1093, + .device = 21, + .variants = ZYNQMP_VARIANT_DR, }, { - .id = 0x39, - .name = "6eg", + .id = 0x047E3093, + .device = 23, + .variants = ZYNQMP_VARIANT_DR, }, { - .id = 0x39, - .ver = 0x2c, - .name = "6cg", - }, - { - .id = 0x40, - .name = "11eg", - }, - { /* For testing purpose only */ - .id = 0x50, - .ver = 0x2c, - .name = "15cg", + .id = 0x047E5093, + .device = 25, + .variants = ZYNQMP_VARIANT_DR, }, { - .id = 0x50, - .name = "15eg", + .id = 0x047E4093, + .device = 27, + .variants = ZYNQMP_VARIANT_DR, }, { - .id = 0x58, - .name = "19eg", + .id = 0x047E0093, + .device = 28, + .variants = ZYNQMP_VARIANT_DR, }, { - .id = 0x59, - .name = "17eg", + .id = 0x047E2093, + .device = 29, + .variants = ZYNQMP_VARIANT_DR, }, { - .id = 0x61, - .name = "21dr", + .id = 0x047E6093, + .device = 39, + .variants = ZYNQMP_VARIANT_DR, }, { - .id = 0x63, - .name = "23dr", + .id = 0x047FD093, + .device = 43, + .variants = ZYNQMP_VARIANT_DR, }, { - .id = 0x65, - .name = "25dr", + .id = 0x047F8093, + .device = 46, + .variants = ZYNQMP_VARIANT_DR, }, { - .id = 0x64, - .name = "27dr", + .id = 0x047FF093, + .device = 47, + .variants = ZYNQMP_VARIANT_DR, }, { - .id = 0x60, - .name = "28dr", + .id = 0x047FB093, + .device = 48, + .variants = ZYNQMP_VARIANT_DR, }, { - .id = 0x62, - .name = "29dr", - }, - { - .id = 0x66, - .name = "39dr", - }, - { - .id = 0x7b, - .name = "48dr", - }, - { - .id = 0x7e, - .name = "49dr", + .id = 0x047FE093, + .device = 49, + .variants = ZYNQMP_VARIANT_DR, }, }; -#endif -#define ZYNQMP_VERSION_SIZE 9 -#define ZYNQMP_PL_STATUS_BIT 9 -#define ZYNQMP_IPDIS_VCU_BIT 8 -#define ZYNQMP_PL_STATUS_MASK BIT(ZYNQMP_PL_STATUS_BIT) -#define ZYNQMP_CSU_VERSION_MASK ~(ZYNQMP_PL_STATUS_MASK) -#define ZYNQMP_CSU_VCUDIS_VER_MASK ZYNQMP_CSU_VERSION_MASK & \ - ~BIT(ZYNQMP_IPDIS_VCU_BIT) -#define MAX_VARIANTS_EV 3 - -#if defined(CONFIG_FPGA) && defined(CONFIG_FPGA_ZYNQMPPL) && \ - !defined(CONFIG_SPL_BUILD) static char *zynqmp_get_silicon_idcode_name(void) { - u32 i, id, ver, j; - char *buf; - static char name[ZYNQMP_VERSION_SIZE]; + u32 i; + u32 idcode, idcode2; + char name[ZYNQMP_VERSION_SIZE]; u32 ret_payload[PAYLOAD_ARG_CNT]; xilinx_pm_request(PM_GET_CHIPID, 0, 0, 0, 0, ret_payload); @@ -226,61 +202,71 @@ static char *zynqmp_get_silicon_idcode_name(void) * 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); + idcode = ret_payload[1]; + idcode2 = ret_payload[2] >> ZYNQMP_CSU_VERSION_EMPTY_SHIFT; + debug("%s, IDCODE: 0x%0X, IDCODE2: 0x%0X\r\n", __func__, idcode, + idcode2); for (i = 0; i < ARRAY_SIZE(zynqmp_devices); i++) { - if (zynqmp_devices[i].id == id) { - if (zynqmp_devices[i].evexists && - !(ver & ZYNQMP_PL_STATUS_MASK)) - break; - if (zynqmp_devices[i].ver == (ver & - ZYNQMP_CSU_VERSION_MASK)) - break; - } + if (zynqmp_devices[i].id == (idcode & 0x0FFFFFFF)) + break; } if (i >= ARRAY_SIZE(zynqmp_devices)) return "unknown"; - strncat(name, "zu", 2); - if (!zynqmp_devices[i].evexists || - (ver & ZYNQMP_PL_STATUS_MASK)) { - strncat(name, zynqmp_devices[i].name, - ZYNQMP_VERSION_SIZE - 3); - return name; - } - - /* - * Here we are means, PL not powered up and ev variant - * exists. So, we need to ignore VCU disable bit(8) in - * version and findout if its CG or EG/EV variant. - */ - for (j = 0; j < MAX_VARIANTS_EV; j++, i++) { - if ((zynqmp_devices[i].ver & ~BIT(ZYNQMP_IPDIS_VCU_BIT)) == - (ver & ZYNQMP_CSU_VCUDIS_VER_MASK)) { - strncat(name, zynqmp_devices[i].name, - ZYNQMP_VERSION_SIZE - 3); - break; + /* Add device prefix to the name */ + strncpy(name, "zu", ZYNQMP_VERSION_SIZE); + strncat(&name[2], simple_itoa(zynqmp_devices[i].device), 2); + + if (zynqmp_devices[i].variants & ZYNQMP_VARIANT_EV) { + /* Devices with EV variant might be EG/CG/EV family */ + if (idcode2 & IDCODE2_PL_INIT_MASK) { + u32 family = ((idcode2 & EFUSE_VCU_DIS_MASK) >> + EFUSE_VCU_DIS_SHIFT) << 1 | + ((idcode2 & EFUSE_GPU_DIS_MASK) >> + EFUSE_GPU_DIS_SHIFT); + + /* + * Get family name based on extended idcode values as + * determined on UG1087, EXTENDED_IDCODE register + * description + */ + switch (family) { + case 0x00: + strncat(name, "ev", 2); + break; + case 0x10: + strncat(name, "eg", 2); + break; + case 0x11: + strncat(name, "cg", 2); + break; + default: + /* Do not append family name*/ + break; + } + } else { + /* + * When PL powered down the VCU Disable efuse cannot be + * read. So, ignore the bit and just findout if it is CG + * or EG/EV variant. + */ + strncat(name, (idcode2 & EFUSE_GPU_DIS_MASK) ? "cg" : + "e", 2); } + } else if (zynqmp_devices[i].variants & ZYNQMP_VARIANT_CG) { + /* Devices with CG variant might be EG or CG family */ + strncat(name, (idcode2 & EFUSE_GPU_DIS_MASK) ? "cg" : "eg", 2); + } else if (zynqmp_devices[i].variants & ZYNQMP_VARIANT_EG) { + strncat(name, "eg", 2); + } else if (zynqmp_devices[i].variants & ZYNQMP_VARIANT_DR) { + strncat(name, "dr", 2); + } else { + debug("Variant not identified\n"); } - if (j >= MAX_VARIANTS_EV) - return "unknown"; - - if (strstr(name, "eg") || strstr(name, "ev")) { - buf = strstr(name, "e"); - *buf = '\0'; - } - - return name; + return strdup(name); } #endif @@ -342,9 +328,7 @@ int board_init(void) /* Bug in ROM sets wrong value in this register */ writel(PS_SYSMON_ANALOG_BUS_VAL, PS_SYSMON_ANALOG_BUS_REG); -#if defined(CONFIG_FPGA) && defined(CONFIG_FPGA_ZYNQMPPL) && \ - !defined(CONFIG_SPL_BUILD) || (defined(CONFIG_SPL_FPGA_SUPPORT) && \ - defined(CONFIG_SPL_BUILD)) +#if CONFIG_IS_ENABLED(FPGA) && defined(CONFIG_FPGA_ZYNQMPPL) zynqmppl.name = zynqmp_get_silicon_idcode_name(); printf("Chip ID:\t%s\n", zynqmppl.name); fpga_init(); @@ -444,6 +428,24 @@ void reset_cpu(ulong addr) { } +static u8 __maybe_unused zynqmp_get_bootmode(void) +{ + u8 bootmode; + u32 reg = 0; + int ret; + + ret = zynqmp_mmio_read((ulong)&crlapb_base->boot_mode, ®); + if (ret) + return -EINVAL; + + if (reg >> BOOT_MODE_ALT_SHIFT) + reg >>= BOOT_MODE_ALT_SHIFT; + + bootmode = reg & BOOT_MODES_MASK; + + return bootmode; +} + #if defined(CONFIG_BOARD_LATE_INIT) static const struct { u32 bit; @@ -527,24 +529,6 @@ static int set_fdtfile(void) return 0; } -static u8 zynqmp_get_bootmode(void) -{ - u8 bootmode; - u32 reg = 0; - int ret; - - ret = zynqmp_mmio_read((ulong)&crlapb_base->boot_mode, ®); - if (ret) - return -EINVAL; - - if (reg >> BOOT_MODE_ALT_SHIFT) - reg >>= BOOT_MODE_ALT_SHIFT; - - bootmode = reg & BOOT_MODES_MASK; - - return bootmode; -} - int board_late_init(void) { u8 bootmode; @@ -689,3 +673,37 @@ int checkboard(void) puts("Board: Xilinx ZynqMP\n"); return 0; } + +enum env_location env_get_location(enum env_operation op, int prio) +{ + u32 bootmode = zynqmp_get_bootmode(); + + if (prio) + return ENVL_UNKNOWN; + + switch (bootmode) { + case EMMC_MODE: + case SD_MODE: + case SD1_LSHFT_MODE: + case SD_MODE1: + if (IS_ENABLED(CONFIG_ENV_IS_IN_FAT)) + return ENVL_FAT; + if (IS_ENABLED(CONFIG_ENV_IS_IN_EXT4)) + return ENVL_EXT4; + return ENVL_UNKNOWN; + case NAND_MODE: + if (IS_ENABLED(CONFIG_ENV_IS_IN_NAND)) + return ENVL_NAND; + if (IS_ENABLED(CONFIG_ENV_IS_IN_UBI)) + return ENVL_UBI; + return ENVL_UNKNOWN; + case QSPI_MODE_24BIT: + case QSPI_MODE_32BIT: + if (IS_ENABLED(CONFIG_ENV_IS_IN_SPI_FLASH)) + return ENVL_SPI_FLASH; + return ENVL_UNKNOWN; + case JTAG_MODE: + default: + return ENVL_NOWHERE; + } +} |