diff options
author | Tom Rini <trini@konsulko.com> | 2022-02-21 08:32:02 -0500 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2022-02-21 08:32:02 -0500 |
commit | 24b628a8f844868adca897aae40af6f98cdbc26d (patch) | |
tree | 43572009123231107d618dce3a4f84d7e2c536d6 | |
parent | 55e9cef1432ffd42559874b2a469729f20b627d9 (diff) | |
parent | 9bd4232f958b94fdd700e44897fb61bdc898b787 (diff) | |
download | u-boot-24b628a8f844868adca897aae40af6f98cdbc26d.zip u-boot-24b628a8f844868adca897aae40af6f98cdbc26d.tar.gz u-boot-24b628a8f844868adca897aae40af6f98cdbc26d.tar.bz2 |
Merge tag 'xilinx-for-v2022.04-rc3' of https://gitlab.denx.de/u-boot/custodians/u-boot-microblaze
Xilinx changes for v2022.04-rc3
microblaze:
- Fix exception handler
zynqmp:
- Show information about secure images
- DT changes (som u-boot file removal)
- Fix zynqmp_pm_cfg_obj_convert.py
- Fix platform boot
xilinx:
- Fix bootm_size calculation
- Remove GPIO_EXTRA_HEADER selection
power:
- Add zynqmp power management driver
scsi:
- Add phy support to ceva driver
zynq qspi:
- Fix unaligned accesses and check baudrate setup
- Add support for spi memory operations
net:
- Fix 64bit calculation in axi_emac
video:
- Add missing gpio dependency for seps driver
34 files changed, 493 insertions, 128 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index 1c98029..fb171e0 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -647,6 +647,7 @@ F: drivers/mtd/nand/raw/zynq_nand.c F: drivers/net/phy/xilinx_phy.c F: drivers/net/zynq_gem.c F: drivers/phy/phy-zynqmp.c +F: drivers/power/domain/zynqmp-power-domain.c F: drivers/serial/serial_zynq.c F: drivers/reset/reset-zynqmp.c F: drivers/rtc/zynqmp_rtc.c diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 8053394..391a77c 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1139,7 +1139,6 @@ config ARCH_VERSAL select DM_MMC if MMC select DM_SERIAL select GICV3 - select GPIO_EXTRA_HEADER select OF_CONTROL select SOC_DEVICE imply BOARD_LATE_INIT @@ -1159,13 +1158,13 @@ config ARCH_ZYNQ select CLK select CLK_ZYNQ select CPU_V7A + select DEBUG_UART_BOARD_INIT if SPL && DEBUG_UART select DM select DM_ETH if NET select DM_MMC if MMC select DM_SERIAL select DM_SPI select DM_SPI_FLASH - select GPIO_EXTRA_HEADER select OF_CONTROL select SPI select SPL_BOARD_INIT if SPL @@ -1192,7 +1191,6 @@ config ARCH_ZYNQMP_R5 select DM_ETH if NET select DM_MMC if MMC select DM_SERIAL - select GPIO_EXTRA_HEADER select OF_CONTROL imply CMD_DM imply DM_USB_GADGET @@ -1202,6 +1200,7 @@ config ARCH_ZYNQMP select ARM64 select CLK select DM + select DEBUG_UART_BOARD_INIT if SPL && DEBUG_UART select DM_ETH if NET select DM_MAILBOX select DM_MMC if MMC @@ -1210,7 +1209,6 @@ config ARCH_ZYNQMP select DM_SPI_FLASH if DM_SPI imply FIRMWARE select GICV2 - select GPIO_EXTRA_HEADER select OF_CONTROL select SPL_BOARD_INIT if SPL select SPL_CLK if SPL diff --git a/arch/arm/dts/zynqmp-dlc21-revA.dts b/arch/arm/dts/zynqmp-dlc21-revA.dts index cf0aadf..0461219 100644 --- a/arch/arm/dts/zynqmp-dlc21-revA.dts +++ b/arch/arm/dts/zynqmp-dlc21-revA.dts @@ -12,7 +12,6 @@ #include "zynqmp-clk-ccf.dtsi" #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/phy/phy.h> -#include <include/dt-bindings/gpio/gpio.h> / { model = "Smartlynq+ DLC21 RevA"; diff --git a/arch/arm/dts/zynqmp-sm-k26-revA-u-boot.dtsi b/arch/arm/dts/zynqmp-sm-k26-revA-u-boot.dtsi deleted file mode 100644 index 467df9f..0000000 --- a/arch/arm/dts/zynqmp-sm-k26-revA-u-boot.dtsi +++ /dev/null @@ -1,21 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * dts file for Xilinx ZynqMP K26/KV260 SD wiring - * - * (C) Copyright 2020 - 2021, Xilinx, Inc. - * - * Michal Simek <michal.simek@xilinx.com> - */ - -/* SD0 only supports 3.3V, no level shifter */ -&sdhci1 { /* on CC - MIO 39 - 51 */ - status = "okay"; - no-1-8-v; - disable-wp; - broken-cd; - xlnx,mio-bank = <1>; - /* Do not run SD in HS mode from bootloader */ - sdhci-caps-mask = <0 0x200000>; - sdhci-caps = <0 0>; - max-frequency = <19000000>; -}; diff --git a/arch/arm/dts/zynqmp-smk-k26-revA-u-boot.dtsi b/arch/arm/dts/zynqmp-smk-k26-revA-u-boot.dtsi deleted file mode 100644 index 34e6328..0000000 --- a/arch/arm/dts/zynqmp-smk-k26-revA-u-boot.dtsi +++ /dev/null @@ -1,21 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * dts file for Xilinx ZynqMP Z2-VSOM - * - * (C) Copyright 2020 - 2021, Xilinx, Inc. - * - * Michal Simek <michal.simek@xilinx.com> - */ - -/* SD0 only supports 3.3V, no level shifter */ -&sdhci1 { /* FIXME - on CC - MIO 39 - 51 */ - status = "okay"; - no-1-8-v; - disable-wp; - broken-cd; - xlnx,mio-bank = <1>; - /* Do not run SD in HS mode from bootloader */ - sdhci-caps-mask = <0 0x200000>; - sdhci-caps = <0 0>; - max-frequency = <19000000>; -}; diff --git a/arch/arm/mach-versal/include/mach/gpio.h b/arch/arm/mach-versal/include/mach/gpio.h deleted file mode 100644 index 677facb..0000000 --- a/arch/arm/mach-versal/include/mach/gpio.h +++ /dev/null @@ -1,6 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Copyright 2016 - 2018 Xilinx, Inc. - */ - -/* Empty file - for compilation */ diff --git a/arch/arm/mach-zynq/include/mach/gpio.h b/arch/arm/mach-zynq/include/mach/gpio.h deleted file mode 100644 index 6143e24..0000000 --- a/arch/arm/mach-zynq/include/mach/gpio.h +++ /dev/null @@ -1,10 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Copyright (c) 2013 Xilinx, Inc. - * Copyright (c) 2015 DAVE Embedded Systems - */ - -#ifndef _ZYNQ_GPIO_H -#define _ZYNQ_GPIO_H - -#endif /* _ZYNQ_GPIO_H */ diff --git a/arch/arm/mach-zynq/spl.c b/arch/arm/mach-zynq/spl.c index b1a5184..fea1c9b 100644 --- a/arch/arm/mach-zynq/spl.c +++ b/arch/arm/mach-zynq/spl.c @@ -16,17 +16,20 @@ #include <asm/arch/sys_proto.h> #include <asm/arch/ps7_init_gpl.h> +#if defined(CONFIG_DEBUG_UART_BOARD_INIT) +void board_debug_uart_init(void) +{ + ps7_init(); +} +#endif + void board_init_f(ulong dummy) { +#if !defined(CONFIG_DEBUG_UART_BOARD_INIT) ps7_init(); +#endif arch_cpu_init(); - -#ifdef CONFIG_DEBUG_UART - /* Uart debug for sure */ - debug_uart_init(); - puts("Debug uart enabled\n"); /* or printch() */ -#endif } #ifdef CONFIG_SPL_BOARD_INIT diff --git a/arch/arm/mach-zynqmp/Kconfig b/arch/arm/mach-zynqmp/Kconfig index f8b5906..6604506 100644 --- a/arch/arm/mach-zynqmp/Kconfig +++ b/arch/arm/mach-zynqmp/Kconfig @@ -140,6 +140,7 @@ config DEFINE_TCM_OCM_MMAP config ZYNQMP_PSU_INIT_ENABLED bool "Include psu_init" + select BOARD_EARLY_INIT_F help Include psu_init to full u-boot. SPL include psu_init by default. diff --git a/arch/arm/mach-zynqmp/Makefile b/arch/arm/mach-zynqmp/Makefile index eb6c511..4f9f6b5 100644 --- a/arch/arm/mach-zynqmp/Makefile +++ b/arch/arm/mach-zynqmp/Makefile @@ -6,6 +6,6 @@ obj-y += clk.o obj-y += cpu.o obj-$(CONFIG_MP) += mp.o -obj-$(CONFIG_SPL_BUILD) += spl.o handoff.o +obj-$(CONFIG_SPL_BUILD) += spl.o handoff.o psu_spl_init.o obj-$(CONFIG_SPL_ZYNQMP_DRAM_ECC_INIT) += ecc_spl_init.o obj-$(CONFIG_ZYNQMP_PSU_INIT_ENABLED) += psu_spl_init.o diff --git a/arch/arm/mach-zynqmp/include/mach/gpio.h b/arch/arm/mach-zynqmp/include/mach/gpio.h deleted file mode 100644 index 542a5fc..0000000 --- a/arch/arm/mach-zynqmp/include/mach/gpio.h +++ /dev/null @@ -1,11 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Copyright 2015 Xilinx, Inc. - */ - -#ifndef __ARCH_ZYNQMP_GPIO_H -#define __ARCH_ZYNQMP_GPIO_H - -/* Empty file - sdhci requires this. */ - -#endif diff --git a/arch/arm/mach-zynqmp/include/mach/hardware.h b/arch/arm/mach-zynqmp/include/mach/hardware.h index e6a3ee4..a70d6d6 100644 --- a/arch/arm/mach-zynqmp/include/mach/hardware.h +++ b/arch/arm/mach-zynqmp/include/mach/hardware.h @@ -152,8 +152,12 @@ struct apu_regs { #define CSU_JTAG_CHAIN_WR_SETUP GENMASK(1, 0) #define CSU_PCAP_PROG_RELEASE_PL BIT(0) +#define ZYNQMP_CSU_STATUS_AUTHENTICATED BIT(0) +#define ZYNQMP_CSU_STATUS_ENCRYPTED BIT(1) + struct csu_regs { - u32 reserved0[4]; + u32 status; + u32 reserved0[3]; u32 multi_boot; u32 reserved1[7]; u32 jtag_chain_status_wr; diff --git a/arch/arm/mach-zynqmp/include/mach/psu_init_gpl.h b/arch/arm/mach-zynqmp/include/mach/psu_init_gpl.h index e37acda..434a7fa 100644 --- a/arch/arm/mach-zynqmp/include/mach/psu_init_gpl.h +++ b/arch/arm/mach-zynqmp/include/mach/psu_init_gpl.h @@ -22,5 +22,6 @@ void prog_reg(unsigned long addr, unsigned long mask, int psu_init(void); unsigned long psu_post_config_data(void); +int psu_uboot_init(void); #endif /* _PSU_INIT_GPL_H_ */ diff --git a/arch/arm/mach-zynqmp/spl.c b/arch/arm/mach-zynqmp/spl.c index 6b836cb..b428fd5 100644 --- a/arch/arm/mach-zynqmp/spl.c +++ b/arch/arm/mach-zynqmp/spl.c @@ -19,9 +19,19 @@ #include <asm/arch/psu_init_gpl.h> #include <asm/arch/sys_proto.h> +#if defined(CONFIG_DEBUG_UART_BOARD_INIT) +void board_debug_uart_init(void) +{ + psu_uboot_init(); +} +#endif + void board_init_f(ulong dummy) { - board_early_init_f(); +#if !defined(CONFIG_DEBUG_UART_BOARD_INIT) + psu_uboot_init(); +#endif + board_early_init_r(); #ifdef CONFIG_SPL_ZYNQMP_DRAM_ECC_INIT zynqmp_ecc_init(); diff --git a/arch/microblaze/cpu/exception.c b/arch/microblaze/cpu/exception.c index e9476ab..d3640d3 100644 --- a/arch/microblaze/cpu/exception.c +++ b/arch/microblaze/cpu/exception.c @@ -20,10 +20,25 @@ void _hw_exception_handler (void) MFS(state, resr); printf("Hardware exception at 0x%x address\n", address); R17(address); - printf("Return address from exception 0x%x\n", address); + + if (CONFIG_IS_ENABLED(XILINX_MICROBLAZE0_DELAY_SLOT_EXCEP) && + (state & 0x1000)) { + /* + * For exceptions in delay slots, the return address is stored + * in the Branch Target Register (BTR), rather than R17. + */ + MFS(address, rbtr); + + puts("Exception in delay slot\n"); + } + switch (state & 0x1f) { /* mask on exception cause */ case 0x1: puts("Unaligned data access exception\n"); + + printf("Unaligned %sword access\n", ((state & 0x800) ? "" : "half")); + printf("Unaligned %s access\n", ((state & 0x400) ? "store" : "load")); + printf("Register R%x\n", (state & 0x3E0) >> 5); break; case 0x2: puts("Illegal op-code exception\n"); @@ -37,21 +52,15 @@ void _hw_exception_handler (void) case 0x5: puts("Divide by zero exception\n"); break; -#ifdef MICROBLAZE_V5 case 0x7: puts("Priviledged or stack protection violation exception\n"); break; - case 0x1000: - puts("Exception in delay slot\n"); - break; -#endif default: puts("Undefined cause\n"); break; } - printf("Unaligned %sword access\n", ((state & 0x800) ? "" : "half")); - printf("Unaligned %s access\n", ((state & 0x400) ? "store" : "load")); - printf("Register R%x\n", (state & 0x3E) >> 5); + + printf("Return address from exception 0x%x\n", address); hang(); } diff --git a/board/xilinx/common/board.c b/board/xilinx/common/board.c index 78a5d0e..0068cb8 100644 --- a/board/xilinx/common/board.c +++ b/board/xilinx/common/board.c @@ -319,7 +319,7 @@ __maybe_unused int xilinx_read_eeprom(void) return 0; } -#if defined(CONFIG_OF_BOARD) || defined(CONFIG_OF_SEPARATE) +#if defined(CONFIG_OF_BOARD) void *board_fdt_blob_setup(int *err) { void *fdt_blob; @@ -355,6 +355,7 @@ void *board_fdt_blob_setup(int *err) debug("DTB is also not passed via %p\n", fdt_blob); + *err = -EINVAL; return NULL; } #endif @@ -377,7 +378,7 @@ int board_late_init_xilinx(void) u32 ret = 0; int i, id, macid = 0; struct xilinx_board_description *desc; - phys_size_t bootm_size = gd->ram_size; + phys_size_t bootm_size = gd->ram_top - gd->ram_base; if (!CONFIG_IS_ENABLED(MICROBLAZE)) { ulong scriptaddr; diff --git a/board/xilinx/microblaze-generic/Kconfig b/board/xilinx/microblaze-generic/Kconfig index e31257d..117b476 100644 --- a/board/xilinx/microblaze-generic/Kconfig +++ b/board/xilinx/microblaze-generic/Kconfig @@ -47,6 +47,15 @@ config XILINX_MICROBLAZE0_USR_EXCEP the exception vector table. The user exception vector is located at C_BASE_VECTORS + 0x8 address. +config XILINX_MICROBLAZE0_DELAY_SLOT_EXCEP + bool "MicroBlaze delay slot exception support" + default y + help + Enable this option if the MicroBlaze processor supports exceptions + caused by delay slot instructions (processor version >= v5.00). When + enabled, the hw exception handler will print a message indicating + whether the exception was triggered by a delay slot instruction. + config XILINX_MICROBLAZE0_VECTOR_BASE_ADDR hex "Location of MicroBlaze vectors" default 0x0 diff --git a/board/xilinx/zynq/board.c b/board/xilinx/zynq/board.c index 1111ad6..26ef048 100644 --- a/board/xilinx/zynq/board.c +++ b/board/xilinx/zynq/board.c @@ -25,6 +25,13 @@ DECLARE_GLOBAL_DATA_PTR; +#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_DEBUG_UART_BOARD_INIT) +void board_debug_uart_init(void) +{ + /* Add initialization sequence if UART is not configured */ +} +#endif + int board_init(void) { if (IS_ENABLED(CONFIG_SPL_BUILD)) diff --git a/board/xilinx/zynqmp/cmds.c b/board/xilinx/zynqmp/cmds.c index 5a277c7..2ab9596 100644 --- a/board/xilinx/zynqmp/cmds.c +++ b/board/xilinx/zynqmp/cmds.c @@ -209,6 +209,19 @@ static int do_zynqmp_pmufw(struct cmd_tbl *cmdtp, int flag, int argc, if (argc != cmdtp->maxargs) return CMD_RET_USAGE; + if (!strncmp(argv[2], "node", 4)) { + u32 id; + + if (!strncmp(argv[3], "close", 5)) + return zynqmp_pmufw_config_close(); + + id = dectoul(argv[3], NULL); + + printf("Enable permission for node ID %d\n", id); + + return zynqmp_pmufw_node(id); + } + addr = hextoul(argv[2], NULL); size = hextoul(argv[3], NULL); @@ -416,6 +429,9 @@ static char zynqmp_help_text[] = " lock(0)/split(1)\n" #endif "zynqmp pmufw address size - load PMU FW configuration object\n" + "zynqmp pmufw node <id> - load PMU FW configuration object\n" + "zynqmp pmufw node close - disable config object loading\n" + " node: keyword, id: NODE_ID in decimal format\n" "zynqmp rsa srcaddr srclen mod exp rsaop -\n" " Performs RSA encryption and RSA decryption on blob of data\n" " at srcaddr and puts it back in srcaddr using modulus and\n" diff --git a/board/xilinx/zynqmp/zynqmp.c b/board/xilinx/zynqmp/zynqmp.c index 2b5239c..70b3c81 100644 --- a/board/xilinx/zynqmp/zynqmp.c +++ b/board/xilinx/zynqmp/zynqmp.c @@ -313,9 +313,8 @@ static char *zynqmp_get_silicon_idcode_name(void) } #endif -int board_early_init_f(void) +int __maybe_unused psu_uboot_init(void) { -#if defined(CONFIG_ZYNQMP_PSU_INIT_ENABLED) int ret; ret = psu_init(); @@ -335,16 +334,31 @@ int board_early_init_f(void) /* Delay is required for clocks to be propagated */ udelay(1000000); -#endif + + return 0; +} -#ifdef CONFIG_DEBUG_UART - /* Uart debug for sure */ - debug_uart_init(); - puts("Debug uart enabled\n"); /* or printch() */ -#endif +#if !defined(CONFIG_SPL_BUILD) +# if defined(CONFIG_DEBUG_UART_BOARD_INIT) +void board_debug_uart_init(void) +{ +# if defined(CONFIG_ZYNQMP_PSU_INIT_ENABLED) + psu_uboot_init(); +# endif +} +# endif - return 0; +# if defined(CONFIG_BOARD_EARLY_INIT_F) +int board_early_init_f(void) +{ + int ret = 0; +# if defined(CONFIG_ZYNQMP_PSU_INIT_ENABLED) && !defined(CONFIG_DEBUG_UART_BOARD_INIT) + ret = psu_uboot_init(); +# endif + return ret; } +# endif +#endif static int multi_boot(void) { @@ -373,6 +387,18 @@ static void restore_jtag(void) } #endif +static void print_secure_boot(void) +{ + u32 status = 0; + + if (zynqmp_mmio_read((ulong)&csu_base->status, &status)) + return; + + printf("Secure Boot:\t%sauthenticated, %sencrypted\n", + status & ZYNQMP_CSU_STATUS_AUTHENTICATED ? "" : "not ", + status & ZYNQMP_CSU_STATUS_ENCRYPTED ? "" : "not "); +} + #define PS_SYSMON_ANALOG_BUS_VAL 0x3210 #define PS_SYSMON_ANALOG_BUS_REG 0xFFA50914 @@ -413,6 +439,8 @@ int board_init(void) fpga_add(fpga_xilinx, &zynqmppl); #endif + /* display secure boot information */ + print_secure_boot(); if (current_el() == 3) printf("Multiboot:\t%d\n", multi_boot()); diff --git a/configs/xilinx_zynq_virt_defconfig b/configs/xilinx_zynq_virt_defconfig index 6aa4ec4..9122b24 100644 --- a/configs/xilinx_zynq_virt_defconfig +++ b/configs/xilinx_zynq_virt_defconfig @@ -60,6 +60,7 @@ CONFIG_CMD_MTDPARTS=y CONFIG_CMD_MTDPARTS_SPREAD=y CONFIG_CMD_MTDPARTS_SHOW_NET_SIZES=y CONFIG_CMD_UBI=y +CONFIG_OF_BOARD=y CONFIG_OF_LIST="zynq-zc702 zynq-zc706 zynq-zc770-xm010 zynq-zc770-xm011 zynq-zc770-xm011-x16 zynq-zc770-xm012 zynq-zc770-xm013 zynq-cc108 zynq-microzed zynq-minized zynq-picozed zynq-zed zynq-zturn zynq-zturn-v5 zynq-zybo zynq-zybo-z7 zynq-dlc20-rev1.0" CONFIG_ENV_IS_NOWHERE=y CONFIG_ENV_IS_IN_FAT=y diff --git a/configs/xilinx_zynqmp_virt_defconfig b/configs/xilinx_zynqmp_virt_defconfig index 6ea1575..976cb02 100644 --- a/configs/xilinx_zynqmp_virt_defconfig +++ b/configs/xilinx_zynqmp_virt_defconfig @@ -18,7 +18,6 @@ CONFIG_ZYNQ_MAC_IN_EEPROM=y CONFIG_ZYNQ_GEM_I2C_MAC_OFFSET=0x20 CONFIG_CMD_FRU=y CONFIG_ZYNQMP_USB=y -CONFIG_ZYNQMP_PSU_INIT_ENABLED=y CONFIG_AHCI=y CONFIG_DISTRO_DEFAULTS=y CONFIG_REMAKE_ELF=y @@ -30,7 +29,6 @@ CONFIG_SPL_LOAD_FIT_ADDRESS=0x10000000 # CONFIG_ARCH_FIXUP_FDT_MEMORY is not set CONFIG_USE_PREBOOT=y CONFIG_PREBOOT="run scsi_init;usb start" -CONFIG_BOARD_EARLY_INIT_F=y CONFIG_BOARD_EARLY_INIT_R=y CONFIG_SPL_STACK_R=y CONFIG_SPL_FPGA=y @@ -83,6 +81,7 @@ CONFIG_CMD_MTDPARTS_SHOW_NET_SIZES=y CONFIG_CMD_UBI=y CONFIG_PARTITION_TYPE_GUID=y CONFIG_SPL_OF_CONTROL=y +CONFIG_OF_BOARD=y CONFIG_OF_LIST="avnet-ultra96-rev1 zynqmp-a2197-revA zynqmp-e-a2197-00-revA zynqmp-g-a2197-00-revA zynqmp-m-a2197-01-revA zynqmp-m-a2197-02-revA zynqmp-m-a2197-03-revA zynqmp-p-a2197-00-revA zynqmp-zc1232-revA zynqmp-zc1254-revA zynqmp-zc1751-xm015-dc1 zynqmp-zc1751-xm016-dc2 zynqmp-zc1751-xm017-dc3 zynqmp-zc1751-xm018-dc4 zynqmp-zc1751-xm019-dc5 zynqmp-zcu100-revC zynqmp-zcu102-rev1.1 zynqmp-zcu102-rev1.0 zynqmp-zcu102-revA zynqmp-zcu102-revB zynqmp-zcu104-revA zynqmp-zcu104-revC zynqmp-zcu106-revA zynqmp-zcu111-revA zynqmp-zcu1275-revA zynqmp-zcu1275-revB zynqmp-zcu1285-revA zynqmp-zcu208-revA zynqmp-zcu216-revA zynqmp-topic-miamimp-xilinx-xdp-v1r1 zynqmp-sm-k26-revA zynqmp-smk-k26-revA zynqmp-dlc21-revA" CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names interrupt-parent interrupts iommus power-domains" CONFIG_ENV_IS_NOWHERE=y diff --git a/drivers/ata/sata_ceva.c b/drivers/ata/sata_ceva.c index b71f102..43bcc59 100644 --- a/drivers/ata/sata_ceva.c +++ b/drivers/ata/sata_ceva.c @@ -6,9 +6,12 @@ #include <common.h> #include <dm.h> #include <ahci.h> +#include <generic-phy.h> #include <log.h> +#include <reset.h> #include <scsi.h> #include <asm/io.h> +#include <dm/device_compat.h> #include <linux/ioport.h> /* Vendor Specific Register Offsets */ @@ -181,6 +184,47 @@ static int sata_ceva_bind(struct udevice *dev) static int sata_ceva_probe(struct udevice *dev) { struct ceva_sata_priv *priv = dev_get_priv(dev); + struct phy phy; + int ret; + struct reset_ctl_bulk resets; + + ret = generic_phy_get_by_index(dev, 0, &phy); + if (!ret) { + dev_dbg(dev, "Perform PHY initialization\n"); + ret = generic_phy_init(&phy); + if (ret) + return ret; + } else if (ret != -ENOENT) { + dev_dbg(dev, "could not get phy (err %d)\n", ret); + return ret; + } + + /* reset is optional */ + ret = reset_get_bulk(dev, &resets); + if (ret && ret != -ENOTSUPP && ret != -ENOENT) { + dev_dbg(dev, "Getting reset fails (err %d)\n", ret); + return ret; + } + + /* Just trigger reset when reset is specified */ + if (!ret) { + dev_dbg(dev, "Perform IP reset\n"); + ret = reset_deassert_bulk(&resets); + if (ret) { + dev_dbg(dev, "Reset fails (err %d)\n", ret); + reset_release_bulk(&resets); + return ret; + } + } + + if (phy.dev) { + dev_dbg(dev, "Perform PHY power on\n"); + ret = generic_phy_power_on(&phy); + if (ret) { + dev_dbg(dev, "PHY power on failed (err %d)\n", ret); + return ret; + } + } ceva_init_sata(priv); diff --git a/drivers/firmware/firmware-zynqmp.c b/drivers/firmware/firmware-zynqmp.c index 839203e..8d8492d 100644 --- a/drivers/firmware/firmware-zynqmp.c +++ b/drivers/firmware/firmware-zynqmp.c @@ -8,6 +8,7 @@ #include <common.h> #include <cpu_func.h> #include <dm.h> +#include <dm/lists.h> #include <log.h> #include <zynqmp_firmware.h> #include <asm/cache.h> @@ -27,6 +28,57 @@ struct zynqmp_power { struct mbox_chan rx_chan; } zynqmp_power; +#define NODE_ID_LOCATION 5 + +static unsigned int xpm_configobject[] = { + /**********************************************************************/ + /* HEADER */ + 2, /* Number of remaining words in the header */ + 1, /* Number of sections included in config object */ + PM_CONFIG_OBJECT_TYPE_OVERLAY, /* Type of Config object as overlay */ + /**********************************************************************/ + /* SLAVE SECTION */ + + PM_CONFIG_SLAVE_SECTION_ID, /* Section ID */ + 1, /* Number of slaves */ + + 0, /* Node ID which will be changed below */ + PM_SLAVE_FLAG_IS_SHAREABLE, + PM_CONFIG_IPI_PSU_CORTEXA53_0_MASK | + PM_CONFIG_IPI_PSU_CORTEXR5_0_MASK | + PM_CONFIG_IPI_PSU_CORTEXR5_1_MASK, /* IPI Mask */ +}; + +static unsigned int xpm_configobject_close[] = { + /**********************************************************************/ + /* HEADER */ + 2, /* Number of remaining words in the header */ + 1, /* Number of sections included in config object */ + PM_CONFIG_OBJECT_TYPE_OVERLAY, /* Type of Config object as overlay */ + /**********************************************************************/ + /* SET CONFIG SECTION */ + PM_CONFIG_SET_CONFIG_SECTION_ID, + 0U, /* Loading permission to Overlay config object */ +}; + +int zynqmp_pmufw_config_close(void) +{ + zynqmp_pmufw_load_config_object(xpm_configobject_close, + sizeof(xpm_configobject_close)); + return 0; +} + +int zynqmp_pmufw_node(u32 id) +{ + /* Record power domain id */ + xpm_configobject[NODE_ID_LOCATION] = id; + + zynqmp_pmufw_load_config_object(xpm_configobject, + sizeof(xpm_configobject)); + + return 0; +} + static int ipi_req(const u32 *req, size_t req_len, u32 *res, size_t res_maxlen) { struct zynqmp_ipi_msg msg; @@ -226,8 +278,27 @@ static const struct udevice_id zynqmp_firmware_ids[] = { { } }; +static int zynqmp_firmware_bind(struct udevice *dev) +{ + int ret; + struct udevice *child; + + if (IS_ENABLED(CONFIG_ZYNQMP_POWER_DOMAIN)) { + ret = device_bind_driver_to_node(dev, "zynqmp_power_domain", + "zynqmp_power_domain", + dev_ofnode(dev), &child); + if (ret) { + printf("zynqmp power domain driver is not bound: %d\n", ret); + return ret; + } + } + + return dm_scan_fdt_dev(dev); +} + U_BOOT_DRIVER(zynqmp_firmware) = { .id = UCLASS_FIRMWARE, .name = "zynqmp_firmware", .of_match = zynqmp_firmware_ids, + .bind = zynqmp_firmware_bind, }; diff --git a/drivers/net/xilinx_axi_emac.c b/drivers/net/xilinx_axi_emac.c index 2ec76d0..f21addb 100644 --- a/drivers/net/xilinx_axi_emac.c +++ b/drivers/net/xilinx_axi_emac.c @@ -832,8 +832,8 @@ static int axi_emac_of_to_plat(struct udevice *dev) printf("%s: axistream is not found\n", __func__); return -EINVAL; } - plat->dmatx = (struct axidma_reg *)fdtdec_get_addr(gd->fdt_blob, - offset, "reg"); + plat->dmatx = (struct axidma_reg *)fdtdec_get_addr_size_auto_parent + (gd->fdt_blob, 0, offset, "reg", 0, NULL, false); if (!plat->dmatx) { printf("%s: axi_dma register space not found\n", __func__); return -EINVAL; diff --git a/drivers/phy/phy-zynqmp.c b/drivers/phy/phy-zynqmp.c index 9dc3d42..08c1b6e 100644 --- a/drivers/phy/phy-zynqmp.c +++ b/drivers/phy/phy-zynqmp.c @@ -373,6 +373,29 @@ static void xpsgtr_bypass_scrambler_8b10b(struct xpsgtr_phy *gtr_phy) xpsgtr_write_phy(gtr_phy, L0_TX_DIG_61, L0_TM_DISABLE_SCRAMBLE_ENCODER); } +/* DP-specific initialization. */ +static void xpsgtr_phy_init_dp(struct xpsgtr_phy *gtr_phy) +{ + xpsgtr_write_phy(gtr_phy, L0_TXPMD_TM_45, + L0_TXPMD_TM_45_OVER_DP_MAIN | + L0_TXPMD_TM_45_ENABLE_DP_MAIN | + L0_TXPMD_TM_45_OVER_DP_POST1 | + L0_TXPMD_TM_45_OVER_DP_POST2 | + L0_TXPMD_TM_45_ENABLE_DP_POST2); + xpsgtr_write_phy(gtr_phy, L0_TX_ANA_TM_118, + L0_TX_ANA_TM_118_FORCE_17_0); +} + +/* SATA-specific initialization. */ +static void xpsgtr_phy_init_sata(struct xpsgtr_phy *gtr_phy) +{ + struct xpsgtr_dev *gtr_dev = gtr_phy->dev; + + xpsgtr_bypass_scrambler_8b10b(gtr_phy); + + writel(gtr_phy->lane, gtr_dev->siou + SATA_CONTROL_OFFSET); +} + /* SGMII-specific initialization. */ static void xpsgtr_phy_init_sgmii(struct xpsgtr_phy *gtr_phy) { @@ -427,9 +450,12 @@ static int xpsgtr_init(struct phy *x) case ICM_PROTOCOL_SGMII: xpsgtr_phy_init_sgmii(gtr_phy); break; - case ICM_PROTOCOL_DP: case ICM_PROTOCOL_SATA: - return -EINVAL; + xpsgtr_phy_init_sata(gtr_phy); + break; + case ICM_PROTOCOL_DP: + xpsgtr_phy_init_dp(gtr_phy); + break; } dev_dbg(gtr_dev->dev, "lane %u (type %u, protocol %u): init done\n", diff --git a/drivers/power/domain/Kconfig b/drivers/power/domain/Kconfig index 9aea5fc..93d2599 100644 --- a/drivers/power/domain/Kconfig +++ b/drivers/power/domain/Kconfig @@ -88,4 +88,13 @@ config TI_POWER_DOMAIN help Generic power domain implementation for TI K3 devices. +config ZYNQMP_POWER_DOMAIN + bool "Enable the Xilinx ZynqMP Power domain driver" + depends on POWER_DOMAIN && ZYNQMP_FIRMWARE + help + Generic power domain implementation for Xilinx ZynqMP devices. + The driver should be enabled when system starts in very minimal + configuration and it is extended at run time. Then enabling + the driver will ensure that PMUFW enable access to requested IP. + endmenu diff --git a/drivers/power/domain/Makefile b/drivers/power/domain/Makefile index 530ae35..7c8af67 100644 --- a/drivers/power/domain/Makefile +++ b/drivers/power/domain/Makefile @@ -16,3 +16,4 @@ obj-$(CONFIG_SANDBOX_POWER_DOMAIN) += sandbox-power-domain-test.o obj-$(CONFIG_TEGRA186_POWER_DOMAIN) += tegra186-power-domain.o obj-$(CONFIG_TI_SCI_POWER_DOMAIN) += ti-sci-power-domain.o obj-$(CONFIG_TI_POWER_DOMAIN) += ti-power-domain.o +obj-$(CONFIG_ZYNQMP_POWER_DOMAIN) += zynqmp-power-domain.o diff --git a/drivers/power/domain/zynqmp-power-domain.c b/drivers/power/domain/zynqmp-power-domain.c new file mode 100644 index 0000000..5383d09 --- /dev/null +++ b/drivers/power/domain/zynqmp-power-domain.c @@ -0,0 +1,89 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2021, Xilinx. Inc. + */ + +#include <common.h> +#include <dm.h> +#include <log.h> +#include <malloc.h> +#include <misc.h> +#include <power-domain-uclass.h> +#include <linux/bitops.h> + +#include <zynqmp_firmware.h> + +#define NODE_ID_LOCATION 5 + +static unsigned int xpm_configobject[] = { + /* HEADER */ + 2, /* Number of remaining words in the header */ + 1, /* Number of sections included in config object */ + PM_CONFIG_OBJECT_TYPE_OVERLAY, /* Type of Config object as overlay */ + /* SLAVE SECTION */ + + PM_CONFIG_SLAVE_SECTION_ID, /* Section ID */ + 1, /* Number of slaves */ + + 0, /* Node ID which will be changed below */ + PM_SLAVE_FLAG_IS_SHAREABLE, + PM_CONFIG_IPI_PSU_CORTEXA53_0_MASK | + PM_CONFIG_IPI_PSU_CORTEXR5_0_MASK | + PM_CONFIG_IPI_PSU_CORTEXR5_1_MASK, /* IPI Mask */ +}; + +static int zynqmp_pm_request_node(const u32 node, const u32 capabilities, + const u32 qos, const enum zynqmp_pm_request_ack ack) +{ + return xilinx_pm_request(PM_REQUEST_NODE, node, capabilities, + qos, ack, NULL); +} + +static int zynqmp_power_domain_request(struct power_domain *power_domain) +{ + /* Record power domain id */ + xpm_configobject[NODE_ID_LOCATION] = power_domain->id; + + zynqmp_pmufw_load_config_object(xpm_configobject, sizeof(xpm_configobject)); + + return 0; +} + +static int zynqmp_power_domain_free(struct power_domain *power_domain) +{ + /* nop now */ + return 0; +} + +static int zynqmp_power_domain_on(struct power_domain *power_domain) +{ + return zynqmp_pm_request_node(power_domain->id, + ZYNQMP_PM_CAPABILITY_ACCESS, + ZYNQMP_PM_MAX_QOS, + ZYNQMP_PM_REQUEST_ACK_BLOCKING); +} + +static int zynqmp_power_domain_off(struct power_domain *power_domain) +{ + /* nop now */ + return 0; +} + +struct power_domain_ops zynqmp_power_domain_ops = { + .request = zynqmp_power_domain_request, + .rfree = zynqmp_power_domain_free, + .on = zynqmp_power_domain_on, + .off = zynqmp_power_domain_off, +}; + +static int zynqmp_power_domain_probe(struct udevice *dev) +{ + return 0; +} + +U_BOOT_DRIVER(zynqmp_power_domain) = { + .name = "zynqmp_power_domain", + .id = UCLASS_POWER_DOMAIN, + .probe = zynqmp_power_domain_probe, + .ops = &zynqmp_power_domain_ops, +}; diff --git a/drivers/spi/zynq_qspi.c b/drivers/spi/zynq_qspi.c index cf6da53..b69d992 100644 --- a/drivers/spi/zynq_qspi.c +++ b/drivers/spi/zynq_qspi.c @@ -16,6 +16,7 @@ #include <asm/global_data.h> #include <asm/io.h> #include <linux/bitops.h> +#include <spi-mem.h> DECLARE_GLOBAL_DATA_PTR; @@ -49,6 +50,9 @@ DECLARE_GLOBAL_DATA_PTR; #define ZYNQ_QSPI_CR_BAUD_SHIFT 3 /* Baud rate divisor shift */ #define ZYNQ_QSPI_CR_SS_SHIFT 10 /* Slave select shift */ +#define ZYNQ_QSPI_MAX_BAUD_RATE 0x7 +#define ZYNQ_QSPI_DEFAULT_BAUD_RATE 0x2 + #define ZYNQ_QSPI_FIFO_DEPTH 63 #define ZYNQ_QSPI_WAIT (CONFIG_SYS_HZ / 100) /* 10 ms */ @@ -230,12 +234,16 @@ static void zynq_qspi_read_data(struct zynq_qspi_priv *priv, u32 data, u8 size) priv->rx_buf += 1; break; case 2: - *((u16 *)priv->rx_buf) = data; - priv->rx_buf += 2; + *((u8 *)priv->rx_buf) = data; + priv->rx_buf += 1; + *((u8 *)priv->rx_buf) = (u8)(data >> 8); + priv->rx_buf += 1; break; case 3: - *((u16 *)priv->rx_buf) = data; - priv->rx_buf += 2; + *((u8 *)priv->rx_buf) = data; + priv->rx_buf += 1; + *((u8 *)priv->rx_buf) = (u8)(data >> 8); + priv->rx_buf += 1; byte3 = (u8)(data >> 16); *((u8 *)priv->rx_buf) = byte3; priv->rx_buf += 1; @@ -272,13 +280,17 @@ static void zynq_qspi_write_data(struct zynq_qspi_priv *priv, *data |= 0xFFFFFF00; break; case 2: - *data = *((u16 *)priv->tx_buf); - priv->tx_buf += 2; + *data = *((u8 *)priv->tx_buf); + priv->tx_buf += 1; + *data |= (*((u8 *)priv->tx_buf) << 8); + priv->tx_buf += 1; *data |= 0xFFFF0000; break; case 3: - *data = *((u16 *)priv->tx_buf); - priv->tx_buf += 2; + *data = *((u8 *)priv->tx_buf); + priv->tx_buf += 1; + *data |= (*((u8 *)priv->tx_buf) << 8); + priv->tx_buf += 1; *data |= (*((u8 *)priv->tx_buf) << 16); priv->tx_buf += 1; *data |= 0xFF000000; @@ -613,6 +625,9 @@ static int zynq_qspi_set_speed(struct udevice *bus, uint speed) (2 << baud_rate_val)) > speed)) baud_rate_val++; + if (baud_rate_val > ZYNQ_QSPI_MAX_BAUD_RATE) + baud_rate_val = ZYNQ_QSPI_DEFAULT_BAUD_RATE; + plat->speed_hz = speed / (2 << baud_rate_val); } confr &= ~ZYNQ_QSPI_CR_BAUD_MASK; @@ -649,12 +664,72 @@ static int zynq_qspi_set_mode(struct udevice *bus, uint mode) return 0; } +static int zynq_qspi_exec_op(struct spi_slave *slave, + const struct spi_mem_op *op) +{ + int op_len, pos = 0, ret, i; + unsigned int flag = 0; + const u8 *tx_buf = NULL; + u8 *rx_buf = NULL; + + if (op->data.nbytes) { + if (op->data.dir == SPI_MEM_DATA_IN) + rx_buf = op->data.buf.in; + else + tx_buf = op->data.buf.out; + } + + op_len = op->cmd.nbytes + op->addr.nbytes + op->dummy.nbytes; + + u8 op_buf[op_len]; + + op_buf[pos++] = op->cmd.opcode; + + if (op->addr.nbytes) { + for (i = 0; i < op->addr.nbytes; i++) + op_buf[pos + i] = op->addr.val >> + (8 * (op->addr.nbytes - i - 1)); + + pos += op->addr.nbytes; + } + + if (op->dummy.nbytes) + memset(op_buf + pos, 0xff, op->dummy.nbytes); + + /* 1st transfer: opcode + address + dummy cycles */ + /* Make sure to set END bit if no tx or rx data messages follow */ + if (!tx_buf && !rx_buf) + flag |= SPI_XFER_END; + + ret = zynq_qspi_xfer(slave->dev, op_len * 8, op_buf, NULL, + flag | SPI_XFER_BEGIN); + if (ret) + return ret; + + /* 2nd transfer: rx or tx data path */ + if (tx_buf || rx_buf) { + ret = zynq_qspi_xfer(slave->dev, op->data.nbytes * 8, tx_buf, + rx_buf, flag | SPI_XFER_END); + if (ret) + return ret; + } + + spi_release_bus(slave); + + return 0; +} + +static const struct spi_controller_mem_ops zynq_qspi_mem_ops = { + .exec_op = zynq_qspi_exec_op, +}; + static const struct dm_spi_ops zynq_qspi_ops = { .claim_bus = zynq_qspi_claim_bus, .release_bus = zynq_qspi_release_bus, .xfer = zynq_qspi_xfer, .set_speed = zynq_qspi_set_speed, .set_mode = zynq_qspi_set_mode, + .mem_ops = &zynq_qspi_mem_ops, }; static const struct udevice_id zynq_qspi_ids[] = { diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index cfa08b5..ff8e11f 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -675,7 +675,7 @@ config VIDEO_NX config VIDEO_SEPS525 bool "Enable video support for Seps525" - depends on DM_VIDEO + depends on DM_VIDEO && DM_GPIO help Enable support for the Syncoam PM-OLED display driver (RGB 160x128). Currently driver is supporting only SPI interface. diff --git a/include/configs/microblaze-generic.h b/include/configs/microblaze-generic.h index ca749ed..fd5a9cf 100644 --- a/include/configs/microblaze-generic.h +++ b/include/configs/microblaze-generic.h @@ -11,9 +11,6 @@ /* Microblaze is microblaze_0 */ #define XILINX_FSL_NUMBER 3 -/* MicroBlaze CPU */ -#define MICROBLAZE_V5 1 - #define CONFIG_SYS_BOOTM_LEN (64 * 1024 * 1024) /* uart */ diff --git a/include/zynqmp_firmware.h b/include/zynqmp_firmware.h index 0b068d7..50bf4ef 100644 --- a/include/zynqmp_firmware.h +++ b/include/zynqmp_firmware.h @@ -342,20 +342,20 @@ enum pm_ioctl_id { IOCTL_AIE_ISR_CLEAR = 24, }; -#define PM_SIP_SVC 0xc2000000 +#define PM_SIP_SVC 0xc2000000 -#define ZYNQMP_PM_VERSION_MAJOR 1 -#define ZYNQMP_PM_VERSION_MINOR 0 -#define ZYNQMP_PM_VERSION_MAJOR_SHIFT 16 -#define ZYNQMP_PM_VERSION_MINOR_MASK 0xFFFF +#define ZYNQMP_PM_VERSION_MAJOR 1 +#define ZYNQMP_PM_VERSION_MINOR 0 +#define ZYNQMP_PM_VERSION_MAJOR_SHIFT 16 +#define ZYNQMP_PM_VERSION_MINOR_MASK 0xFFFF #define ZYNQMP_PM_VERSION \ ((ZYNQMP_PM_VERSION_MAJOR << ZYNQMP_PM_VERSION_MAJOR_SHIFT) | \ ZYNQMP_PM_VERSION_MINOR) -#define ZYNQMP_PM_VERSION_INVALID ~0 +#define ZYNQMP_PM_VERSION_INVALID ~0 -#define PMUFW_V1_0 ((1 << ZYNQMP_PM_VERSION_MAJOR_SHIFT) | 0) +#define PMUFW_V1_0 ((1 << ZYNQMP_PM_VERSION_MAJOR_SHIFT) | 0) /* * Return payload size @@ -367,8 +367,41 @@ enum pm_ioctl_id { #define PAYLOAD_ARG_CNT 5U unsigned int zynqmp_firmware_version(void); +int zynqmp_pmufw_node(u32 id); +int zynqmp_pmufw_config_close(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, u32 arg3, u32 *ret_payload); +/* Type of Config Object */ +#define PM_CONFIG_OBJECT_TYPE_BASE 0x1U +#define PM_CONFIG_OBJECT_TYPE_OVERLAY 0x2U + +/* Section Id */ +#define PM_CONFIG_SLAVE_SECTION_ID 0x102U +#define PM_CONFIG_SET_CONFIG_SECTION_ID 0x107U + +/* Flag Option */ +#define PM_SLAVE_FLAG_IS_SHAREABLE 0x1U +#define PM_MASTER_USING_SLAVE_MASK 0x2U + +/* IPI Mask for Master */ +#define PM_CONFIG_IPI_PSU_CORTEXA53_0_MASK 0x00000001 +#define PM_CONFIG_IPI_PSU_CORTEXR5_0_MASK 0x00000100 +#define PM_CONFIG_IPI_PSU_CORTEXR5_1_MASK 0x00000200 + +enum zynqmp_pm_request_ack { + ZYNQMP_PM_REQUEST_ACK_NO = 1, + ZYNQMP_PM_REQUEST_ACK_BLOCKING = 2, + ZYNQMP_PM_REQUEST_ACK_NON_BLOCKING = 3, +}; + +/* Node capabilities */ +#define ZYNQMP_PM_CAPABILITY_ACCESS 0x1U +#define ZYNQMP_PM_CAPABILITY_CONTEXT 0x2U +#define ZYNQMP_PM_CAPABILITY_WAKEUP 0x4U +#define ZYNQMP_PM_CAPABILITY_UNUSABLE 0x8U + +#define ZYNQMP_PM_MAX_QOS 100U + #endif /* _ZYNQMP_FIRMWARE_H_ */ diff --git a/tools/zynqmp_pm_cfg_obj_convert.py b/tools/zynqmp_pm_cfg_obj_convert.py index 0a44710..239991a 100755 --- a/tools/zynqmp_pm_cfg_obj_convert.py +++ b/tools/zynqmp_pm_cfg_obj_convert.py @@ -244,6 +244,8 @@ pm_define = { 'SUSPEND_TIMEOUT' : 0xFFFFFFFF, + 'PM_CONFIG_OBJECT_TYPE_BASE' : 0x1, + 'PM_CONFIG_IPI_PSU_CORTEXA53_0_MASK' : 0x00000001, 'PM_CONFIG_IPI_PSU_CORTEXR5_0_MASK' : 0x00000100, 'PM_CONFIG_IPI_PSU_CORTEXR5_1_MASK' : 0x00000200, |