From ce7b93d4fc6b992ce0215e7b22f3983d20482b60 Mon Sep 17 00:00:00 2001 From: "Robert P. J. Day" Date: Thu, 18 Apr 2019 10:50:23 -0400 Subject: [PATCH 01/22] ARM: zynq: delete long-dead CONFIG_USB_CABLE_CHECK This Kbuild option disappeared way back in 2014: commit 75504e9592745021006cb8905b5ff5a51d9d1cb3 Author: Mateusz Zalega Date: Wed Apr 30 13:07:48 2014 +0200 ... snip ... CONFIG_USB_CABLE_CHECK was removed. Signed-off-by: Robert P. J. Day Signed-off-by: Michal Simek --- include/configs/xilinx_zynqmp.h | 1 - include/configs/zynq-common.h | 1 - scripts/config_whitelist.txt | 1 - 3 files changed, 3 deletions(-) diff --git a/include/configs/xilinx_zynqmp.h b/include/configs/xilinx_zynqmp.h index 684faaee2e..bbcb20737b 100644 --- a/include/configs/xilinx_zynqmp.h +++ b/include/configs/xilinx_zynqmp.h @@ -62,7 +62,6 @@ #if defined(CONFIG_ZYNQMP_USB) #define CONFIG_SYS_DFU_DATA_BUF_SIZE 0x1800000 #define DFU_DEFAULT_POLL_TIMEOUT 300 -#define CONFIG_USB_CABLE_CHECK #define CONFIG_THOR_RESET_OFF #define DFU_ALT_INFO_RAM \ "dfu_ram_info=" \ diff --git a/include/configs/zynq-common.h b/include/configs/zynq-common.h index b51914d1e0..62fbf8866f 100644 --- a/include/configs/zynq-common.h +++ b/include/configs/zynq-common.h @@ -65,7 +65,6 @@ # define CONFIG_SYS_DFU_DATA_BUF_SIZE 0x600000 # define DFU_DEFAULT_POLL_TIMEOUT 300 -# define CONFIG_USB_CABLE_CHECK # define CONFIG_THOR_RESET_OFF # define DFU_ALT_INFO_RAM \ "dfu_ram_info=" \ diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt index bcb24d1bc3..89119aea22 100644 --- a/scripts/config_whitelist.txt +++ b/scripts/config_whitelist.txt @@ -4293,7 +4293,6 @@ CONFIG_USB_ATMEL_CLK_SEL_PLLB CONFIG_USB_ATMEL_CLK_SEL_UPLL CONFIG_USB_BIN_FIXUP CONFIG_USB_BOOTING -CONFIG_USB_CABLE_CHECK CONFIG_USB_DEVICE CONFIG_USB_DEV_BASE CONFIG_USB_DEV_PULLUP_GPIO From 420d44678119a5df1fcc154d1c33d35fd9722285 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Tue, 21 May 2019 12:07:23 +0200 Subject: [PATCH 02/22] arm64: zynqmp: Rename zc1275 to zcu1275 Name of this platform has changed and released to customers that's why name has also changed. Signed-off-by: Michal Simek Series-to: uboot --- arch/arm/dts/Makefile | 4 ++-- .../{zynqmp-zc1275-revA.dts => zynqmp-zcu1275-revA.dts} | 7 ++++--- .../{zynqmp-zc1275-revB.dts => zynqmp-zcu1275-revB.dts} | 7 ++++--- ...revA_defconfig => xilinx_zynqmp_zcu1275_revA_defconfig} | 2 +- ...revB_defconfig => xilinx_zynqmp_zcu1275_revB_defconfig} | 2 +- 5 files changed, 12 insertions(+), 10 deletions(-) rename arch/arm/dts/{zynqmp-zc1275-revA.dts => zynqmp-zcu1275-revA.dts} (89%) rename arch/arm/dts/{zynqmp-zc1275-revB.dts => zynqmp-zcu1275-revB.dts} (89%) rename configs/{xilinx_zynqmp_zc1275_revA_defconfig => xilinx_zynqmp_zcu1275_revA_defconfig} (96%) rename configs/{xilinx_zynqmp_zc1275_revB_defconfig => xilinx_zynqmp_zcu1275_revB_defconfig} (96%) diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index b437f7500c..ff181978de 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -253,10 +253,10 @@ dtb-$(CONFIG_ARCH_ZYNQMP) += \ zynqmp-zcu104-revC.dtb \ zynqmp-zcu106-revA.dtb \ zynqmp-zcu111-revA.dtb \ + zynqmp-zcu1275-revA.dtb \ + zynqmp-zcu1275-revB.dtb \ zynqmp-zc1232-revA.dtb \ zynqmp-zc1254-revA.dtb \ - zynqmp-zc1275-revA.dtb \ - zynqmp-zc1275-revB.dtb \ zynqmp-zc1751-xm015-dc1.dtb \ zynqmp-zc1751-xm016-dc2.dtb \ zynqmp-zc1751-xm017-dc3.dtb \ diff --git a/arch/arm/dts/zynqmp-zc1275-revA.dts b/arch/arm/dts/zynqmp-zcu1275-revA.dts similarity index 89% rename from arch/arm/dts/zynqmp-zc1275-revA.dts rename to arch/arm/dts/zynqmp-zcu1275-revA.dts index 82c30a3fbe..c22de576a5 100644 --- a/arch/arm/dts/zynqmp-zc1275-revA.dts +++ b/arch/arm/dts/zynqmp-zcu1275-revA.dts @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0+ /* - * dts file for Xilinx ZynqMP ZC1275 + * dts file for Xilinx ZynqMP ZCU1275 * * (C) Copyright 2017 - 2018, Xilinx, Inc. * @@ -14,8 +14,9 @@ #include "zynqmp-clk-ccf.dtsi" / { - model = "ZynqMP ZC1275 RevA"; - compatible = "xlnx,zynqmp-zc1275-revA", "xlnx,zynqmp-zc1275", "xlnx,zynqmp"; + model = "ZynqMP ZCU1275 RevA"; + compatible = "xlnx,zynqmp-zcu1275-revA", "xlnx,zynqmp-zcu1275", + "xlnx,zynqmp"; aliases { serial0 = &uart0; diff --git a/arch/arm/dts/zynqmp-zc1275-revB.dts b/arch/arm/dts/zynqmp-zcu1275-revB.dts similarity index 89% rename from arch/arm/dts/zynqmp-zc1275-revB.dts rename to arch/arm/dts/zynqmp-zcu1275-revB.dts index 0473503afa..34c4becd43 100644 --- a/arch/arm/dts/zynqmp-zc1275-revB.dts +++ b/arch/arm/dts/zynqmp-zcu1275-revB.dts @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 /* - * dts file for Xilinx ZynqMP ZC1275 RevB + * dts file for Xilinx ZynqMP ZCU1275 RevB * * (C) Copyright 2018, Xilinx, Inc. * @@ -14,8 +14,9 @@ #include "zynqmp-clk-ccf.dtsi" / { - model = "ZynqMP ZC1275 RevB"; - compatible = "xlnx,zynqmp-zc1275-revB", "xlnx,zynqmp-zc1275", "xlnx,zynqmp"; + model = "ZynqMP ZCU1275 RevB"; + compatible = "xlnx,zynqmp-zcu1275-revB", "xlnx,zynqmp-zcu1275", + "xlnx,zynqmp"; aliases { serial0 = &uart0; diff --git a/configs/xilinx_zynqmp_zc1275_revA_defconfig b/configs/xilinx_zynqmp_zcu1275_revA_defconfig similarity index 96% rename from configs/xilinx_zynqmp_zc1275_revA_defconfig rename to configs/xilinx_zynqmp_zcu1275_revA_defconfig index ed6c1b8296..c73a97a050 100644 --- a/configs/xilinx_zynqmp_zc1275_revA_defconfig +++ b/configs/xilinx_zynqmp_zcu1275_revA_defconfig @@ -30,7 +30,7 @@ CONFIG_CMD_SF=y CONFIG_CMD_TIME=y CONFIG_CMD_TIMER=y CONFIG_SPL_OF_CONTROL=y -CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zc1275-revA" +CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zcu1275-revA" CONFIG_SPL_DM=y CONFIG_CLK_ZYNQMP=y CONFIG_FPGA_XILINX=y diff --git a/configs/xilinx_zynqmp_zc1275_revB_defconfig b/configs/xilinx_zynqmp_zcu1275_revB_defconfig similarity index 96% rename from configs/xilinx_zynqmp_zc1275_revB_defconfig rename to configs/xilinx_zynqmp_zcu1275_revB_defconfig index 0c2491aceb..0d4302ea73 100644 --- a/configs/xilinx_zynqmp_zc1275_revB_defconfig +++ b/configs/xilinx_zynqmp_zcu1275_revB_defconfig @@ -31,7 +31,7 @@ CONFIG_CMD_SF=y CONFIG_CMD_TIME=y CONFIG_CMD_TIMER=y CONFIG_SPL_OF_CONTROL=y -CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zc1275-revB" +CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zcu1275-revB" CONFIG_NET_RANDOM_ETHADDR=y CONFIG_SPL_DM=y CONFIG_CLK_ZYNQMP=y From c28a9cfa4079031edd511746770096a131414642 Mon Sep 17 00:00:00 2001 From: Luca Ceresoli Date: Tue, 21 May 2019 18:06:43 +0200 Subject: [PATCH 03/22] arm64: zynqmp: spl: install a PMU firmware config object at runtime Optionally allow U-Boot to load a configuration object into the Power Management Unit (PMU) firmware on Xilinx ZynqMP. The configuration object is required by the PMU FW to enable most SoC peripherals. So far the only way to boot using U-Boot SPL was to hard-code the configuration object in the PMU firmware. Allow a different boot process, where the PMU FW is equal for any ZynqMP chip and its configuration is passed at runtime by U-Boot SPL. All the code for Inter-processor communication with the PMU is isolated in a new file (pmu_ipc.c). The code is inspired by the same feature as implemented in the Xilinx First Stage Bootloader (FSBL) and Arm Trusted Firmware: * https://github.com/Xilinx/embeddedsw/blob/fb647e6b4c00f5154eba52a88b948195b6f1dc2b/lib/sw_apps/zynqmp_fsbl/src/xfsbl_misc_drivers.c#L295 * https://github.com/ARM-software/arm-trusted-firmware/blob/c48d02bade88b07fa7f43aa44e5217f68e5d047f/plat/xilinx/zynqmp/pm_service/pm_api_sys.c#L357 SPL logs on the console before loading the configuration object: U-Boot SPL 2019.07-rc1-00511-gaec224515c87 (May 15 2019 - 08:43:41 +0200) Loading PMUFW cfg obj (2008 bytes) EL Level: EL3 ... Signed-off-by: Luca Ceresoli Signed-off-by: Michal Simek --- arch/arm/mach-zynqmp/Kconfig | 18 +++ arch/arm/mach-zynqmp/Makefile | 4 + arch/arm/mach-zynqmp/include/mach/sys_proto.h | 2 + arch/arm/mach-zynqmp/pmu_ipc.c | 112 ++++++++++++++++++ board/xilinx/zynqmp/Makefile | 5 + board/xilinx/zynqmp/pm_cfg_obj.S | 17 +++ board/xilinx/zynqmp/pm_cfg_obj.h | 9 ++ board/xilinx/zynqmp/zynqmp.c | 9 ++ 8 files changed, 176 insertions(+) create mode 100644 arch/arm/mach-zynqmp/pmu_ipc.c create mode 100644 board/xilinx/zynqmp/pm_cfg_obj.S create mode 100644 board/xilinx/zynqmp/pm_cfg_obj.h diff --git a/arch/arm/mach-zynqmp/Kconfig b/arch/arm/mach-zynqmp/Kconfig index 9bb5a5c202..6cf17eb94e 100644 --- a/arch/arm/mach-zynqmp/Kconfig +++ b/arch/arm/mach-zynqmp/Kconfig @@ -65,6 +65,24 @@ config PMUFW_INIT_FILE Include external PMUFW (Platform Management Unit FirmWare) to a Xilinx bootable image (boot.bin). +config ZYNQMP_SPL_PM_CFG_OBJ_FILE + string "PMU firmware configuration object to load at runtime by SPL" + depends on SPL + help + Path to a binary PMU firmware configuration object to be linked + into U-Boot SPL and loaded at runtime into the PMU firmware. + + The ZynqMP Power Management Unit (PMU) needs a configuration + object for most SoC peripherals to work. To have it loaded by + U-Boot SPL set here the file name (absolute path or relative to + the top source tree) of your configuration, which must be a + binary blob. It will be linked in the SPL binary and loaded + into the PMU firmware by U-Boot SPL during board + initialization. + + Leave this option empty if your PMU firmware has a hard-coded + configuration object or you are loading it by any other means. + config ZYNQMP_USB bool "Configure ZynqMP USB" diff --git a/arch/arm/mach-zynqmp/Makefile b/arch/arm/mach-zynqmp/Makefile index 8a3b074724..f3765e45b1 100644 --- a/arch/arm/mach-zynqmp/Makefile +++ b/arch/arm/mach-zynqmp/Makefile @@ -8,3 +8,7 @@ obj-y += cpu.o obj-$(CONFIG_MP) += mp.o obj-$(CONFIG_SPL_BUILD) += spl.o handoff.o obj-$(CONFIG_ZYNQMP_PSU_INIT_ENABLED) += psu_spl_init.o + +ifneq ($(CONFIG_ZYNQMP_SPL_PM_CFG_OBJ_FILE),"") +obj-$(CONFIG_SPL_BUILD) += pmu_ipc.o +endif diff --git a/arch/arm/mach-zynqmp/include/mach/sys_proto.h b/arch/arm/mach-zynqmp/include/mach/sys_proto.h index 385c8825f2..915badc6fb 100644 --- a/arch/arm/mach-zynqmp/include/mach/sys_proto.h +++ b/arch/arm/mach-zynqmp/include/mach/sys_proto.h @@ -72,4 +72,6 @@ int chip_id(unsigned char id); void tcm_init(u8 mode); #endif +void zynqmp_pmufw_load_config_object(const void *cfg_obj, size_t size); + #endif /* _ASM_ARCH_SYS_PROTO_H */ diff --git a/arch/arm/mach-zynqmp/pmu_ipc.c b/arch/arm/mach-zynqmp/pmu_ipc.c new file mode 100644 index 0000000000..d8858ea3ff --- /dev/null +++ b/arch/arm/mach-zynqmp/pmu_ipc.c @@ -0,0 +1,112 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Inter-Processor Communication with the Platform Management Unit (PMU) + * firmware. + * + * (C) Copyright 2019 Luca Ceresoli + * Luca Ceresoli + */ + +#include +#include +#include + +/* IPI bitmasks, register base and register offsets */ +#define IPI_BIT_MASK_APU 0x00001 +#define IPI_BIT_MASK_PMU0 0x10000 +#define IPI_REG_BASE_APU 0xFF300000 +#define IPI_REG_BASE_PMU0 0xFF330000 +#define IPI_REG_OFFSET_TRIG 0x00 +#define IPI_REG_OFFSET_OBR 0x04 + +/* IPI mailbox buffer offsets */ +#define IPI_BUF_BASE_APU 0xFF990400 +#define IPI_BUF_OFFSET_TARGET_PMU 0x1C0 +#define IPI_BUF_OFFSET_REQ 0x00 +#define IPI_BUF_OFFSET_RESP 0x20 + +#define PMUFW_PAYLOAD_ARG_CNT 8 + +/* PMUFW commands */ +#define PMUFW_CMD_SET_CONFIGURATION 2 + +static void pmu_ipc_send_request(const u32 *req, size_t req_len) +{ + u32 *mbx = (u32 *)(IPI_BUF_BASE_APU + + IPI_BUF_OFFSET_TARGET_PMU + + IPI_BUF_OFFSET_REQ); + size_t i; + + for (i = 0; i < req_len; i++) + writel(req[i], &mbx[i]); +} + +static void pmu_ipc_read_response(unsigned int *value, size_t count) +{ + u32 *mbx = (u32 *)(IPI_BUF_BASE_APU + + IPI_BUF_OFFSET_TARGET_PMU + + IPI_BUF_OFFSET_RESP); + size_t i; + + for (i = 0; i < count; i++) + value[i] = readl(&mbx[i]); +} + +/** + * Send request to PMU and get the response. + * + * @req: Request buffer. Byte 0 is the API ID, other bytes are optional + * parameters. + * @req_len: Request length in number of 32-bit words. + * @res: Response buffer. Byte 0 is the error code, other bytes are + * optional parameters. Optional, if @res_maxlen==0 the parameters + * will not be read. + * @res_maxlen: Space allocated for the response in number of 32-bit words. + * + * @return Error code returned by the PMU (i.e. the first word of the response) + */ +static int pmu_ipc_request(const u32 *req, size_t req_len, + u32 *res, size_t res_maxlen) +{ + u32 status; + + if (req_len > PMUFW_PAYLOAD_ARG_CNT || + res_maxlen > PMUFW_PAYLOAD_ARG_CNT) + return -EINVAL; + + pmu_ipc_send_request(req, req_len); + + /* Raise Inter-Processor Interrupt to PMU and wait for response */ + writel(IPI_BIT_MASK_PMU0, IPI_REG_BASE_APU + IPI_REG_OFFSET_TRIG); + do { + status = readl(IPI_REG_BASE_APU + IPI_REG_OFFSET_OBR); + } while (status & IPI_BIT_MASK_PMU0); + + pmu_ipc_read_response(res, res_maxlen); + + return 0; +} + +/** + * Send a configuration object to the PMU firmware. + * + * @cfg_obj: Pointer to the configuration object + * @size: Size of @cfg_obj in bytes + */ +void zynqmp_pmufw_load_config_object(const void *cfg_obj, size_t size) +{ + const u32 request[] = { + PMUFW_CMD_SET_CONFIGURATION, + (u32)((u64)cfg_obj) + }; + u32 response; + int err; + + printf("Loading PMUFW cfg obj (%ld bytes)\n", size); + + err = pmu_ipc_request(request, ARRAY_SIZE(request), &response, 1); + if (err) + panic("Cannot load PMUFW configuration object (%d)\n", err); + if (response != 0) + panic("PMUFW returned 0x%08x status!\n", response); +} diff --git a/board/xilinx/zynqmp/Makefile b/board/xilinx/zynqmp/Makefile index 80f8ca7e1e..b4d39edc11 100644 --- a/board/xilinx/zynqmp/Makefile +++ b/board/xilinx/zynqmp/Makefile @@ -33,6 +33,11 @@ ifneq ($(call ifdef_any_of, CONFIG_ZYNQMP_PSU_INIT_ENABLED CONFIG_SPL_BUILD),) obj-y += $(init-objs) endif +ifneq ($(CONFIG_ZYNQMP_SPL_PM_CFG_OBJ_FILE),"") +obj-$(CONFIG_SPL_BUILD) += pm_cfg_obj.o +$(obj)/pm_cfg_obj.o: $(shell cd $(srctree); readlink -f $(CONFIG_ZYNQMP_SPL_PM_CFG_OBJ_FILE)) FORCE +endif + obj-$(CONFIG_MMC_SDHCI_ZYNQ) += tap_delays.o ifndef CONFIG_SPL_BUILD diff --git a/board/xilinx/zynqmp/pm_cfg_obj.S b/board/xilinx/zynqmp/pm_cfg_obj.S new file mode 100644 index 0000000000..c4ca77e396 --- /dev/null +++ b/board/xilinx/zynqmp/pm_cfg_obj.S @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ + +.section .rodata + +.global zynqmp_pm_cfg_obj +.type zynqmp_pm_cfg_obj, @object +.global zynqmp_pm_cfg_obj_size +.type zynqmp_pm_cfg_obj_size, @object + +zynqmp_pm_cfg_obj: +.align 4 +.incbin CONFIG_ZYNQMP_SPL_PM_CFG_OBJ_FILE + +zynqmp_pm_cfg_obj_end: + +zynqmp_pm_cfg_obj_size: +.int zynqmp_pm_cfg_obj_end - zynqmp_pm_cfg_obj diff --git a/board/xilinx/zynqmp/pm_cfg_obj.h b/board/xilinx/zynqmp/pm_cfg_obj.h new file mode 100644 index 0000000000..86e785490c --- /dev/null +++ b/board/xilinx/zynqmp/pm_cfg_obj.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * (C) Copyright 2019 Luca Ceresoli + * + * Declaration of PMU config object binary blob linked in at build time. + */ + +extern const u32 zynqmp_pm_cfg_obj[]; +extern const int zynqmp_pm_cfg_obj_size; diff --git a/board/xilinx/zynqmp/zynqmp.c b/board/xilinx/zynqmp/zynqmp.c index c840e92d9c..057ca1fbf7 100644 --- a/board/xilinx/zynqmp/zynqmp.c +++ b/board/xilinx/zynqmp/zynqmp.c @@ -22,6 +22,8 @@ #include #include +#include "pm_cfg_obj.h" + DECLARE_GLOBAL_DATA_PTR; #if defined(CONFIG_FPGA) && defined(CONFIG_FPGA_ZYNQMPPL) && \ @@ -327,6 +329,13 @@ int board_early_init_f(void) int board_init(void) { +#if defined(CONFIG_SPL_BUILD) + /* Check *at build time* if the filename is an non-empty string */ + if (sizeof(CONFIG_ZYNQMP_SPL_PM_CFG_OBJ_FILE) > 1) + zynqmp_pmufw_load_config_object(zynqmp_pm_cfg_obj, + zynqmp_pm_cfg_obj_size); +#endif + printf("EL Level:\tEL%d\n", current_el()); #if defined(CONFIG_FPGA) && defined(CONFIG_FPGA_ZYNQMPPL) && \ From 4f4b56205ec0ad76f001fef19709e9e1014b2e5f Mon Sep 17 00:00:00 2001 From: Luca Ceresoli Date: Tue, 21 May 2019 18:06:44 +0200 Subject: [PATCH 04/22] arm64: zynqmp: add tool to convert PMU config object .c to binary The recently-added ZYNQMP_SPL_PM_CFG_OBJ_FILE option allows SPL to load a PMUFW configuration object from a binary blob. However the configuration object is produced by Xilinx proprietary tools as a C source file and no tool exists to easily convert it to a binary blob in an embedded Linux build system for U-Boot to use. Add a simple Python script to do the conversion. It is definitely not a complete C language parser, but it is enough to parse the known patterns generated by Xilinx tools, including: - defines - literal integers, optionally with a 'U' suffix - bitwise OR between them Signed-off-by: Luca Ceresoli Signed-off-by: Michal Simek --- tools/zynqmp_pm_cfg_obj_convert.py | 301 +++++++++++++++++++++++++++++ 1 file changed, 301 insertions(+) create mode 100755 tools/zynqmp_pm_cfg_obj_convert.py diff --git a/tools/zynqmp_pm_cfg_obj_convert.py b/tools/zynqmp_pm_cfg_obj_convert.py new file mode 100755 index 0000000000..dd27f47921 --- /dev/null +++ b/tools/zynqmp_pm_cfg_obj_convert.py @@ -0,0 +1,301 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: GPL-2.0+ +# Copyright (C) 2019 Luca Ceresoli + +import sys +import re +import struct +import logging +import argparse + +parser = argparse.ArgumentParser( + description='Convert a PMU configuration object from C source to a binary blob.') +parser.add_argument('-D', '--debug', action="store_true") +parser.add_argument( + "in_file", metavar='INPUT_FILE', + help='PMU configuration object (C source as produced by Xilinx XSDK)') +parser.add_argument( + "out_file", metavar='OUTPUT_FILE', + help='PMU configuration object binary blob') +args = parser.parse_args() + +logging.basicConfig(format='%(levelname)s:%(message)s', + level=(logging.DEBUG if args.debug else logging.WARNING)) + +pm_define = { + 'PM_CAP_ACCESS' : 0x1, + 'PM_CAP_CONTEXT' : 0x2, + 'PM_CAP_WAKEUP' : 0x4, + + 'NODE_UNKNOWN' : 0, + 'NODE_APU' : 1, + 'NODE_APU_0' : 2, + 'NODE_APU_1' : 3, + 'NODE_APU_2' : 4, + 'NODE_APU_3' : 5, + 'NODE_RPU' : 6, + 'NODE_RPU_0' : 7, + 'NODE_RPU_1' : 8, + 'NODE_PLD' : 9, + 'NODE_FPD' : 10, + 'NODE_OCM_BANK_0' : 11, + 'NODE_OCM_BANK_1' : 12, + 'NODE_OCM_BANK_2' : 13, + 'NODE_OCM_BANK_3' : 14, + 'NODE_TCM_0_A' : 15, + 'NODE_TCM_0_B' : 16, + 'NODE_TCM_1_A' : 17, + 'NODE_TCM_1_B' : 18, + 'NODE_L2' : 19, + 'NODE_GPU_PP_0' : 20, + 'NODE_GPU_PP_1' : 21, + 'NODE_USB_0' : 22, + 'NODE_USB_1' : 23, + 'NODE_TTC_0' : 24, + 'NODE_TTC_1' : 25, + 'NODE_TTC_2' : 26, + 'NODE_TTC_3' : 27, + 'NODE_SATA' : 28, + 'NODE_ETH_0' : 29, + 'NODE_ETH_1' : 30, + 'NODE_ETH_2' : 31, + 'NODE_ETH_3' : 32, + 'NODE_UART_0' : 33, + 'NODE_UART_1' : 34, + 'NODE_SPI_0' : 35, + 'NODE_SPI_1' : 36, + 'NODE_I2C_0' : 37, + 'NODE_I2C_1' : 38, + 'NODE_SD_0' : 39, + 'NODE_SD_1' : 40, + 'NODE_DP' : 41, + 'NODE_GDMA' : 42, + 'NODE_ADMA' : 43, + 'NODE_NAND' : 44, + 'NODE_QSPI' : 45, + 'NODE_GPIO' : 46, + 'NODE_CAN_0' : 47, + 'NODE_CAN_1' : 48, + 'NODE_EXTERN' : 49, + 'NODE_APLL' : 50, + 'NODE_VPLL' : 51, + 'NODE_DPLL' : 52, + 'NODE_RPLL' : 53, + 'NODE_IOPLL' : 54, + 'NODE_DDR' : 55, + 'NODE_IPI_APU' : 56, + 'NODE_IPI_RPU_0' : 57, + 'NODE_GPU' : 58, + 'NODE_PCIE' : 59, + 'NODE_PCAP' : 60, + 'NODE_RTC' : 61, + 'NODE_LPD' : 62, + 'NODE_VCU' : 63, + 'NODE_IPI_RPU_1' : 64, + 'NODE_IPI_PL_0' : 65, + 'NODE_IPI_PL_1' : 66, + 'NODE_IPI_PL_2' : 67, + 'NODE_IPI_PL_3' : 68, + 'NODE_PL' : 69, + 'NODE_ID_MA' : 70, + + 'XILPM_RESET_PCIE_CFG' : 1000, + 'XILPM_RESET_PCIE_BRIDGE' : 1001, + 'XILPM_RESET_PCIE_CTRL' : 1002, + 'XILPM_RESET_DP' : 1003, + 'XILPM_RESET_SWDT_CRF' : 1004, + 'XILPM_RESET_AFI_FM5' : 1005, + 'XILPM_RESET_AFI_FM4' : 1006, + 'XILPM_RESET_AFI_FM3' : 1007, + 'XILPM_RESET_AFI_FM2' : 1008, + 'XILPM_RESET_AFI_FM1' : 1009, + 'XILPM_RESET_AFI_FM0' : 1010, + 'XILPM_RESET_GDMA' : 1011, + 'XILPM_RESET_GPU_PP1' : 1012, + 'XILPM_RESET_GPU_PP0' : 1013, + 'XILPM_RESET_GPU' : 1014, + 'XILPM_RESET_GT' : 1015, + 'XILPM_RESET_SATA' : 1016, + 'XILPM_RESET_ACPU3_PWRON' : 1017, + 'XILPM_RESET_ACPU2_PWRON' : 1018, + 'XILPM_RESET_ACPU1_PWRON' : 1019, + 'XILPM_RESET_ACPU0_PWRON' : 1020, + 'XILPM_RESET_APU_L2' : 1021, + 'XILPM_RESET_ACPU3' : 1022, + 'XILPM_RESET_ACPU2' : 1023, + 'XILPM_RESET_ACPU1' : 1024, + 'XILPM_RESET_ACPU0' : 1025, + 'XILPM_RESET_DDR' : 1026, + 'XILPM_RESET_APM_FPD' : 1027, + 'XILPM_RESET_SOFT' : 1028, + 'XILPM_RESET_GEM0' : 1029, + 'XILPM_RESET_GEM1' : 1030, + 'XILPM_RESET_GEM2' : 1031, + 'XILPM_RESET_GEM3' : 1032, + 'XILPM_RESET_QSPI' : 1033, + 'XILPM_RESET_UART0' : 1034, + 'XILPM_RESET_UART1' : 1035, + 'XILPM_RESET_SPI0' : 1036, + 'XILPM_RESET_SPI1' : 1037, + 'XILPM_RESET_SDIO0' : 1038, + 'XILPM_RESET_SDIO1' : 1039, + 'XILPM_RESET_CAN0' : 1040, + 'XILPM_RESET_CAN1' : 1041, + 'XILPM_RESET_I2C0' : 1042, + 'XILPM_RESET_I2C1' : 1043, + 'XILPM_RESET_TTC0' : 1044, + 'XILPM_RESET_TTC1' : 1045, + 'XILPM_RESET_TTC2' : 1046, + 'XILPM_RESET_TTC3' : 1047, + 'XILPM_RESET_SWDT_CRL' : 1048, + 'XILPM_RESET_NAND' : 1049, + 'XILPM_RESET_ADMA' : 1050, + 'XILPM_RESET_GPIO' : 1051, + 'XILPM_RESET_IOU_CC' : 1052, + 'XILPM_RESET_TIMESTAMP' : 1053, + 'XILPM_RESET_RPU_R50' : 1054, + 'XILPM_RESET_RPU_R51' : 1055, + 'XILPM_RESET_RPU_AMBA' : 1056, + 'XILPM_RESET_OCM' : 1057, + 'XILPM_RESET_RPU_PGE' : 1058, + 'XILPM_RESET_USB0_CORERESET' : 1059, + 'XILPM_RESET_USB1_CORERESET' : 1060, + 'XILPM_RESET_USB0_HIBERRESET' : 1061, + 'XILPM_RESET_USB1_HIBERRESET' : 1062, + 'XILPM_RESET_USB0_APB' : 1063, + 'XILPM_RESET_USB1_APB' : 1064, + 'XILPM_RESET_IPI' : 1065, + 'XILPM_RESET_APM_LPD' : 1066, + 'XILPM_RESET_RTC' : 1067, + 'XILPM_RESET_SYSMON' : 1068, + 'XILPM_RESET_AFI_FM6' : 1069, + 'XILPM_RESET_LPD_SWDT' : 1070, + 'XILPM_RESET_FPD' : 1071, + 'XILPM_RESET_RPU_DBG1' : 1072, + 'XILPM_RESET_RPU_DBG0' : 1073, + 'XILPM_RESET_DBG_LPD' : 1074, + 'XILPM_RESET_DBG_FPD' : 1075, + 'XILPM_RESET_APLL' : 1076, + 'XILPM_RESET_DPLL' : 1077, + 'XILPM_RESET_VPLL' : 1078, + 'XILPM_RESET_IOPLL' : 1079, + 'XILPM_RESET_RPLL' : 1080, + 'XILPM_RESET_GPO3_PL_0' : 1081, + 'XILPM_RESET_GPO3_PL_1' : 1082, + 'XILPM_RESET_GPO3_PL_2' : 1083, + 'XILPM_RESET_GPO3_PL_3' : 1084, + 'XILPM_RESET_GPO3_PL_4' : 1085, + 'XILPM_RESET_GPO3_PL_5' : 1086, + 'XILPM_RESET_GPO3_PL_6' : 1087, + 'XILPM_RESET_GPO3_PL_7' : 1088, + 'XILPM_RESET_GPO3_PL_8' : 1089, + 'XILPM_RESET_GPO3_PL_9' : 1090, + 'XILPM_RESET_GPO3_PL_10' : 1091, + 'XILPM_RESET_GPO3_PL_11' : 1092, + 'XILPM_RESET_GPO3_PL_12' : 1093, + 'XILPM_RESET_GPO3_PL_13' : 1094, + 'XILPM_RESET_GPO3_PL_14' : 1095, + 'XILPM_RESET_GPO3_PL_15' : 1096, + 'XILPM_RESET_GPO3_PL_16' : 1097, + 'XILPM_RESET_GPO3_PL_17' : 1098, + 'XILPM_RESET_GPO3_PL_18' : 1099, + 'XILPM_RESET_GPO3_PL_19' : 1100, + 'XILPM_RESET_GPO3_PL_20' : 1101, + 'XILPM_RESET_GPO3_PL_21' : 1102, + 'XILPM_RESET_GPO3_PL_22' : 1103, + 'XILPM_RESET_GPO3_PL_23' : 1104, + 'XILPM_RESET_GPO3_PL_24' : 1105, + 'XILPM_RESET_GPO3_PL_25' : 1106, + 'XILPM_RESET_GPO3_PL_26' : 1107, + 'XILPM_RESET_GPO3_PL_27' : 1108, + 'XILPM_RESET_GPO3_PL_28' : 1109, + 'XILPM_RESET_GPO3_PL_29' : 1110, + 'XILPM_RESET_GPO3_PL_30' : 1111, + 'XILPM_RESET_GPO3_PL_31' : 1112, + 'XILPM_RESET_RPU_LS' : 1113, + 'XILPM_RESET_PS_ONLY' : 1114, + 'XILPM_RESET_PL' : 1115, + 'XILPM_RESET_GPIO5_EMIO_92' : 1116, + 'XILPM_RESET_GPIO5_EMIO_93' : 1117, + 'XILPM_RESET_GPIO5_EMIO_94' : 1118, + 'XILPM_RESET_GPIO5_EMIO_95' : 1119, + + 'PM_CONFIG_MASTER_SECTION_ID' : 0x101, + 'PM_CONFIG_SLAVE_SECTION_ID' : 0x102, + 'PM_CONFIG_PREALLOC_SECTION_ID' : 0x103, + 'PM_CONFIG_POWER_SECTION_ID' : 0x104, + 'PM_CONFIG_RESET_SECTION_ID' : 0x105, + 'PM_CONFIG_SHUTDOWN_SECTION_ID' : 0x106, + 'PM_CONFIG_SET_CONFIG_SECTION_ID' : 0x107, + 'PM_CONFIG_GPO_SECTION_ID' : 0x108, + + 'PM_SLAVE_FLAG_IS_SHAREABLE' : 0x1, + 'PM_MASTER_USING_SLAVE_MASK' : 0x2, + + 'PM_CONFIG_GPO1_MIO_PIN_34_MAP' : (1 << 10), + 'PM_CONFIG_GPO1_MIO_PIN_35_MAP' : (1 << 11), + 'PM_CONFIG_GPO1_MIO_PIN_36_MAP' : (1 << 12), + 'PM_CONFIG_GPO1_MIO_PIN_37_MAP' : (1 << 13), + + 'PM_CONFIG_GPO1_BIT_2_MASK' : (1 << 2), + 'PM_CONFIG_GPO1_BIT_3_MASK' : (1 << 3), + 'PM_CONFIG_GPO1_BIT_4_MASK' : (1 << 4), + 'PM_CONFIG_GPO1_BIT_5_MASK' : (1 << 5), + + 'SUSPEND_TIMEOUT' : 0xFFFFFFFF, + + 'PM_CONFIG_IPI_PSU_CORTEXA53_0_MASK' : 0x00000001, + 'PM_CONFIG_IPI_PSU_CORTEXR5_0_MASK' : 0x00000100, + 'PM_CONFIG_IPI_PSU_CORTEXR5_1_MASK' : 0x00000200, +} + +in_file = open(args.in_file, mode='r') +out_file = open(args.out_file, mode='wb') + +num_re = re.compile(r"^([0-9]+)U?$") +const_re = re.compile(r"^([A-Z_][A-Z0-9_]*)$") + +def process_item(item): + logging.debug("* ITEM " + item) + + value = 0 + for item in item.split('|'): + item = item.strip() + + num_match = num_re .match(item) + const_match = const_re.match(item) + + if num_match: + num = int(num_match.group(1)) + logging.debug(" - num " + str(num)) + value |= num + elif const_match: + name = const_match.group(1) + if not name in pm_define: + sys.stderr.write("Unknown define " + name + "!\n") + exit(1) + num = pm_define[name] + logging.debug(" - def " + hex(num)) + value |= num + + logging.debug(" = res " + hex(value)) + out_file.write(struct.pack(' Date: Fri, 24 May 2019 15:40:01 +0200 Subject: [PATCH 05/22] arm64: zynqmp: xil_io.h: declare functions as static Fixes sparse warnings when building zynqmp defconfigs: ./board/xilinx/zynqmp/xil_io.h:12:6: warning: symbol 'Xil_Out32' was not declared. Should it be static? ./board/xilinx/zynqmp/xil_io.h:17:5: warning: symbol 'Xil_In32' was not declared. Should it be static? ./board/xilinx/zynqmp/xil_io.h:22:6: warning: symbol 'usleep' was not declared. Should it be static? Also add __maybe_unused to usleep() since it is not used by minimized psu_init_gpl.c files, so it would warn as "defined but not used". Signed-off-by: Luca Ceresoli Signed-off-by: Michal Simek --- board/xilinx/zynqmp/xil_io.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/board/xilinx/zynqmp/xil_io.h b/board/xilinx/zynqmp/xil_io.h index c476c902eb..1c1bf32ada 100644 --- a/board/xilinx/zynqmp/xil_io.h +++ b/board/xilinx/zynqmp/xil_io.h @@ -9,17 +9,17 @@ #define xil_printf(...) -void Xil_Out32(unsigned long addr, unsigned long val) +static void Xil_Out32(unsigned long addr, unsigned long val) { writel(val, addr); } -int Xil_In32(unsigned long addr) +static int Xil_In32(unsigned long addr) { return readl(addr); } -void usleep(u32 sleep) +static void __maybe_unused usleep(u32 sleep) { udelay(sleep); } From 84a2c83263ff1a82ea9faf1fb2764e17a9de1bc3 Mon Sep 17 00:00:00 2001 From: Luca Ceresoli Date: Fri, 24 May 2019 15:40:02 +0200 Subject: [PATCH 06/22] arm64: zynqmp: add tool to minimize psu_init_gpl.c files This script transforms a pair of psu_init_gpl.c and .h files produced by the Xilinx Vivado tool for ZynqMP into a smaller psu_init_gpl.c file that is almost checkpatch compliant. Based on a script by Michal Simek. Signed-off-by: Luca Ceresoli Signed-off-by: Michal Simek --- tools/zynqmp_psu_init_minimize.sh | 145 ++++++++++++++++++++++++++++++ 1 file changed, 145 insertions(+) create mode 100755 tools/zynqmp_psu_init_minimize.sh diff --git a/tools/zynqmp_psu_init_minimize.sh b/tools/zynqmp_psu_init_minimize.sh new file mode 100755 index 0000000000..b0a07f9080 --- /dev/null +++ b/tools/zynqmp_psu_init_minimize.sh @@ -0,0 +1,145 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0+ +# Copyright (C) 2018 Michal Simek +# Copyright (C) 2019 Luca Ceresoli + +usage() +{ + cat </ + +Notes: INPUT_DIR must contain both .c and .h files. + If INPUT_DIR and OUTPUT_DIR are the same directory, + psu_init_gpl.c will be overwritten. + +EOF +} + +set -o errexit -o errtrace +set -o nounset + +if [ $# -ne 2 ] +then + usage >&2 + exit 1 +fi + +IN="${1}/psu_init_gpl.c" +OUT="${2}/psu_init_gpl.c" +TMP=$(mktemp /tmp/psu_init_gpl.XXXXXX) +trap "rm ${TMP}" ERR + +# Step through a temp file to allow both $IN!=$OUT and $IN==$OUT +sed -e '/sleep.h/d' \ + -e '/xil_io.h/d' \ + ${IN} >${TMP} +cp ${TMP} ${OUT} + +# preprocess to expand defines, then remove cpp lines starting with '#' +gcc -I${1} -E ${OUT} -o ${TMP} +sed '/^#/d' ${TMP} >${OUT} + +# Remove trivial code before psu_pll_init_data() +sed -ni '/psu_pll_init_data/,$p' ${OUT} + +# Functions are lowercase in U-Boot, rename them +sed -i 's/PSU_Mask_Write/psu_mask_write/g' ${OUT} +sed -i 's/mask_pollOnValue/mask_pollonvalue/g' ${OUT} +sed -i 's/RegValue/regvalue/g' ${OUT} +sed -i 's/MaskStatus/maskstatus/g' ${OUT} + +sed -i '/&= psu_peripherals_powerdwn_data()/d' ${OUT} + +FUNCS_TO_REMOVE="psu_protection +psu_..._protection +psu_init_xppu_aper_ram +mask_delay(u32 +mask_read(u32 +dpll_prog +mask_poll(u32 +mask_pollonvalue(u32 +psu_ps_pl_reset_config_data +psu_ps_pl_isolation_removal_data +psu_apply_master_tz +psu_post_config_data +psu_post_config_data +psu_peripherals_powerdwn_data +psu_init_ddr_self_refresh +xmpu +xppu +" +for i in $FUNCS_TO_REMOVE; do +sed -i "/$i/,/^}$/d" ${OUT} +done + +scripts/Lindent ${OUT} + +# Prepend 'static' to internal functions +sed -i 's/^.*data(void)$/static &/g' ${OUT} +sed -i 's/^.*psu_afi_config(void)$/static &/g' ${OUT} +sed -i 's/^void init_peripheral/static &/g' ${OUT} +sed -i 's/^int serdes/static &/g' ${OUT} +sed -i 's/^int init_serdes/static &/g' ${OUT} +sed -i 's/^unsigned long /static &/g' ${OUT} + +sed -i 's/()$/(void)/g' ${OUT} +sed -i 's/0X/0x/g' ${OUT} + +# Add header +cat << EOF >${TMP} +// SPDX-License-Identifier: GPL-2.0+ +/* + * (c) Copyright 2015 Xilinx, Inc. All rights reserved. + */ + +#include +#include + +EOF + +cat ${OUT} >>${TMP} +cp ${TMP} ${OUT} + +# Temporarily convert newlines to do some mangling across lines +tr "\n" "\r" <${OUT} >${TMP} + +# Cleanup empty loops. E.g.: +# |while (e) {| +# | | ==> |while (e)| +# | } | | ; | +# | | +sed -i -r 's| \{\r+(\t*)\}\r\r|\n\1\t;\n|g' ${TMP} + +# Remove empty line between variable declaration +sed -i -r 's|\r(\r\t(unsigned )?int )|\1|g' ${TMP} + +# Remove empty lines at function beginning/end +sed -i -e 's|\r{\r\r|\r{\r|g' ${TMP} +sed -i -e 's|\r\r}\r|\r}\r|g' ${TMP} + +# Remove empty lines after '{' line +sed -i -e 's| {\r\r| {\r|g' ${TMP} + +# Remove braces {} around single statement blocks. E.g.: +# | while (e) { | | while (e) | +# | stg(); | => | stg();| +# | } | +sed -i -r 's| \{(\r[^\r]*;)\r\t*\}|\1|g' ${TMP} + +# Remove Unnecessary parentheses around 'n_code <= 0x3C' and similar. E.g.: +# if ((p_code >= 0x26) && ...) -> if (p_code >= 0x26 && ...) +sed -i -r 's|\((._code .= [x[:xdigit:]]+)\)|\1|g' ${TMP} + +# Convert back newlines +tr "\r" "\n" <${TMP} >${OUT} + +rm ${TMP} From ce9e4e0d52354902f571f961b187c3d0f7eb66a5 Mon Sep 17 00:00:00 2001 From: "Robert P. J. Day" Date: Tue, 28 May 2019 11:33:27 -0400 Subject: [PATCH 07/22] cmd: fpga: correct typo, capitalize "Xilinx" A couple minor tweaks to printed strings in cmd/fpga.c. Signed-off-by: Robert P. J. Day Signed-off-by: Michal Simek --- cmd/fpga.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/fpga.c b/cmd/fpga.c index bc48abdd6d..eba989a730 100644 --- a/cmd/fpga.c +++ b/cmd/fpga.c @@ -458,7 +458,7 @@ U_BOOT_CMD(fpga, 6, 1, do_fpga_wrapper, "0-device key, 1-user key, 2-no encryption.\n" "The optional Userkey address specifies from which address key\n" "has to be used for decryption if user key is selected.\n" - "NOTE: the sceure bitstream has to be created using xilinx\n" + "NOTE: the secure bitstream has to be created using Xilinx\n" "bootgen tool only.\n" #endif ); From 5456935a1da3714f5e51cbceac224725ca587e83 Mon Sep 17 00:00:00 2001 From: Anton Gerasimov Date: Tue, 4 Jun 2019 22:10:49 +0200 Subject: [PATCH 08/22] ARM: zynq: Add configuration for Z-turn board Basic (PS-only) configuration based on Vivado board files by Sergiusz Bazanski Signed-off-by: Anton Gerasimov --- board/xilinx/zynq/zynq-zturn/ps7_init_gpl.c | 281 ++++++++++++++++++++ 1 file changed, 281 insertions(+) create mode 100644 board/xilinx/zynq/zynq-zturn/ps7_init_gpl.c diff --git a/board/xilinx/zynq/zynq-zturn/ps7_init_gpl.c b/board/xilinx/zynq/zynq-zturn/ps7_init_gpl.c new file mode 100644 index 0000000000..d4f0ee796f --- /dev/null +++ b/board/xilinx/zynq/zynq-zturn/ps7_init_gpl.c @@ -0,0 +1,281 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) Xilinx, Inc. + */ + +#include + +static unsigned long ps7_pll_init_data[] = { + EMIT_WRITE(0xF8000008, 0x0000DF0DU), + EMIT_MASKWRITE(0xF8000110, 0x003FFFF0U, 0x000FA220U), + EMIT_MASKWRITE(0xF8000100, 0x0007F000U, 0x00028000U), + EMIT_MASKWRITE(0xF8000100, 0x00000010U, 0x00000010U), + EMIT_MASKWRITE(0xF8000100, 0x00000001U, 0x00000001U), + EMIT_MASKWRITE(0xF8000100, 0x00000001U, 0x00000000U), + EMIT_MASKPOLL(0xF800010C, 0x00000001U), + EMIT_MASKWRITE(0xF8000100, 0x00000010U, 0x00000000U), + EMIT_MASKWRITE(0xF8000120, 0x1F003F30U, 0x1F000200U), + EMIT_MASKWRITE(0xF8000114, 0x003FFFF0U, 0x0012C220U), + EMIT_MASKWRITE(0xF8000104, 0x0007F000U, 0x00020000U), + EMIT_MASKWRITE(0xF8000104, 0x00000010U, 0x00000010U), + EMIT_MASKWRITE(0xF8000104, 0x00000001U, 0x00000001U), + EMIT_MASKWRITE(0xF8000104, 0x00000001U, 0x00000000U), + EMIT_MASKPOLL(0xF800010C, 0x00000002U), + EMIT_MASKWRITE(0xF8000104, 0x00000010U, 0x00000000U), + EMIT_MASKWRITE(0xF8000124, 0xFFF00003U, 0x0C200003U), + EMIT_MASKWRITE(0xF8000118, 0x003FFFF0U, 0x001452C0U), + EMIT_MASKWRITE(0xF8000108, 0x0007F000U, 0x0001E000U), + EMIT_MASKWRITE(0xF8000108, 0x00000010U, 0x00000010U), + EMIT_MASKWRITE(0xF8000108, 0x00000001U, 0x00000001U), + EMIT_MASKWRITE(0xF8000108, 0x00000001U, 0x00000000U), + EMIT_MASKPOLL(0xF800010C, 0x00000004U), + EMIT_MASKWRITE(0xF8000108, 0x00000010U, 0x00000000U), + EMIT_WRITE(0xF8000004, 0x0000767BU), + EMIT_EXIT(), +}; + +static unsigned long ps7_clock_init_data[] = { + EMIT_WRITE(0xF8000008, 0x0000DF0DU), + EMIT_MASKWRITE(0xF8000128, 0x03F03F01U, 0x00700F01U), + EMIT_MASKWRITE(0xF8000138, 0x00000011U, 0x00000001U), + EMIT_MASKWRITE(0xF8000140, 0x03F03F71U, 0x00100801U), + EMIT_MASKWRITE(0xF800014C, 0x00003F31U, 0x00000501U), + EMIT_MASKWRITE(0xF8000150, 0x00003F33U, 0x00001401U), + EMIT_MASKWRITE(0xF8000154, 0x00003F33U, 0x00000A03U), + EMIT_MASKWRITE(0xF800015C, 0x03F03F33U, 0x00200501U), + EMIT_MASKWRITE(0xF8000160, 0x007F007FU, 0x00000000U), + EMIT_MASKWRITE(0xF8000168, 0x00003F31U, 0x00000501U), + EMIT_MASKWRITE(0xF8000170, 0x03F03F30U, 0x00200500U), + EMIT_MASKWRITE(0xF8000180, 0x03F03F30U, 0x00400500U), + EMIT_MASKWRITE(0xF80001C4, 0x00000001U, 0x00000001U), + EMIT_MASKWRITE(0xF800012C, 0x01FFCCCDU, 0x01FD044DU), + EMIT_WRITE(0xF8000004, 0x0000767BU), + EMIT_EXIT(), +}; + +static unsigned long ps7_ddr_init_data[] = { + EMIT_MASKWRITE(0xF8006000, 0x0001FFFFU, 0x00000080U), + EMIT_MASKWRITE(0xF8006004, 0x0007FFFFU, 0x00001082U), + EMIT_MASKWRITE(0xF8006008, 0x03FFFFFFU, 0x03C0780FU), + EMIT_MASKWRITE(0xF800600C, 0x03FFFFFFU, 0x02001001U), + EMIT_MASKWRITE(0xF8006010, 0x03FFFFFFU, 0x00014001U), + EMIT_MASKWRITE(0xF8006014, 0x001FFFFFU, 0x0004285BU), + EMIT_MASKWRITE(0xF8006018, 0xF7FFFFFFU, 0x44E458D3U), + EMIT_MASKWRITE(0xF800601C, 0xFFFFFFFFU, 0x7282BCE5U), + EMIT_MASKWRITE(0xF8006020, 0x7FDFFFFCU, 0x270872D0U), + EMIT_MASKWRITE(0xF8006024, 0x0FFFFFC3U, 0x00000000U), + EMIT_MASKWRITE(0xF8006028, 0x00003FFFU, 0x00002007U), + EMIT_MASKWRITE(0xF800602C, 0xFFFFFFFFU, 0x00000008U), + EMIT_MASKWRITE(0xF8006030, 0xFFFFFFFFU, 0x00040B30U), + EMIT_MASKWRITE(0xF8006034, 0x13FF3FFFU, 0x000116D4U), + EMIT_MASKWRITE(0xF8006038, 0x00000003U, 0x00000000U), + EMIT_MASKWRITE(0xF800603C, 0x000FFFFFU, 0x00000777U), + EMIT_MASKWRITE(0xF8006040, 0xFFFFFFFFU, 0xFFF00000U), + EMIT_MASKWRITE(0xF8006044, 0x0FFFFFFFU, 0x0F666666U), + EMIT_MASKWRITE(0xF8006048, 0x0003F03FU, 0x0003C008U), + EMIT_MASKWRITE(0xF8006050, 0xFF0F8FFFU, 0x77010800U), + EMIT_MASKWRITE(0xF8006058, 0x00010000U, 0x00000000U), + EMIT_MASKWRITE(0xF800605C, 0x0000FFFFU, 0x00005003U), + EMIT_MASKWRITE(0xF8006060, 0x000017FFU, 0x0000003EU), + EMIT_MASKWRITE(0xF8006064, 0x00021FE0U, 0x00020000U), + EMIT_MASKWRITE(0xF8006068, 0x03FFFFFFU, 0x00284141U), + EMIT_MASKWRITE(0xF800606C, 0x0000FFFFU, 0x00001610U), + EMIT_MASKWRITE(0xF8006078, 0x03FFFFFFU, 0x00466111U), + EMIT_MASKWRITE(0xF800607C, 0x000FFFFFU, 0x00032222U), + EMIT_MASKWRITE(0xF80060A4, 0xFFFFFFFFU, 0x10200802U), + EMIT_MASKWRITE(0xF80060A8, 0x0FFFFFFFU, 0x0690CB73U), + EMIT_MASKWRITE(0xF80060AC, 0x000001FFU, 0x000001FEU), + EMIT_MASKWRITE(0xF80060B0, 0x1FFFFFFFU, 0x1CFFFFFFU), + EMIT_MASKWRITE(0xF80060B4, 0x00000200U, 0x00000200U), + EMIT_MASKWRITE(0xF80060B8, 0x01FFFFFFU, 0x00200066U), + EMIT_MASKWRITE(0xF80060C4, 0x00000003U, 0x00000000U), + EMIT_MASKWRITE(0xF80060C8, 0x000000FFU, 0x00000000U), + EMIT_MASKWRITE(0xF80060DC, 0x00000001U, 0x00000000U), + EMIT_MASKWRITE(0xF80060F0, 0x0000FFFFU, 0x00000000U), + EMIT_MASKWRITE(0xF80060F4, 0x0000000FU, 0x00000008U), + EMIT_MASKWRITE(0xF8006114, 0x000000FFU, 0x00000000U), + EMIT_MASKWRITE(0xF8006118, 0x7FFFFFCFU, 0x40000001U), + EMIT_MASKWRITE(0xF800611C, 0x7FFFFFCFU, 0x40000001U), + EMIT_MASKWRITE(0xF8006120, 0x7FFFFFCFU, 0x40000001U), + EMIT_MASKWRITE(0xF8006124, 0x7FFFFFCFU, 0x40000001U), + EMIT_MASKWRITE(0xF800612C, 0x000FFFFFU, 0x0002A81FU), + EMIT_MASKWRITE(0xF8006130, 0x000FFFFFU, 0x00029822U), + EMIT_MASKWRITE(0xF8006134, 0x000FFFFFU, 0x00026C10U), + EMIT_MASKWRITE(0xF8006138, 0x000FFFFFU, 0x00026013U), + EMIT_MASKWRITE(0xF8006140, 0x000FFFFFU, 0x00000035U), + EMIT_MASKWRITE(0xF8006144, 0x000FFFFFU, 0x00000035U), + EMIT_MASKWRITE(0xF8006148, 0x000FFFFFU, 0x00000035U), + EMIT_MASKWRITE(0xF800614C, 0x000FFFFFU, 0x00000035U), + EMIT_MASKWRITE(0xF8006154, 0x000FFFFFU, 0x0000009FU), + EMIT_MASKWRITE(0xF8006158, 0x000FFFFFU, 0x000000A2U), + EMIT_MASKWRITE(0xF800615C, 0x000FFFFFU, 0x00000090U), + EMIT_MASKWRITE(0xF8006160, 0x000FFFFFU, 0x00000093U), + EMIT_MASKWRITE(0xF8006168, 0x001FFFFFU, 0x000000FFU), + EMIT_MASKWRITE(0xF800616C, 0x001FFFFFU, 0x000000FBU), + EMIT_MASKWRITE(0xF8006170, 0x001FFFFFU, 0x000000F0U), + EMIT_MASKWRITE(0xF8006174, 0x001FFFFFU, 0x000000EDU), + EMIT_MASKWRITE(0xF800617C, 0x000FFFFFU, 0x000000DFU), + EMIT_MASKWRITE(0xF8006180, 0x000FFFFFU, 0x000000E2U), + EMIT_MASKWRITE(0xF8006184, 0x000FFFFFU, 0x000000D0U), + EMIT_MASKWRITE(0xF8006188, 0x000FFFFFU, 0x000000D3U), + EMIT_MASKWRITE(0xF8006190, 0x6FFFFEFEU, 0x00040080U), + EMIT_MASKWRITE(0xF8006194, 0x000FFFFFU, 0x0001FC82U), + EMIT_MASKWRITE(0xF8006204, 0xFFFFFFFFU, 0x00000000U), + EMIT_MASKWRITE(0xF8006208, 0x000703FFU, 0x000003FFU), + EMIT_MASKWRITE(0xF800620C, 0x000703FFU, 0x000003FFU), + EMIT_MASKWRITE(0xF8006210, 0x000703FFU, 0x000003FFU), + EMIT_MASKWRITE(0xF8006214, 0x000703FFU, 0x000003FFU), + EMIT_MASKWRITE(0xF8006218, 0x000F03FFU, 0x000003FFU), + EMIT_MASKWRITE(0xF800621C, 0x000F03FFU, 0x000003FFU), + EMIT_MASKWRITE(0xF8006220, 0x000F03FFU, 0x000003FFU), + EMIT_MASKWRITE(0xF8006224, 0x000F03FFU, 0x000003FFU), + EMIT_MASKWRITE(0xF80062A8, 0x00000FF5U, 0x00000000U), + EMIT_MASKWRITE(0xF80062AC, 0xFFFFFFFFU, 0x00000000U), + EMIT_MASKWRITE(0xF80062B0, 0x003FFFFFU, 0x00005125U), + EMIT_MASKWRITE(0xF80062B4, 0x0003FFFFU, 0x000012A8U), + EMIT_MASKPOLL(0xF8000B74, 0x00002000U), + EMIT_MASKWRITE(0xF8006000, 0x0001FFFFU, 0x00000081U), + EMIT_MASKPOLL(0xF8006054, 0x00000007U), + EMIT_EXIT(), +}; + +static unsigned long ps7_mio_init_data[] = { + EMIT_WRITE(0xF8000008, 0x0000DF0DU), + EMIT_MASKWRITE(0xF8000B40, 0x00000FFFU, 0x00000600U), + EMIT_MASKWRITE(0xF8000B44, 0x00000FFFU, 0x00000600U), + EMIT_MASKWRITE(0xF8000B48, 0x00000FFFU, 0x00000672U), + EMIT_MASKWRITE(0xF8000B4C, 0x00000FFFU, 0x00000672U), + EMIT_MASKWRITE(0xF8000B50, 0x00000FFFU, 0x00000674U), + EMIT_MASKWRITE(0xF8000B54, 0x00000FFFU, 0x00000674U), + EMIT_MASKWRITE(0xF8000B58, 0x00000FFFU, 0x00000600U), + EMIT_MASKWRITE(0xF8000B5C, 0xFFFFFFFFU, 0x0018C61CU), + EMIT_MASKWRITE(0xF8000B60, 0xFFFFFFFFU, 0x00F9861CU), + EMIT_MASKWRITE(0xF8000B64, 0xFFFFFFFFU, 0x00F9861CU), + EMIT_MASKWRITE(0xF8000B68, 0xFFFFFFFFU, 0x00F9861CU), + EMIT_MASKWRITE(0xF8000B6C, 0x00007FFFU, 0x00000260U), + EMIT_MASKWRITE(0xF8000B70, 0x00000001U, 0x00000001U), + EMIT_MASKWRITE(0xF8000B70, 0x00000021U, 0x00000020U), + EMIT_MASKWRITE(0xF8000B70, 0x07FEFFFFU, 0x00000823U), + EMIT_MASKWRITE(0xF8000700, 0x00003FFFU, 0x00001600U), + EMIT_MASKWRITE(0xF8000704, 0x00003FFFU, 0x00000602U), + EMIT_MASKWRITE(0xF8000708, 0x00003FFFU, 0x00000602U), + EMIT_MASKWRITE(0xF800070C, 0x00003FFFU, 0x00000602U), + EMIT_MASKWRITE(0xF8000710, 0x00003FFFU, 0x00000602U), + EMIT_MASKWRITE(0xF8000714, 0x00003FFFU, 0x00000602U), + EMIT_MASKWRITE(0xF8000718, 0x00003FFFU, 0x00000602U), + EMIT_MASKWRITE(0xF800071C, 0x00003FFFU, 0x00000600U), + EMIT_MASKWRITE(0xF8000720, 0x00003FFFU, 0x00000602U), + EMIT_MASKWRITE(0xF8000724, 0x00003FFFU, 0x00000600U), + EMIT_MASKWRITE(0xF8000728, 0x00003FFFU, 0x000016E1U), + EMIT_MASKWRITE(0xF800072C, 0x00003FFFU, 0x000016E0U), + EMIT_MASKWRITE(0xF8000730, 0x00003FFFU, 0x00001640U), + EMIT_MASKWRITE(0xF8000734, 0x00003FFFU, 0x00001640U), + EMIT_MASKWRITE(0xF8000738, 0x00003FFFU, 0x00001621U), + EMIT_MASKWRITE(0xF800073C, 0x00003FFFU, 0x00001620U), + EMIT_MASKWRITE(0xF8000740, 0x00003FFFU, 0x00001202U), + EMIT_MASKWRITE(0xF8000744, 0x00003FFFU, 0x00001202U), + EMIT_MASKWRITE(0xF8000748, 0x00003FFFU, 0x00001202U), + EMIT_MASKWRITE(0xF800074C, 0x00003FFFU, 0x00001202U), + EMIT_MASKWRITE(0xF8000750, 0x00003FFFU, 0x00001202U), + EMIT_MASKWRITE(0xF8000754, 0x00003FFFU, 0x00001202U), + EMIT_MASKWRITE(0xF8000758, 0x00003FFFU, 0x00001203U), + EMIT_MASKWRITE(0xF800075C, 0x00003FFFU, 0x00001203U), + EMIT_MASKWRITE(0xF8000760, 0x00003FFFU, 0x00001203U), + EMIT_MASKWRITE(0xF8000764, 0x00003FFFU, 0x00001203U), + EMIT_MASKWRITE(0xF8000768, 0x00003FFFU, 0x00001203U), + EMIT_MASKWRITE(0xF800076C, 0x00003FFFU, 0x00001203U), + EMIT_MASKWRITE(0xF8000770, 0x00003FFFU, 0x00001204U), + EMIT_MASKWRITE(0xF8000774, 0x00003FFFU, 0x00001205U), + EMIT_MASKWRITE(0xF8000778, 0x00003FFFU, 0x00001204U), + EMIT_MASKWRITE(0xF800077C, 0x00003FFFU, 0x00001205U), + EMIT_MASKWRITE(0xF8000780, 0x00003FFFU, 0x00001204U), + EMIT_MASKWRITE(0xF8000784, 0x00003FFFU, 0x00001204U), + EMIT_MASKWRITE(0xF8000788, 0x00003FFFU, 0x00001204U), + EMIT_MASKWRITE(0xF800078C, 0x00003FFFU, 0x00001204U), + EMIT_MASKWRITE(0xF8000790, 0x00003FFFU, 0x00001205U), + EMIT_MASKWRITE(0xF8000794, 0x00003FFFU, 0x00001204U), + EMIT_MASKWRITE(0xF8000798, 0x00003FFFU, 0x00001204U), + EMIT_MASKWRITE(0xF800079C, 0x00003FFFU, 0x00001204U), + EMIT_MASKWRITE(0xF80007A0, 0x00003FFFU, 0x00001280U), + EMIT_MASKWRITE(0xF80007A4, 0x00003FFFU, 0x00001280U), + EMIT_MASKWRITE(0xF80007A8, 0x00003FFFU, 0x00001280U), + EMIT_MASKWRITE(0xF80007AC, 0x00003FFFU, 0x00001280U), + EMIT_MASKWRITE(0xF80007B0, 0x00003FFFU, 0x00001280U), + EMIT_MASKWRITE(0xF80007B4, 0x00003FFFU, 0x00001280U), + EMIT_MASKWRITE(0xF80007B8, 0x00003F01U, 0x00000201U), + EMIT_MASKWRITE(0xF80007BC, 0x00003F01U, 0x00000201U), + EMIT_MASKWRITE(0xF80007C0, 0x00003FFFU, 0x000012E0U), + EMIT_MASKWRITE(0xF80007C4, 0x00003FFFU, 0x000012E1U), + EMIT_MASKWRITE(0xF80007C8, 0x00003FFFU, 0x00000200U), + EMIT_MASKWRITE(0xF80007CC, 0x00003FFFU, 0x00000200U), + EMIT_MASKWRITE(0xF80007D0, 0x00003FFFU, 0x00001280U), + EMIT_MASKWRITE(0xF80007D4, 0x00003FFFU, 0x00001280U), + EMIT_MASKWRITE(0xF8000830, 0x003F003FU, 0x002E002FU), + EMIT_WRITE(0xF8000004, 0x0000767BU), + EMIT_EXIT(), +}; + +static unsigned long ps7_peripherals_init_data[] = { + EMIT_WRITE(0xF8000008, 0x0000DF0DU), + EMIT_MASKWRITE(0xF8000B48, 0x00000180U, 0x00000180U), + EMIT_MASKWRITE(0xF8000B4C, 0x00000180U, 0x00000180U), + EMIT_MASKWRITE(0xF8000B50, 0x00000180U, 0x00000180U), + EMIT_MASKWRITE(0xF8000B54, 0x00000180U, 0x00000180U), + EMIT_WRITE(0xF8000004, 0x0000767BU), + EMIT_MASKWRITE(0xE0001034, 0x000000FFU, 0x00000006U), + EMIT_MASKWRITE(0xE0001018, 0x0000FFFFU, 0x0000007CU), + EMIT_MASKWRITE(0xE0001000, 0x000001FFU, 0x00000017U), + EMIT_MASKWRITE(0xE0001004, 0x000003FFU, 0x00000020U), + EMIT_MASKWRITE(0xE0000034, 0x000000FFU, 0x00000006U), + EMIT_MASKWRITE(0xE0000018, 0x0000FFFFU, 0x0000007CU), + EMIT_MASKWRITE(0xE0000000, 0x000001FFU, 0x00000017U), + EMIT_MASKWRITE(0xE0000004, 0x000003FFU, 0x00000020U), + EMIT_MASKWRITE(0xE000D000, 0x00080000U, 0x00080000U), + EMIT_MASKWRITE(0xF8007000, 0x20000000U, 0x00000000U), + EMIT_MASKWRITE(0xE000A244, 0x003FFFFFU, 0x00080000U), + EMIT_MASKWRITE(0xE000A00C, 0x003F003FU, 0x00370008U), + EMIT_MASKWRITE(0xE000A248, 0x003FFFFFU, 0x00080000U), + EMIT_MASKWRITE(0xE000A00C, 0x003F003FU, 0x00370000U), + EMIT_MASKDELAY(0xF8F00200, 1), + EMIT_MASKWRITE(0xE000A00C, 0x003F003FU, 0x00370008U), + EMIT_EXIT(), +}; + +static unsigned long ps7_post_config_0[] = { + EMIT_WRITE(0xF8000008, 0x0000DF0DU), + EMIT_MASKWRITE(0xF8000900, 0x0000000FU, 0x0000000FU), + EMIT_MASKWRITE(0xF8000240, 0xFFFFFFFFU, 0x00000000U), + EMIT_WRITE(0xF8000004, 0x0000767BU), + EMIT_EXIT(), +}; + +int ps7_post_config(void) +{ + return ps7_config(ps7_post_config_0); +} + +int ps7_init(void) +{ + int ret; + + ret = ps7_config(ps7_mio_init_data); + if (ret != PS7_INIT_SUCCESS) + return ret; + + ret = ps7_config(ps7_pll_init_data); + if (ret != PS7_INIT_SUCCESS) + return ret; + + ret = ps7_config(ps7_clock_init_data); + if (ret != PS7_INIT_SUCCESS) + return ret; + + ret = ps7_config(ps7_ddr_init_data); + if (ret != PS7_INIT_SUCCESS) + return ret; + + ret = ps7_config(ps7_peripherals_init_data); + if (ret != PS7_INIT_SUCCESS) + return ret; + return PS7_INIT_SUCCESS; +} From 7f492f3c11ff29467f4bc8bde24b81e18324d184 Mon Sep 17 00:00:00 2001 From: Luca Ceresoli Date: Tue, 11 Jun 2019 18:39:40 +0200 Subject: [PATCH 09/22] tools: zynqmp_psu_init_minimize.sh: fix return lines coding style Remove unneeded parenthess around return value. E.g.: return (0); -> return 0; Signed-off-by: Luca Ceresoli Signed-off-by: Michal Simek --- tools/zynqmp_psu_init_minimize.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/zynqmp_psu_init_minimize.sh b/tools/zynqmp_psu_init_minimize.sh index b0a07f9080..384bb56e1a 100755 --- a/tools/zynqmp_psu_init_minimize.sh +++ b/tools/zynqmp_psu_init_minimize.sh @@ -94,6 +94,9 @@ sed -i 's/^unsigned long /static &/g' ${OUT} sed -i 's/()$/(void)/g' ${OUT} sed -i 's/0X/0x/g' ${OUT} +# return (0) -> return 0 +sed -ri 's/return \(([0-9]+)\)/return \1/g' ${OUT} + # Add header cat << EOF >${TMP} // SPDX-License-Identifier: GPL-2.0+ From ac80ac09c84fda3b5ae2df865ee9f2acf37a91db Mon Sep 17 00:00:00 2001 From: Luca Ceresoli Date: Tue, 11 Jun 2019 18:39:41 +0200 Subject: [PATCH 10/22] arm64: zynqmp: add support for Avnet UltraZed-EV Starter Kit Avnet UltraZed-EV Starter Kit is composed by the UltraZed-EV SoM and the only publicly-available compatible carrier card. The SoM is based on the EV version of the Xilinx ZynqMP SoC+FPGA. The psu_init_gpl.c file has been generated from the board definition files at [0] using Vivado 2018.3 and then minimized by tools/zynqmp_psu_init_minimize.sh. Manually removed serdes init code since it is not mentioned in device tree and fixed a checkpatch error. [0] https://github.com/Avnet/bdf/tree/3686c9ff7d2f0467fb4fcf39f861b8d6ff183b12/ultrazed_7ev_cc/1.1 Signed-off-by: Luca Ceresoli Signed-off-by: Michal Simek --- arch/arm/dts/Makefile | 1 + ...ultrazedev-cc-v1.0-ultrazedev-som-v1.0.dts | 59 ++ arch/arm/dts/avnet-ultrazedev-som-v1.0.dtsi | 56 ++ .../psu_init_gpl.c | 663 ++++++++++++++++++ ...edev_cc_v1_0_ultrazedev_som_v1_0_defconfig | 64 ++ 5 files changed, 843 insertions(+) create mode 100644 arch/arm/dts/avnet-ultrazedev-cc-v1.0-ultrazedev-som-v1.0.dts create mode 100644 arch/arm/dts/avnet-ultrazedev-som-v1.0.dtsi create mode 100644 board/xilinx/zynqmp/avnet-ultrazedev-cc-v1.0-ultrazedev-som-v1.0/psu_init_gpl.c create mode 100644 configs/avnet_ultrazedev_cc_v1_0_ultrazedev_som_v1_0_defconfig diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index ff181978de..aa94c49f37 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -240,6 +240,7 @@ dtb-$(CONFIG_ARCH_ZYNQ) += \ zynq-zybo-z7.dtb dtb-$(CONFIG_ARCH_ZYNQMP) += \ avnet-ultra96-rev1.dtb \ + avnet-ultrazedev-cc-v1.0-ultrazedev-som-v1.0.dtb \ zynqmp-mini.dtb \ zynqmp-mini-emmc0.dtb \ zynqmp-mini-emmc1.dtb \ diff --git a/arch/arm/dts/avnet-ultrazedev-cc-v1.0-ultrazedev-som-v1.0.dts b/arch/arm/dts/avnet-ultrazedev-cc-v1.0-ultrazedev-som-v1.0.dts new file mode 100644 index 0000000000..ac641ff1a5 --- /dev/null +++ b/arch/arm/dts/avnet-ultrazedev-cc-v1.0-ultrazedev-som-v1.0.dts @@ -0,0 +1,59 @@ +// SPDX-License-Identifier: GPL-2.0+ OR X11 + +/* + * UltraZed-EV Carrier Card v1 (based on the UltraZed-EV SoM) + * http://ultrazed.org/product/ultrazed-ev-carrier-card + */ + +/dts-v1/; + +#include "avnet-ultrazedev-som-v1.0.dtsi" + +/ { + model = "Avnet UltraZed EV Carrier Card v1.0"; + compatible = "avnet,ultrazedev-cc-v1.0-ultrazedev-som-v1.0", + "xlnx,zynqmp"; + chosen { + stdout-path = "serial0:115200n8"; + xlnx,eeprom = &eeprom; + }; + aliases { + ethernet0 = &gem3; + serial0 = &uart0; + }; +}; + +&uart0 { + device_type = "serial"; + status = "okay"; +}; + +&i2c_cc { + /* Microchip 24AA025E48T-I/OT: 2K I2C Serial EEPROM with EUI-48 */ + eeprom: eeprom@51 { + compatible = "atmel,24c02"; + reg = <0x51>; + }; + + /* IDT Versa Clock 5P49V5935B */ + vc5: clock-generator@6a { + compatible = "idt,5p49v5935"; + reg = <0x6a>; + #clock-cells = <1>; + }; +}; + +/* Ethernet RJ-45 */ +&gem3 { + status = "okay"; +}; + +/* microSD card slot */ +&sdhci1 { + status = "okay"; + xlnx,mio_bank = <1>; + clock-frequency = <199998000>; + max-frequency = <50000000>; + no-1-8-v; + disable-wp; +}; diff --git a/arch/arm/dts/avnet-ultrazedev-som-v1.0.dtsi b/arch/arm/dts/avnet-ultrazedev-som-v1.0.dtsi new file mode 100644 index 0000000000..b635db649f --- /dev/null +++ b/arch/arm/dts/avnet-ultrazedev-som-v1.0.dtsi @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: GPL-2.0+ OR X11 + +/* + * UltraZed-EV SoM v1 + * http://ultrazed.org/product/ultrazed-ev + */ + +/dts-v1/; + +#include "zynqmp.dtsi" +#include "zynqmp-clk-ccf.dtsi" + +/ { + model = "Avnet UltraZed EV SoM v1.0"; + compatible = "avnet,ultrazedev-som-v1.0", "xlnx,zynqmp"; + memory { + device_type = "memory"; + reg = <0x0 0x0 0x0 0x80000000>, /* 2 GB @ offset 0 */ + <0x8 0x0 0x0 0x80000000>; /* 2 GB @ offset 32GB */ + }; +}; + +&i2c1 { + clock-frequency = <400000>; + status = "okay"; + + i2cswitch@70 { + compatible = "nxp,pca9543"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x70>; + + /* I2C connected to Carrier Card via JX3A1/JX3C1 */ + i2c_cc: i2c@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + }; + }; +}; + +/* Marvell 88E1512-A0-NNP2I000 Ethernet PHY */ +&gem3 { + phy-mode = "rgmii-id"; + phy-handle = <&gem3phy>; + gem3phy: ethernet-phy@0 { + reg = <0>; + }; +}; + +/* Micron MTFC8GAKAJCN-4M 8 GB eMMC */ +&sdhci0 { + status = "okay"; + xlnx,mio_bank = <0>; + clock-frequency = <199998000>; +}; diff --git a/board/xilinx/zynqmp/avnet-ultrazedev-cc-v1.0-ultrazedev-som-v1.0/psu_init_gpl.c b/board/xilinx/zynqmp/avnet-ultrazedev-cc-v1.0-ultrazedev-som-v1.0/psu_init_gpl.c new file mode 100644 index 0000000000..ac3f716392 --- /dev/null +++ b/board/xilinx/zynqmp/avnet-ultrazedev-cc-v1.0-ultrazedev-som-v1.0/psu_init_gpl.c @@ -0,0 +1,663 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (c) Copyright 2015 Xilinx, Inc. All rights reserved. + */ + +#include +#include + +static unsigned long psu_pll_init_data(void) +{ + psu_mask_write(0xFF5E0034, 0xFE7FEDEFU, 0x7E4B0C62U); + psu_mask_write(0xFF5E0030, 0x00717F00U, 0x00014800U); + psu_mask_write(0xFF5E0030, 0x00000008U, 0x00000008U); + psu_mask_write(0xFF5E0030, 0x00000001U, 0x00000001U); + psu_mask_write(0xFF5E0030, 0x00000001U, 0x00000000U); + mask_poll(0xFF5E0040, 0x00000002U); + psu_mask_write(0xFF5E0030, 0x00000008U, 0x00000000U); + psu_mask_write(0xFF5E0048, 0x00003F00U, 0x00000300U); + psu_mask_write(0xFF5E0108, 0x013F3F07U, 0x01012300U); + psu_mask_write(0xFF5E0024, 0xFE7FEDEFU, 0x7E4B0C82U); + psu_mask_write(0xFF5E0020, 0x00717F00U, 0x00015A00U); + psu_mask_write(0xFF5E0020, 0x00000008U, 0x00000008U); + psu_mask_write(0xFF5E0020, 0x00000001U, 0x00000001U); + psu_mask_write(0xFF5E0020, 0x00000001U, 0x00000000U); + mask_poll(0xFF5E0040, 0x00000001U); + psu_mask_write(0xFF5E0020, 0x00000008U, 0x00000000U); + psu_mask_write(0xFF5E0044, 0x00003F00U, 0x00000300U); + psu_mask_write(0xFD1A0024, 0xFE7FEDEFU, 0x7E4B0C62U); + psu_mask_write(0xFD1A0020, 0x00717F00U, 0x00014200U); + psu_mask_write(0xFD1A0020, 0x00000008U, 0x00000008U); + psu_mask_write(0xFD1A0020, 0x00000001U, 0x00000001U); + psu_mask_write(0xFD1A0020, 0x00000001U, 0x00000000U); + mask_poll(0xFD1A0044, 0x00000001U); + psu_mask_write(0xFD1A0020, 0x00000008U, 0x00000000U); + psu_mask_write(0xFD1A0048, 0x00003F00U, 0x00000300U); + psu_mask_write(0xFD1A0030, 0xFE7FEDEFU, 0x7E4B0C62U); + psu_mask_write(0xFD1A002C, 0x00717F00U, 0x00014800U); + psu_mask_write(0xFD1A002C, 0x00000008U, 0x00000008U); + psu_mask_write(0xFD1A002C, 0x00000001U, 0x00000001U); + psu_mask_write(0xFD1A002C, 0x00000001U, 0x00000000U); + mask_poll(0xFD1A0044, 0x00000002U); + psu_mask_write(0xFD1A002C, 0x00000008U, 0x00000000U); + psu_mask_write(0xFD1A004C, 0x00003F00U, 0x00000300U); + psu_mask_write(0xFD1A003C, 0xFE7FEDEFU, 0x7E4B0C82U); + psu_mask_write(0xFD1A0038, 0x00717F00U, 0x00015A00U); + psu_mask_write(0xFD1A0038, 0x00000008U, 0x00000008U); + psu_mask_write(0xFD1A0038, 0x00000001U, 0x00000001U); + psu_mask_write(0xFD1A0038, 0x00000001U, 0x00000000U); + mask_poll(0xFD1A0044, 0x00000004U); + psu_mask_write(0xFD1A0038, 0x00000008U, 0x00000000U); + psu_mask_write(0xFD1A0050, 0x00003F00U, 0x00000300U); + + return 1; +} + +static unsigned long psu_clock_init_data(void) +{ + psu_mask_write(0xFF5E005C, 0x063F3F07U, 0x06010C00U); + psu_mask_write(0xFF5E0100, 0x013F3F07U, 0x01010600U); + psu_mask_write(0xFF5E0060, 0x023F3F07U, 0x02010600U); + psu_mask_write(0xFF5E004C, 0x023F3F07U, 0x02031900U); + psu_mask_write(0xFF5E0068, 0x013F3F07U, 0x01010C00U); + psu_mask_write(0xFF5E006C, 0x013F3F07U, 0x01010602U); + psu_mask_write(0xFF5E0070, 0x013F3F07U, 0x01010602U); + psu_mask_write(0xFF18030C, 0x00020003U, 0x00000000U); + psu_mask_write(0xFF5E0074, 0x013F3F07U, 0x01010F00U); + psu_mask_write(0xFF5E0078, 0x013F3F07U, 0x01010F00U); + psu_mask_write(0xFF5E0124, 0x013F3F07U, 0x01010F00U); + psu_mask_write(0xFF5E0090, 0x01003F07U, 0x01000302U); + psu_mask_write(0xFF5E009C, 0x01003F07U, 0x01000602U); + psu_mask_write(0xFF5E00A4, 0x01003F07U, 0x01000800U); + psu_mask_write(0xFF5E00A8, 0x01003F07U, 0x01000302U); + psu_mask_write(0xFF5E00AC, 0x01003F07U, 0x01000F02U); + psu_mask_write(0xFF5E00B0, 0x01003F07U, 0x01000602U); + psu_mask_write(0xFF5E00B8, 0x01003F07U, 0x01000302U); + psu_mask_write(0xFF5E00C0, 0x013F3F07U, 0x01010F00U); + psu_mask_write(0xFF5E0108, 0x013F3F07U, 0x01011E02U); + psu_mask_write(0xFF5E0104, 0x00000007U, 0x00000000U); + psu_mask_write(0xFF5E0128, 0x01003F07U, 0x01000F00U); + psu_mask_write(0xFD1A00A0, 0x01003F07U, 0x01000200U); + psu_mask_write(0xFD1A00B4, 0x01003F07U, 0x01000200U); + psu_mask_write(0xFD1A0070, 0x013F3F07U, 0x01010500U); + psu_mask_write(0xFD1A0074, 0x013F3F07U, 0x01011003U); + psu_mask_write(0xFD1A007C, 0x013F3F07U, 0x01010F03U); + psu_mask_write(0xFD1A0060, 0x03003F07U, 0x03000100U); + psu_mask_write(0xFD1A0068, 0x01003F07U, 0x01000200U); + psu_mask_write(0xFD1A0080, 0x00003F07U, 0x00000200U); + psu_mask_write(0xFD1A0084, 0x07003F07U, 0x07000100U); + psu_mask_write(0xFD1A00B8, 0x01003F07U, 0x01000200U); + psu_mask_write(0xFD1A00BC, 0x01003F07U, 0x01000200U); + psu_mask_write(0xFD1A00C0, 0x01003F07U, 0x01000303U); + psu_mask_write(0xFD1A00C4, 0x01003F07U, 0x01000502U); + psu_mask_write(0xFD1A00F8, 0x00003F07U, 0x00000200U); + psu_mask_write(0xFF180380, 0x000000FFU, 0x00000000U); + psu_mask_write(0xFD610100, 0x00000001U, 0x00000000U); + psu_mask_write(0xFF180300, 0x00000001U, 0x00000000U); + psu_mask_write(0xFF410050, 0x00000001U, 0x00000000U); + + return 1; +} + +static unsigned long psu_ddr_init_data(void) +{ + psu_mask_write(0xFD1A0108, 0x00000008U, 0x00000008U); + psu_mask_write(0xFD070000, 0xE30FBE3DU, 0x81040010U); + psu_mask_write(0xFD070010, 0x8000F03FU, 0x00000030U); + psu_mask_write(0xFD070020, 0x000003F3U, 0x00000300U); + psu_mask_write(0xFD070024, 0xFFFFFFFFU, 0x00800000U); + psu_mask_write(0xFD070030, 0x0000007FU, 0x00000000U); + psu_mask_write(0xFD070034, 0x00FFFF1FU, 0x00409410U); + psu_mask_write(0xFD070050, 0x00F1F1F4U, 0x00210000U); + psu_mask_write(0xFD070054, 0x0FFF0FFFU, 0x00000000U); + psu_mask_write(0xFD070060, 0x00000073U, 0x00000001U); + psu_mask_write(0xFD070064, 0x0FFF83FFU, 0x009280D2U); + psu_mask_write(0xFD070070, 0x00000017U, 0x00000010U); + psu_mask_write(0xFD070074, 0x00000003U, 0x00000000U); + psu_mask_write(0xFD0700C4, 0x3F000391U, 0x10000200U); + psu_mask_write(0xFD0700C8, 0x01FF1F3FU, 0x0048051FU); + psu_mask_write(0xFD0700D0, 0xC3FF0FFFU, 0x00020126U); + psu_mask_write(0xFD0700D4, 0x01FF7F0FU, 0x00020000U); + psu_mask_write(0xFD0700D8, 0x0000FF0FU, 0x00002705U); + psu_mask_write(0xFD0700DC, 0xFFFFFFFFU, 0x09340301U); + psu_mask_write(0xFD0700E0, 0xFFFFFFFFU, 0x00280200U); + psu_mask_write(0xFD0700E4, 0x00FF03FFU, 0x00210004U); + psu_mask_write(0xFD0700E8, 0xFFFFFFFFU, 0x000006C0U); + psu_mask_write(0xFD0700EC, 0xFFFF0000U, 0x08190000U); + psu_mask_write(0xFD0700F0, 0x0000003FU, 0x00000010U); + psu_mask_write(0xFD0700F4, 0x00000FFFU, 0x0000066FU); + psu_mask_write(0xFD070100, 0x7F3F7F3FU, 0x131C2813U); + psu_mask_write(0xFD070104, 0x001F1F7FU, 0x0004041CU); + psu_mask_write(0xFD070108, 0x3F3F3F3FU, 0x0808050FU); + psu_mask_write(0xFD07010C, 0x3FF3F3FFU, 0x0050400CU); + psu_mask_write(0xFD070110, 0x1F0F0F1FU, 0x08030409U); + psu_mask_write(0xFD070114, 0x0F0F3F1FU, 0x06060403U); + psu_mask_write(0xFD070118, 0x0F0F000FU, 0x01010004U); + psu_mask_write(0xFD07011C, 0x00000F0FU, 0x00000606U); + psu_mask_write(0xFD070120, 0x7F7F7F7FU, 0x05050D08U); + psu_mask_write(0xFD070124, 0x40070F3FU, 0x0002040CU); + psu_mask_write(0xFD07012C, 0x7F1F031FU, 0x1308010EU); + psu_mask_write(0xFD070130, 0x00030F1FU, 0x00020608U); + psu_mask_write(0xFD070180, 0xF7FF03FFU, 0x81000040U); + psu_mask_write(0xFD070184, 0x3FFFFFFFU, 0x0201C9C2U); + psu_mask_write(0xFD070190, 0x1FBFBF3FU, 0x048C820DU); + psu_mask_write(0xFD070194, 0xF31F0F0FU, 0x00030304U); + psu_mask_write(0xFD070198, 0x0FF1F1F1U, 0x07000101U); + psu_mask_write(0xFD07019C, 0x000000F1U, 0x00000021U); + psu_mask_write(0xFD0701A0, 0xC3FF03FFU, 0x00400003U); + psu_mask_write(0xFD0701A4, 0x00FF00FFU, 0x00C800FFU); + psu_mask_write(0xFD0701B0, 0x00000007U, 0x00000000U); + psu_mask_write(0xFD0701B4, 0x00003F3FU, 0x00000A0BU); + psu_mask_write(0xFD0701C0, 0x00000007U, 0x00000001U); + psu_mask_write(0xFD070200, 0x0000001FU, 0x0000001FU); + psu_mask_write(0xFD070204, 0x001F1F1FU, 0x001F0909U); + psu_mask_write(0xFD070208, 0x0F0F0F0FU, 0x00000000U); + psu_mask_write(0xFD07020C, 0x0F0F0F0FU, 0x00000000U); + psu_mask_write(0xFD070210, 0x00000F0FU, 0x00000F0FU); + psu_mask_write(0xFD070214, 0x0F0F0F0FU, 0x070F0707U); + psu_mask_write(0xFD070218, 0x8F0F0F0FU, 0x07070707U); + psu_mask_write(0xFD07021C, 0x00000F0FU, 0x00000F0FU); + psu_mask_write(0xFD070220, 0x00001F1FU, 0x00001F08U); + psu_mask_write(0xFD070224, 0x0F0F0F0FU, 0x07070707U); + psu_mask_write(0xFD070228, 0x0F0F0F0FU, 0x07070707U); + psu_mask_write(0xFD07022C, 0x0000000FU, 0x00000007U); + psu_mask_write(0xFD070240, 0x0F1F0F7CU, 0x06000600U); + psu_mask_write(0xFD070244, 0x00003333U, 0x00000001U); + psu_mask_write(0xFD070250, 0x7FFF3F07U, 0x01002001U); + psu_mask_write(0xFD070264, 0xFF00FFFFU, 0x08000040U); + psu_mask_write(0xFD07026C, 0xFF00FFFFU, 0x08000040U); + psu_mask_write(0xFD070280, 0xFFFFFFFFU, 0x00000000U); + psu_mask_write(0xFD070284, 0xFFFFFFFFU, 0x00000000U); + psu_mask_write(0xFD070288, 0xFFFFFFFFU, 0x00000000U); + psu_mask_write(0xFD07028C, 0xFFFFFFFFU, 0x00000000U); + psu_mask_write(0xFD070290, 0x0000FFFFU, 0x00000000U); + psu_mask_write(0xFD070294, 0x00000001U, 0x00000001U); + psu_mask_write(0xFD070300, 0x00000011U, 0x00000000U); + psu_mask_write(0xFD07030C, 0x80000033U, 0x00000000U); + psu_mask_write(0xFD070320, 0x00000001U, 0x00000000U); + psu_mask_write(0xFD070400, 0x00000111U, 0x00000001U); + psu_mask_write(0xFD070404, 0x000073FFU, 0x0000200FU); + psu_mask_write(0xFD070408, 0x000073FFU, 0x0000200FU); + psu_mask_write(0xFD070490, 0x00000001U, 0x00000001U); + psu_mask_write(0xFD070494, 0x0033000FU, 0x0020000BU); + psu_mask_write(0xFD070498, 0x07FF07FFU, 0x00000000U); + psu_mask_write(0xFD0704B4, 0x000073FFU, 0x0000200FU); + psu_mask_write(0xFD0704B8, 0x000073FFU, 0x0000200FU); + psu_mask_write(0xFD070540, 0x00000001U, 0x00000001U); + psu_mask_write(0xFD070544, 0x03330F0FU, 0x02000B03U); + psu_mask_write(0xFD070548, 0x07FF07FFU, 0x00000000U); + psu_mask_write(0xFD070564, 0x000073FFU, 0x0000200FU); + psu_mask_write(0xFD070568, 0x000073FFU, 0x0000200FU); + psu_mask_write(0xFD0705F0, 0x00000001U, 0x00000001U); + psu_mask_write(0xFD0705F4, 0x03330F0FU, 0x02000B03U); + psu_mask_write(0xFD0705F8, 0x07FF07FFU, 0x00000000U); + psu_mask_write(0xFD070614, 0x000073FFU, 0x0000200FU); + psu_mask_write(0xFD070618, 0x000073FFU, 0x0000200FU); + psu_mask_write(0xFD0706A0, 0x00000001U, 0x00000001U); + psu_mask_write(0xFD0706A4, 0x0033000FU, 0x00100003U); + psu_mask_write(0xFD0706A8, 0x07FF07FFU, 0x0000004FU); + psu_mask_write(0xFD0706AC, 0x0033000FU, 0x00100003U); + psu_mask_write(0xFD0706B0, 0x000007FFU, 0x0000004FU); + psu_mask_write(0xFD0706C4, 0x000073FFU, 0x0000200FU); + psu_mask_write(0xFD0706C8, 0x000073FFU, 0x0000200FU); + psu_mask_write(0xFD070750, 0x00000001U, 0x00000001U); + psu_mask_write(0xFD070754, 0x0033000FU, 0x00100003U); + psu_mask_write(0xFD070758, 0x07FF07FFU, 0x0000004FU); + psu_mask_write(0xFD07075C, 0x0033000FU, 0x00100003U); + psu_mask_write(0xFD070760, 0x000007FFU, 0x0000004FU); + psu_mask_write(0xFD070774, 0x000073FFU, 0x0000200FU); + psu_mask_write(0xFD070778, 0x000073FFU, 0x0000200FU); + psu_mask_write(0xFD070800, 0x00000001U, 0x00000001U); + psu_mask_write(0xFD070804, 0x0033000FU, 0x00100003U); + psu_mask_write(0xFD070808, 0x07FF07FFU, 0x0000004FU); + psu_mask_write(0xFD07080C, 0x0033000FU, 0x00100003U); + psu_mask_write(0xFD070810, 0x000007FFU, 0x0000004FU); + psu_mask_write(0xFD070F04, 0x000001FFU, 0x00000000U); + psu_mask_write(0xFD070F08, 0x000000FFU, 0x00000000U); + psu_mask_write(0xFD070F0C, 0x000001FFU, 0x00000010U); + psu_mask_write(0xFD070F10, 0x000000FFU, 0x0000000FU); + psu_mask_write(0xFD072190, 0x1FBFBF3FU, 0x07828002U); + psu_mask_write(0xFD1A0108, 0x0000000CU, 0x00000000U); + psu_mask_write(0xFD080010, 0xFFFFFFFFU, 0x07001E00U); + psu_mask_write(0xFD080018, 0xFFFFFFFFU, 0x00F12090U); + psu_mask_write(0xFD08001C, 0xFFFFFFFFU, 0x55AA5480U); + psu_mask_write(0xFD080024, 0xFFFFFFFFU, 0x010100F4U); + psu_mask_write(0xFD080040, 0xFFFFFFFFU, 0x4B025810U); + psu_mask_write(0xFD080044, 0xFFFFFFFFU, 0xEA601518U); + psu_mask_write(0xFD080068, 0xFFFFFFFFU, 0x000E0000U); + psu_mask_write(0xFD080090, 0xFFFFFFFFU, 0x02A04161U); + psu_mask_write(0xFD0800C0, 0xFFFFFFFFU, 0x00000000U); + psu_mask_write(0xFD0800C4, 0xFFFFFFFFU, 0x000000DDU); + psu_mask_write(0xFD080100, 0xFFFFFFFFU, 0x0800040CU); + psu_mask_write(0xFD080110, 0xFFFFFFFFU, 0x08261009U); + psu_mask_write(0xFD080114, 0xFFFFFFFFU, 0x28380008U); + psu_mask_write(0xFD080118, 0xFFFFFFFFU, 0x000F0300U); + psu_mask_write(0xFD08011C, 0xFFFFFFFFU, 0x83000800U); + psu_mask_write(0xFD080120, 0xFFFFFFFFU, 0x01A42B08U); + psu_mask_write(0xFD080124, 0xFFFFFFFFU, 0x00371009U); + psu_mask_write(0xFD080128, 0xFFFFFFFFU, 0x00001010U); + psu_mask_write(0xFD080140, 0xFFFFFFFFU, 0x08400020U); + psu_mask_write(0xFD080144, 0xFFFFFFFFU, 0x00000C80U); + psu_mask_write(0xFD080150, 0xFFFFFFFFU, 0x00000000U); + psu_mask_write(0xFD080154, 0xFFFFFFFFU, 0x00000300U); + psu_mask_write(0xFD080180, 0xFFFFFFFFU, 0x00000834U); + psu_mask_write(0xFD080184, 0xFFFFFFFFU, 0x00000301U); + psu_mask_write(0xFD080188, 0xFFFFFFFFU, 0x00000028U); + psu_mask_write(0xFD08018C, 0xFFFFFFFFU, 0x00000200U); + psu_mask_write(0xFD080190, 0xFFFFFFFFU, 0x00000000U); + psu_mask_write(0xFD080194, 0xFFFFFFFFU, 0x000006C0U); + psu_mask_write(0xFD080198, 0xFFFFFFFFU, 0x00000819U); + psu_mask_write(0xFD0801AC, 0xFFFFFFFFU, 0x00000000U); + psu_mask_write(0xFD0801B0, 0xFFFFFFFFU, 0x0000004DU); + psu_mask_write(0xFD0801B4, 0xFFFFFFFFU, 0x00000008U); + psu_mask_write(0xFD0801B8, 0xFFFFFFFFU, 0x0000004DU); + psu_mask_write(0xFD0801D8, 0xFFFFFFFFU, 0x00000000U); + psu_mask_write(0xFD080200, 0xFFFFFFFFU, 0x800091C7U); + psu_mask_write(0xFD080204, 0xFFFFFFFFU, 0x00010236U); + psu_mask_write(0xFD080240, 0xFFFFFFFFU, 0x00141054U); + psu_mask_write(0xFD080250, 0xFFFFFFFFU, 0x00088000U); + psu_mask_write(0xFD080414, 0xFFFFFFFFU, 0x12341000U); + psu_mask_write(0xFD0804F4, 0xFFFFFFFFU, 0x00000005U); + psu_mask_write(0xFD080500, 0xFFFFFFFFU, 0x30000028U); + psu_mask_write(0xFD080508, 0xFFFFFFFFU, 0x0A000000U); + psu_mask_write(0xFD08050C, 0xFFFFFFFFU, 0x00000009U); + psu_mask_write(0xFD080510, 0xFFFFFFFFU, 0x0A000000U); + psu_mask_write(0xFD080520, 0xFFFFFFFFU, 0x0300B0CEU); + psu_mask_write(0xFD080528, 0xFFFFFFFFU, 0xF9032019U); + psu_mask_write(0xFD08052C, 0xFFFFFFFFU, 0x07F001E3U); + psu_mask_write(0xFD080544, 0xFFFFFFFFU, 0x00000000U); + psu_mask_write(0xFD080548, 0xFFFFFFFFU, 0x00000000U); + psu_mask_write(0xFD080558, 0xFFFFFFFFU, 0x00000000U); + psu_mask_write(0xFD08055C, 0xFFFFFFFFU, 0x00000000U); + psu_mask_write(0xFD080560, 0xFFFFFFFFU, 0x00000000U); + psu_mask_write(0xFD080564, 0xFFFFFFFFU, 0x00000000U); + psu_mask_write(0xFD080680, 0xFFFFFFFFU, 0x008AEA58U); + psu_mask_write(0xFD080684, 0xFFFFFFFFU, 0x000079DDU); + psu_mask_write(0xFD080694, 0xFFFFFFFFU, 0x01E10210U); + psu_mask_write(0xFD080698, 0xFFFFFFFFU, 0x01E10000U); + psu_mask_write(0xFD0806A4, 0xFFFFFFFFU, 0x00087BDBU); + psu_mask_write(0xFD080700, 0xFFFFFFFFU, 0x40800604U); + psu_mask_write(0xFD080704, 0xFFFFFFFFU, 0x00007FFFU); + psu_mask_write(0xFD08070C, 0xFFFFFFFFU, 0x3F000008U); + psu_mask_write(0xFD080710, 0xFFFFFFFFU, 0x0E00B03CU); + psu_mask_write(0xFD080714, 0xFFFFFFFFU, 0x09094F4FU); + psu_mask_write(0xFD080718, 0xFFFFFFFFU, 0x09092B2BU); + psu_mask_write(0xFD080800, 0xFFFFFFFFU, 0x40800604U); + psu_mask_write(0xFD080804, 0xFFFFFFFFU, 0x00007FFFU); + psu_mask_write(0xFD08080C, 0xFFFFFFFFU, 0x3F000008U); + psu_mask_write(0xFD080810, 0xFFFFFFFFU, 0x0E00B03CU); + psu_mask_write(0xFD080814, 0xFFFFFFFFU, 0x09094F4FU); + psu_mask_write(0xFD080818, 0xFFFFFFFFU, 0x09092B2BU); + psu_mask_write(0xFD080900, 0xFFFFFFFFU, 0x40800604U); + psu_mask_write(0xFD080904, 0xFFFFFFFFU, 0x00007FFFU); + psu_mask_write(0xFD08090C, 0xFFFFFFFFU, 0x3F000008U); + psu_mask_write(0xFD080910, 0xFFFFFFFFU, 0x0E00B03CU); + psu_mask_write(0xFD080914, 0xFFFFFFFFU, 0x09094F4FU); + psu_mask_write(0xFD080918, 0xFFFFFFFFU, 0x09092B2BU); + psu_mask_write(0xFD080A00, 0xFFFFFFFFU, 0x40800604U); + psu_mask_write(0xFD080A04, 0xFFFFFFFFU, 0x00007FFFU); + psu_mask_write(0xFD080A0C, 0xFFFFFFFFU, 0x3F000008U); + psu_mask_write(0xFD080A10, 0xFFFFFFFFU, 0x0E00B03CU); + psu_mask_write(0xFD080A14, 0xFFFFFFFFU, 0x09094F4FU); + psu_mask_write(0xFD080A18, 0xFFFFFFFFU, 0x09092B2BU); + psu_mask_write(0xFD080B00, 0xFFFFFFFFU, 0x40800604U); + psu_mask_write(0xFD080B04, 0xFFFFFFFFU, 0x00007FFFU); + psu_mask_write(0xFD080B08, 0xFFFFFFFFU, 0x00000000U); + psu_mask_write(0xFD080B0C, 0xFFFFFFFFU, 0x3F000008U); + psu_mask_write(0xFD080B10, 0xFFFFFFFFU, 0x0E00B004U); + psu_mask_write(0xFD080B14, 0xFFFFFFFFU, 0x09094F4FU); + psu_mask_write(0xFD080B18, 0xFFFFFFFFU, 0x09092B2BU); + psu_mask_write(0xFD080C00, 0xFFFFFFFFU, 0x40800604U); + psu_mask_write(0xFD080C04, 0xFFFFFFFFU, 0x00007FFFU); + psu_mask_write(0xFD080C08, 0xFFFFFFFFU, 0x00000000U); + psu_mask_write(0xFD080C0C, 0xFFFFFFFFU, 0x3F000008U); + psu_mask_write(0xFD080C10, 0xFFFFFFFFU, 0x0E00B03CU); + psu_mask_write(0xFD080C14, 0xFFFFFFFFU, 0x09094F4FU); + psu_mask_write(0xFD080C18, 0xFFFFFFFFU, 0x09092B2BU); + psu_mask_write(0xFD080D00, 0xFFFFFFFFU, 0x40800604U); + psu_mask_write(0xFD080D04, 0xFFFFFFFFU, 0x00007FFFU); + psu_mask_write(0xFD080D08, 0xFFFFFFFFU, 0x00000000U); + psu_mask_write(0xFD080D0C, 0xFFFFFFFFU, 0x3F000008U); + psu_mask_write(0xFD080D10, 0xFFFFFFFFU, 0x0E00B004U); + psu_mask_write(0xFD080D14, 0xFFFFFFFFU, 0x09094F4FU); + psu_mask_write(0xFD080D18, 0xFFFFFFFFU, 0x09092B2BU); + psu_mask_write(0xFD080E00, 0xFFFFFFFFU, 0x40800604U); + psu_mask_write(0xFD080E04, 0xFFFFFFFFU, 0x00007FFFU); + psu_mask_write(0xFD080E08, 0xFFFFFFFFU, 0x00000000U); + psu_mask_write(0xFD080E0C, 0xFFFFFFFFU, 0x3F000008U); + psu_mask_write(0xFD080E10, 0xFFFFFFFFU, 0x0E00B03CU); + psu_mask_write(0xFD080E14, 0xFFFFFFFFU, 0x09094F4FU); + psu_mask_write(0xFD080E18, 0xFFFFFFFFU, 0x09092B2BU); + psu_mask_write(0xFD080F00, 0xFFFFFFFFU, 0x80803660U); + psu_mask_write(0xFD080F04, 0xFFFFFFFFU, 0x55556000U); + psu_mask_write(0xFD080F08, 0xFFFFFFFFU, 0xAAAAAAAAU); + psu_mask_write(0xFD080F0C, 0xFFFFFFFFU, 0x0029A4A4U); + psu_mask_write(0xFD080F10, 0xFFFFFFFFU, 0x0C00B000U); + psu_mask_write(0xFD080F14, 0xFFFFFFFFU, 0x09094F4FU); + psu_mask_write(0xFD080F18, 0xFFFFFFFFU, 0x09092B2BU); + psu_mask_write(0xFD081400, 0xFFFFFFFFU, 0x2A019FFEU); + psu_mask_write(0xFD081404, 0xFFFFFFFFU, 0x000E0000U); + psu_mask_write(0xFD08141C, 0xFFFFFFFFU, 0x01264300U); + psu_mask_write(0xFD08142C, 0xFFFFFFFFU, 0x00041800U); + psu_mask_write(0xFD081430, 0xFFFFFFFFU, 0x70800000U); + psu_mask_write(0xFD081440, 0xFFFFFFFFU, 0x2A019FFEU); + psu_mask_write(0xFD081444, 0xFFFFFFFFU, 0x000E0000U); + psu_mask_write(0xFD08145C, 0xFFFFFFFFU, 0x01264300U); + psu_mask_write(0xFD08146C, 0xFFFFFFFFU, 0x00041800U); + psu_mask_write(0xFD081470, 0xFFFFFFFFU, 0x70800000U); + psu_mask_write(0xFD081480, 0xFFFFFFFFU, 0x2A019FFEU); + psu_mask_write(0xFD081484, 0xFFFFFFFFU, 0x000E0000U); + psu_mask_write(0xFD08149C, 0xFFFFFFFFU, 0x01264300U); + psu_mask_write(0xFD0814AC, 0xFFFFFFFFU, 0x00041800U); + psu_mask_write(0xFD0814B0, 0xFFFFFFFFU, 0x70800000U); + psu_mask_write(0xFD0814C0, 0xFFFFFFFFU, 0x2A019FFEU); + psu_mask_write(0xFD0814C4, 0xFFFFFFFFU, 0x000E0000U); + psu_mask_write(0xFD0814DC, 0xFFFFFFFFU, 0x01264300U); + psu_mask_write(0xFD0814EC, 0xFFFFFFFFU, 0x00041800U); + psu_mask_write(0xFD0814F0, 0xFFFFFFFFU, 0x70800000U); + psu_mask_write(0xFD081500, 0xFFFFFFFFU, 0x15019FFEU); + psu_mask_write(0xFD081504, 0xFFFFFFFFU, 0x200E0000U); + psu_mask_write(0xFD08151C, 0xFFFFFFFFU, 0x01266300U); + psu_mask_write(0xFD08152C, 0xFFFFFFFFU, 0x00041800U); + psu_mask_write(0xFD081530, 0xFFFFFFFFU, 0x70400000U); + psu_mask_write(0xFD0817C4, 0xFFFFFFFFU, 0x000E0000U); + psu_mask_write(0xFD0817DC, 0xFFFFFFFFU, 0x012643C4U); + + return 1; +} + +static unsigned long psu_ddr_qos_init_data(void) +{ + return 1; +} + +static unsigned long psu_mio_init_data(void) +{ + psu_mask_write(0xFF180000, 0x000000FEU, 0x00000002U); + psu_mask_write(0xFF180004, 0x000000FEU, 0x00000002U); + psu_mask_write(0xFF180008, 0x000000FEU, 0x00000002U); + psu_mask_write(0xFF18000C, 0x000000FEU, 0x00000002U); + psu_mask_write(0xFF180010, 0x000000FEU, 0x00000002U); + psu_mask_write(0xFF180014, 0x000000FEU, 0x00000002U); + psu_mask_write(0xFF180018, 0x000000FEU, 0x00000002U); + psu_mask_write(0xFF18001C, 0x000000FEU, 0x00000002U); + psu_mask_write(0xFF180020, 0x000000FEU, 0x00000002U); + psu_mask_write(0xFF180024, 0x000000FEU, 0x00000002U); + psu_mask_write(0xFF180028, 0x000000FEU, 0x00000002U); + psu_mask_write(0xFF18002C, 0x000000FEU, 0x00000002U); + psu_mask_write(0xFF180030, 0x000000FEU, 0x00000002U); + psu_mask_write(0xFF180034, 0x000000FEU, 0x00000008U); + psu_mask_write(0xFF180038, 0x000000FEU, 0x00000008U); + psu_mask_write(0xFF18003C, 0x000000FEU, 0x00000008U); + psu_mask_write(0xFF180040, 0x000000FEU, 0x00000008U); + psu_mask_write(0xFF180044, 0x000000FEU, 0x00000008U); + psu_mask_write(0xFF180048, 0x000000FEU, 0x00000008U); + psu_mask_write(0xFF18004C, 0x000000FEU, 0x00000008U); + psu_mask_write(0xFF180050, 0x000000FEU, 0x00000008U); + psu_mask_write(0xFF180054, 0x000000FEU, 0x00000008U); + psu_mask_write(0xFF180058, 0x000000FEU, 0x00000008U); + psu_mask_write(0xFF18005C, 0x000000FEU, 0x00000000U); + psu_mask_write(0xFF180060, 0x000000FEU, 0x00000040U); + psu_mask_write(0xFF180064, 0x000000FEU, 0x00000040U); + psu_mask_write(0xFF180068, 0x000000FEU, 0x00000000U); + psu_mask_write(0xFF18006C, 0x000000FEU, 0x00000018U); + psu_mask_write(0xFF180070, 0x000000FEU, 0x00000018U); + psu_mask_write(0xFF180074, 0x000000FEU, 0x00000018U); + psu_mask_write(0xFF180078, 0x000000FEU, 0x00000018U); + psu_mask_write(0xFF18007C, 0x000000FEU, 0x00000000U); + psu_mask_write(0xFF180080, 0x000000FEU, 0x000000C0U); + psu_mask_write(0xFF180084, 0x000000FEU, 0x000000C0U); + psu_mask_write(0xFF180088, 0x000000FEU, 0x000000C0U); + psu_mask_write(0xFF18008C, 0x000000FEU, 0x000000C0U); + psu_mask_write(0xFF180090, 0x000000FEU, 0x00000000U); + psu_mask_write(0xFF180094, 0x000000FEU, 0x00000000U); + psu_mask_write(0xFF180098, 0x000000FEU, 0x00000000U); + psu_mask_write(0xFF18009C, 0x000000FEU, 0x00000000U); + psu_mask_write(0xFF1800A0, 0x000000FEU, 0x00000000U); + psu_mask_write(0xFF1800A4, 0x000000FEU, 0x00000000U); + psu_mask_write(0xFF1800A8, 0x000000FEU, 0x00000000U); + psu_mask_write(0xFF1800AC, 0x000000FEU, 0x00000000U); + psu_mask_write(0xFF1800B0, 0x000000FEU, 0x00000000U); + psu_mask_write(0xFF1800B4, 0x000000FEU, 0x00000010U); + psu_mask_write(0xFF1800B8, 0x000000FEU, 0x00000010U); + psu_mask_write(0xFF1800BC, 0x000000FEU, 0x00000010U); + psu_mask_write(0xFF1800C0, 0x000000FEU, 0x00000010U); + psu_mask_write(0xFF1800C4, 0x000000FEU, 0x00000010U); + psu_mask_write(0xFF1800C8, 0x000000FEU, 0x00000010U); + psu_mask_write(0xFF1800CC, 0x000000FEU, 0x00000010U); + psu_mask_write(0xFF1800D0, 0x000000FEU, 0x00000004U); + psu_mask_write(0xFF1800D4, 0x000000FEU, 0x00000004U); + psu_mask_write(0xFF1800D8, 0x000000FEU, 0x00000004U); + psu_mask_write(0xFF1800DC, 0x000000FEU, 0x00000004U); + psu_mask_write(0xFF1800E0, 0x000000FEU, 0x00000004U); + psu_mask_write(0xFF1800E4, 0x000000FEU, 0x00000004U); + psu_mask_write(0xFF1800E8, 0x000000FEU, 0x00000004U); + psu_mask_write(0xFF1800EC, 0x000000FEU, 0x00000004U); + psu_mask_write(0xFF1800F0, 0x000000FEU, 0x00000004U); + psu_mask_write(0xFF1800F4, 0x000000FEU, 0x00000004U); + psu_mask_write(0xFF1800F8, 0x000000FEU, 0x00000004U); + psu_mask_write(0xFF1800FC, 0x000000FEU, 0x00000004U); + psu_mask_write(0xFF180100, 0x000000FEU, 0x00000002U); + psu_mask_write(0xFF180104, 0x000000FEU, 0x00000002U); + psu_mask_write(0xFF180108, 0x000000FEU, 0x00000002U); + psu_mask_write(0xFF18010C, 0x000000FEU, 0x00000002U); + psu_mask_write(0xFF180110, 0x000000FEU, 0x00000002U); + psu_mask_write(0xFF180114, 0x000000FEU, 0x00000002U); + psu_mask_write(0xFF180118, 0x000000FEU, 0x00000002U); + psu_mask_write(0xFF18011C, 0x000000FEU, 0x00000002U); + psu_mask_write(0xFF180120, 0x000000FEU, 0x00000002U); + psu_mask_write(0xFF180124, 0x000000FEU, 0x00000002U); + psu_mask_write(0xFF180128, 0x000000FEU, 0x00000002U); + psu_mask_write(0xFF18012C, 0x000000FEU, 0x00000002U); + psu_mask_write(0xFF180130, 0x000000FEU, 0x000000C0U); + psu_mask_write(0xFF180134, 0x000000FEU, 0x000000C0U); + psu_mask_write(0xFF180204, 0xFFFFFFFFU, 0x50000000U); + psu_mask_write(0xFF180208, 0xFFFFFFFFU, 0x00B02006U); + psu_mask_write(0xFF18020C, 0x00003FFFU, 0x00000FC0U); + psu_mask_write(0xFF180138, 0x03FFFFFFU, 0x03FFFFFFU); + psu_mask_write(0xFF18013C, 0x03FFFFFFU, 0x03FFFFFFU); + psu_mask_write(0xFF180140, 0x03FFFFFFU, 0x00000000U); + psu_mask_write(0xFF180144, 0x03FFFFFFU, 0x03FFFFFFU); + psu_mask_write(0xFF180148, 0x03FFFFFFU, 0x03FFFFFFU); + psu_mask_write(0xFF18014C, 0x03FFFFFFU, 0x00000000U); + psu_mask_write(0xFF180154, 0x03FFFFFFU, 0x03FFFFFFU); + psu_mask_write(0xFF180158, 0x03FFFFFFU, 0x03FFFFFFU); + psu_mask_write(0xFF18015C, 0x03FFFFFFU, 0x00000000U); + psu_mask_write(0xFF180160, 0x03FFFFFFU, 0x03FFFFFFU); + psu_mask_write(0xFF180164, 0x03FFFFFFU, 0x03FFFFFFU); + psu_mask_write(0xFF180168, 0x03FFFFFFU, 0x00000000U); + psu_mask_write(0xFF180170, 0x03FFFFFFU, 0x03FFFFFFU); + psu_mask_write(0xFF180174, 0x03FFFFFFU, 0x03FFFFFFU); + psu_mask_write(0xFF180178, 0x03FFFFFFU, 0x00000000U); + psu_mask_write(0xFF18017C, 0x03FFFFFFU, 0x03FFFFFFU); + psu_mask_write(0xFF180180, 0x03FFFFFFU, 0x03FFFFFFU); + psu_mask_write(0xFF180184, 0x03FFFFFFU, 0x00000000U); + psu_mask_write(0xFF180200, 0x0000000FU, 0x00000000U); + + return 1; +} + +static unsigned long psu_peripherals_pre_init_data(void) +{ + psu_mask_write(0xFF5E0108, 0x013F3F07U, 0x01012302U); + + return 1; +} + +static unsigned long psu_peripherals_init_data(void) +{ + psu_mask_write(0xFD1A0100, 0x000F807EU, 0x00000000U); + psu_mask_write(0xFF5E0238, 0x001A0000U, 0x00000000U); + psu_mask_write(0xFF5E023C, 0x0093C018U, 0x00000000U); + psu_mask_write(0xFF5E0230, 0x00000008U, 0x00000000U); + psu_mask_write(0xFF5E0238, 0x00000001U, 0x00000000U); + psu_mask_write(0xFF180390, 0x00000004U, 0x00000004U); + psu_mask_write(0xFF5E023C, 0x00000400U, 0x00000000U); + psu_mask_write(0xFF5E0238, 0x00000060U, 0x00000000U); + psu_mask_write(0xFF180310, 0x00008001U, 0x00000001U); + psu_mask_write(0xFF180320, 0x33843384U, 0x00801284U); + psu_mask_write(0xFF18031C, 0x00007FFEU, 0x00006450U); + psu_mask_write(0xFF180358, 0x00080000U, 0x00080000U); + psu_mask_write(0xFF18031C, 0x7FFE0000U, 0x64500000U); + psu_mask_write(0xFF180358, 0x00000008U, 0x00000008U); + psu_mask_write(0xFF180324, 0x000003C0U, 0x00000000U); + psu_mask_write(0xFF180324, 0x03C00000U, 0x00000000U); + psu_mask_write(0xFF5E0238, 0x00000400U, 0x00000000U); + psu_mask_write(0xFF5E0238, 0x00008000U, 0x00000000U); + psu_mask_write(0xFF5E0238, 0x00007800U, 0x00000000U); + psu_mask_write(0xFF5E0238, 0x00000006U, 0x00000000U); + psu_mask_write(0xFF000034, 0x000000FFU, 0x00000005U); + psu_mask_write(0xFF000018, 0x0000FFFFU, 0x0000008FU); + psu_mask_write(0xFF000000, 0x000001FFU, 0x00000017U); + psu_mask_write(0xFF000004, 0x000003FFU, 0x00000020U); + psu_mask_write(0xFF010034, 0x000000FFU, 0x00000005U); + psu_mask_write(0xFF010018, 0x0000FFFFU, 0x0000008FU); + psu_mask_write(0xFF010000, 0x000001FFU, 0x00000017U); + psu_mask_write(0xFF010004, 0x000003FFU, 0x00000020U); + psu_mask_write(0xFF5E0238, 0x00040000U, 0x00000000U); + psu_mask_write(0xFF4B0024, 0x000000FFU, 0x000000FFU); + psu_mask_write(0xFFCA5000, 0x00001FFFU, 0x00000000U); + psu_mask_write(0xFD5C0060, 0x000F000FU, 0x00000000U); + psu_mask_write(0xFFA60040, 0x80000000U, 0x80000000U); + psu_mask_write(0xFF260020, 0xFFFFFFFFU, 0x05F5DD18U); + psu_mask_write(0xFF260000, 0x00000001U, 0x00000001U); + psu_mask_write(0xFF5E0250, 0x00000F0FU, 0x00000202U); + + mask_delay(1); + psu_mask_write(0xFF5E0250, 0x00000F0FU, 0x00000002U); + + mask_delay(5); + psu_mask_write(0xFF5E0250, 0x00000F0FU, 0x00000202U); + psu_mask_write(0xFF0A0244, 0x03FFFFFFU, 0x00000020U); + psu_mask_write(0xFF0A0248, 0x03FFFFFFU, 0x00000020U); + psu_mask_write(0xFF0A0008, 0xFFFFFFFFU, 0xFFDF0020U); + mask_delay(1); + psu_mask_write(0xFF0A0008, 0xFFFFFFFFU, 0xFFDF0000U); + mask_delay(5); + + return 1; +} + +static unsigned long psu_afi_config(void) +{ + psu_mask_write(0xFD1A0100, 0x00001F80U, 0x00000000U); + psu_mask_write(0xFF5E023C, 0x00080000U, 0x00000000U); + psu_mask_write(0xFD615000, 0x00000F00U, 0x00000A00U); + + return 1; +} + +static unsigned long psu_ddr_phybringup_data(void) +{ + unsigned int regval = 0; + unsigned int pll_retry = 10; + unsigned int pll_locked = 0; + + while ((pll_retry > 0) && (!pll_locked)) { + Xil_Out32(0xFD080004, 0x00040010); + Xil_Out32(0xFD080004, 0x00040011); + + while ((Xil_In32(0xFD080030) & 0x1) != 1) + ; + pll_locked = (Xil_In32(0xFD080030) & 0x80000000) + >> 31; + pll_locked &= (Xil_In32(0xFD0807E0) & 0x10000) + >> 16; + pll_locked &= (Xil_In32(0xFD0809E0) & 0x10000) + >> 16; + pll_locked &= (Xil_In32(0xFD080BE0) & 0x10000) + >> 16; + pll_locked &= (Xil_In32(0xFD080DE0) & 0x10000) + >> 16; + pll_retry--; + } + Xil_Out32(0xFD0800C4, Xil_In32(0xFD0800C4) | (pll_retry << 16)); + if (!pll_locked) + return 0; + + Xil_Out32(0xFD080004U, 0x00040063U); + + while ((Xil_In32(0xFD080030U) & 0x0000000FU) != 0x0000000FU) + ; + prog_reg(0xFD080004U, 0x00000001U, 0x00000000U, 0x00000001U); + + while ((Xil_In32(0xFD080030U) & 0x000000FFU) != 0x0000001FU) + ; + Xil_Out32(0xFD0701B0U, 0x00000001U); + Xil_Out32(0xFD070320U, 0x00000001U); + while ((Xil_In32(0xFD070004U) & 0x0000000FU) != 0x00000001U) + ; + prog_reg(0xFD080014U, 0x00000040U, 0x00000006U, 0x00000001U); + Xil_Out32(0xFD080004, 0x0004FE01); + regval = Xil_In32(0xFD080030); + while (regval != 0x80000FFF) + regval = Xil_In32(0xFD080030); + regval = ((Xil_In32(0xFD080030) & 0x1FFF0000) >> 18); + if (regval != 0) + return 0; + + Xil_Out32(0xFD080200U, 0x100091C7U); + int cur_R006_tREFPRD; + + cur_R006_tREFPRD = (Xil_In32(0xFD080018U) & 0x0003FFFFU) >> 0x00000000U; + prog_reg(0xFD080018, 0x3FFFF, 0x0, cur_R006_tREFPRD); + + prog_reg(0xFD08001CU, 0x00000018U, 0x00000003U, 0x00000003U); + prog_reg(0xFD08142CU, 0x00000030U, 0x00000004U, 0x00000003U); + prog_reg(0xFD08146CU, 0x00000030U, 0x00000004U, 0x00000003U); + prog_reg(0xFD0814ACU, 0x00000030U, 0x00000004U, 0x00000003U); + prog_reg(0xFD0814ECU, 0x00000030U, 0x00000004U, 0x00000003U); + prog_reg(0xFD08152CU, 0x00000030U, 0x00000004U, 0x00000003U); + + Xil_Out32(0xFD080004, 0x00060001); + regval = Xil_In32(0xFD080030); + while ((regval & 0x80004001) != 0x80004001) + regval = Xil_In32(0xFD080030); + + prog_reg(0xFD08001CU, 0x00000018U, 0x00000003U, 0x00000000U); + prog_reg(0xFD08142CU, 0x00000030U, 0x00000004U, 0x00000000U); + prog_reg(0xFD08146CU, 0x00000030U, 0x00000004U, 0x00000000U); + prog_reg(0xFD0814ACU, 0x00000030U, 0x00000004U, 0x00000000U); + prog_reg(0xFD0814ECU, 0x00000030U, 0x00000004U, 0x00000000U); + prog_reg(0xFD08152CU, 0x00000030U, 0x00000004U, 0x00000000U); + + Xil_Out32(0xFD080200U, 0x800091C7U); + prog_reg(0xFD080018, 0x3FFFF, 0x0, cur_R006_tREFPRD); + + Xil_Out32(0xFD080004, 0x0000C001); + regval = Xil_In32(0xFD080030); + while ((regval & 0x80000C01) != 0x80000C01) + regval = Xil_In32(0xFD080030); + + Xil_Out32(0xFD070180U, 0x01000040U); + Xil_Out32(0xFD070060U, 0x00000000U); + prog_reg(0xFD080014U, 0x00000040U, 0x00000006U, 0x00000000U); + + return 1; +} + +static void init_peripheral(void) +{ + psu_mask_write(0xFD5F0018, 0x8000001FU, 0x8000001FU); +} + +int psu_init(void) +{ + int status = 1; + + status &= psu_mio_init_data(); + status &= psu_peripherals_pre_init_data(); + status &= psu_pll_init_data(); + status &= psu_clock_init_data(); + status &= psu_ddr_init_data(); + status &= psu_ddr_phybringup_data(); + status &= psu_peripherals_init_data(); + init_peripheral(); + + status &= psu_afi_config(); + psu_ddr_qos_init_data(); + + if (status == 0) + return 1; + return 0; +} diff --git a/configs/avnet_ultrazedev_cc_v1_0_ultrazedev_som_v1_0_defconfig b/configs/avnet_ultrazedev_cc_v1_0_ultrazedev_som_v1_0_defconfig new file mode 100644 index 0000000000..b326231b68 --- /dev/null +++ b/configs/avnet_ultrazedev_cc_v1_0_ultrazedev_som_v1_0_defconfig @@ -0,0 +1,64 @@ +CONFIG_ARM=y +CONFIG_ARCH_ZYNQMP=y +CONFIG_SYS_TEXT_BASE=0x8000000 +CONFIG_SYS_MALLOC_F_LEN=0x8000 +CONFIG_SPL=y +CONFIG_DEBUG_UART_BASE=0xff000000 +CONFIG_DEBUG_UART_CLOCK=100000000 +CONFIG_SPL_SPI_FLASH_SUPPORT=y +CONFIG_SPL_SPI_SUPPORT=y +CONFIG_SPL_ZYNQMP_TWO_SDHCI=y +CONFIG_DEBUG_UART=y +CONFIG_DISTRO_DEFAULTS=y +CONFIG_FIT=y +CONFIG_FIT_VERBOSE=y +CONFIG_SPL_LOAD_FIT=y +CONFIG_BOOTDELAY=0 +# CONFIG_DISPLAY_CPUINFO is not set +CONFIG_SPL_TEXT_BASE=0xfffc0000 +CONFIG_SPL_OS_BOOT=y +CONFIG_SYS_PROMPT="ZynqMP> " +CONFIG_CMD_MEMTEST=y +CONFIG_CMD_FPGA_LOADBP=y +CONFIG_CMD_FPGA_LOADP=y +CONFIG_CMD_MMC=y +CONFIG_CMD_SF=y +CONFIG_CMD_SPI=y +CONFIG_CMD_TIME=y +CONFIG_CMD_TIMER=y +CONFIG_CMD_EXT4_WRITE=y +CONFIG_SPL_OF_CONTROL=y +CONFIG_DEFAULT_DEVICE_TREE="avnet-ultrazedev-cc-v1.0-ultrazedev-som-v1.0" +CONFIG_NET_RANDOM_ETHADDR=y +CONFIG_SPL_DM=y +CONFIG_SPL_DM_SEQ_ALIAS=y +CONFIG_CLK_ZYNQMP=y +CONFIG_FPGA_XILINX=y +CONFIG_FPGA_ZYNQMPPL=y +CONFIG_DM_GPIO=y +CONFIG_DM_I2C=y +CONFIG_SYS_I2C_CADENCE=y +CONFIG_I2C_MUX=y +CONFIG_I2C_MUX_PCA954x=y +CONFIG_MISC=y +CONFIG_I2C_EEPROM=y +CONFIG_ZYNQ_GEM_I2C_MAC_OFFSET=0xfa +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_ZYNQ=y +CONFIG_SPI_FLASH=y +CONFIG_SPI_FLASH_BAR=y +CONFIG_SF_DUAL_FLASH=y +CONFIG_SPI_FLASH_ISSI=y +CONFIG_SPI_FLASH_MACRONIX=y +CONFIG_SPI_FLASH_SPANSION=y +CONFIG_SPI_FLASH_STMICRO=y +CONFIG_SPI_FLASH_WINBOND=y +# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set +CONFIG_ZYNQ_GEM=y +CONFIG_DEBUG_UART_ZYNQ=y +CONFIG_DEBUG_UART_ANNOUNCE=y +CONFIG_ZYNQ_SERIAL=y +CONFIG_SPI=y +CONFIG_ZYNQMP_GQSPI=y +CONFIG_OF_LIBFDT_OVERLAY=y +CONFIG_EFI_LOADER_BOUNCE_BUFFER=y From fa57af05526aa1e7f605aa3eb1676a01bdb647d6 Mon Sep 17 00:00:00 2001 From: Robert Hancock Date: Tue, 18 Jun 2019 09:47:12 -0600 Subject: [PATCH 11/22] fpga: virtex2: cosmetic: Cleanup code style Address Checkpatch warnings in virtex2 code prior to making other changes. No functional change intended. Signed-off-by: Robert Hancock Signed-off-by: Michal Simek --- drivers/fpga/virtex2.c | 270 +++++++++++++++++++++-------------------- 1 file changed, 136 insertions(+), 134 deletions(-) diff --git a/drivers/fpga/virtex2.c b/drivers/fpga/virtex2.c index 02773d6a0e..b01a31f080 100644 --- a/drivers/fpga/virtex2.c +++ b/drivers/fpga/virtex2.c @@ -19,16 +19,16 @@ #endif #ifdef FPGA_DEBUG -#define PRINTF(fmt,args...) printf (fmt ,##args) +#define PRINTF(fmt, args...) printf(fmt, ##args) #else -#define PRINTF(fmt,args...) +#define PRINTF(fmt, args...) #endif /* * If the SelectMap interface can be overrun by the processor, define - * CONFIG_SYS_FPGA_CHECK_BUSY and/or CONFIG_FPGA_DELAY in the board configuration - * file and add board-specific support for checking BUSY status. By default, - * assume that the SelectMap interface cannot be overrun. + * CONFIG_SYS_FPGA_CHECK_BUSY and/or CONFIG_FPGA_DELAY in the board + * configuration file and add board-specific support for checking BUSY status. + * By default, assume that the SelectMap interface cannot be overrun. */ #ifndef CONFIG_SYS_FPGA_CHECK_BUSY #undef CONFIG_SYS_FPGA_CHECK_BUSY @@ -65,7 +65,7 @@ * an XC2V1000, if anyone can ever get ahold of one. */ #ifndef CONFIG_SYS_FPGA_WAIT_INIT -#define CONFIG_SYS_FPGA_WAIT_INIT CONFIG_SYS_HZ/2 /* 500 ms */ +#define CONFIG_SYS_FPGA_WAIT_INIT CONFIG_SYS_HZ / 2 /* 500 ms */ #endif /* @@ -74,14 +74,14 @@ * clock frequencies (i.e. 66 MHz or less), BUSY monitoring is unnecessary. */ #ifndef CONFIG_SYS_FPGA_WAIT_BUSY -#define CONFIG_SYS_FPGA_WAIT_BUSY CONFIG_SYS_HZ/200 /* 5 ms*/ +#define CONFIG_SYS_FPGA_WAIT_BUSY CONFIG_SYS_HZ / 200 /* 5 ms*/ #endif /* Default timeout for waiting for FPGA to enter operational mode after * configuration data has been written. */ #ifndef CONFIG_SYS_FPGA_WAIT_CONFIG -#define CONFIG_SYS_FPGA_WAIT_CONFIG CONFIG_SYS_HZ/5 /* 200 ms */ +#define CONFIG_SYS_FPGA_WAIT_CONFIG CONFIG_SYS_HZ / 5 /* 200 ms */ #endif static int virtex2_ssm_load(xilinx_desc *desc, const void *buf, size_t bsize); @@ -97,18 +97,18 @@ static int virtex2_load(xilinx_desc *desc, const void *buf, size_t bsize, switch (desc->iface) { case slave_serial: - PRINTF ("%s: Launching Slave Serial Load\n", __FUNCTION__); + PRINTF("%s: Launching Slave Serial Load\n", __func__); ret_val = virtex2_ss_load(desc, buf, bsize); break; case slave_selectmap: - PRINTF ("%s: Launching Slave Parallel Load\n", __FUNCTION__); + PRINTF("%s: Launching Slave Parallel Load\n", __func__); ret_val = virtex2_ssm_load(desc, buf, bsize); break; default: - printf ("%s: Unsupported interface type, %d\n", - __FUNCTION__, desc->iface); + printf("%s: Unsupported interface type, %d\n", + __func__, desc->iface); } return ret_val; } @@ -119,18 +119,18 @@ static int virtex2_dump(xilinx_desc *desc, const void *buf, size_t bsize) switch (desc->iface) { case slave_serial: - PRINTF ("%s: Launching Slave Serial Dump\n", __FUNCTION__); + PRINTF("%s: Launching Slave Serial Dump\n", __func__); ret_val = virtex2_ss_dump(desc, buf, bsize); break; case slave_parallel: - PRINTF ("%s: Launching Slave Parallel Dump\n", __FUNCTION__); + PRINTF("%s: Launching Slave Parallel Dump\n", __func__); ret_val = virtex2_ssm_dump(desc, buf, bsize); break; default: - printf ("%s: Unsupported interface type, %d\n", - __FUNCTION__, desc->iface); + printf("%s: Unsupported interface type, %d\n", + __func__, desc->iface); } return ret_val; } @@ -159,135 +159,135 @@ static int virtex2_ssm_load(xilinx_desc *desc, const void *buf, size_t bsize) int ret_val = FPGA_FAIL; xilinx_virtex2_slave_selectmap_fns *fn = desc->iface_fns; - PRINTF ("%s:%d: Start with interface functions @ 0x%p\n", - __FUNCTION__, __LINE__, fn); + PRINTF("%s:%d: Start with interface functions @ 0x%p\n", + __func__, __LINE__, fn); if (fn) { size_t bytecount = 0; - unsigned char *data = (unsigned char *) buf; + unsigned char *data = (unsigned char *)buf; int cookie = desc->cookie; unsigned long ts; /* Gotta split this one up (so the stack won't blow??) */ - PRINTF ("%s:%d: Function Table:\n" - " base 0x%p\n" - " struct 0x%p\n" - " pre 0x%p\n" - " prog 0x%p\n" - " init 0x%p\n" - " error 0x%p\n", - __FUNCTION__, __LINE__, - &fn, fn, fn->pre, fn->pgm, fn->init, fn->err); - PRINTF (" clock 0x%p\n" - " cs 0x%p\n" - " write 0x%p\n" - " rdata 0x%p\n" - " wdata 0x%p\n" - " busy 0x%p\n" - " abort 0x%p\n" - " post 0x%p\n\n", - fn->clk, fn->cs, fn->wr, fn->rdata, fn->wdata, - fn->busy, fn->abort, fn->post); + PRINTF("%s:%d: Function Table:\n" + " base 0x%p\n" + " struct 0x%p\n" + " pre 0x%p\n" + " prog 0x%p\n" + " init 0x%p\n" + " error 0x%p\n", + __func__, __LINE__, + &fn, fn, fn->pre, fn->pgm, fn->init, fn->err); + PRINTF(" clock 0x%p\n" + " cs 0x%p\n" + " write 0x%p\n" + " rdata 0x%p\n" + " wdata 0x%p\n" + " busy 0x%p\n" + " abort 0x%p\n" + " post 0x%p\n\n", + fn->clk, fn->cs, fn->wr, fn->rdata, fn->wdata, + fn->busy, fn->abort, fn->post); #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK - printf ("Initializing FPGA Device %d...\n", cookie); + printf("Initializing FPGA Device %d...\n", cookie); #endif /* * Run the pre configuration function if there is one. */ - if (*fn->pre) { - (*fn->pre) (cookie); - } + if (*fn->pre) + (*fn->pre)(cookie); /* * Assert the program line. The minimum pulse width for - * Virtex II devices is 300 nS (Tprogram parameter in datasheet). - * There is no maximum value for the pulse width. Check to make - * sure that INIT_B goes low after assertion of PROG_B + * Virtex II devices is 300 nS (Tprogram parameter in + * datasheet). There is no maximum value for the pulse width. + * Check to make sure that INIT_B goes low after assertion of + * PROG_B */ - (*fn->pgm) (true, true, cookie); - udelay (10); - ts = get_timer (0); + (*fn->pgm)(true, true, cookie); + udelay(10); + ts = get_timer(0); do { - if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT_INIT) { - printf ("%s:%d: ** Timeout after %d ticks waiting for INIT" - " to assert.\n", __FUNCTION__, __LINE__, - CONFIG_SYS_FPGA_WAIT_INIT); - (*fn->abort) (cookie); + if (get_timer(ts) > CONFIG_SYS_FPGA_WAIT_INIT) { + printf("%s:%d: ** Timeout after %d ticks waiting for INIT to assert.\n", + __func__, __LINE__, + CONFIG_SYS_FPGA_WAIT_INIT); + (*fn->abort)(cookie); return FPGA_FAIL; } - } while (!(*fn->init) (cookie)); + } while (!(*fn->init)(cookie)); - (*fn->pgm) (false, true, cookie); - CONFIG_FPGA_DELAY (); - (*fn->clk) (true, true, cookie); + (*fn->pgm)(false, true, cookie); + CONFIG_FPGA_DELAY(); + (*fn->clk)(true, true, cookie); /* * Start a timer and wait for INIT_B to go high */ - ts = get_timer (0); + ts = get_timer(0); do { - CONFIG_FPGA_DELAY (); - if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT_INIT) { - printf ("%s:%d: ** Timeout after %d ticks waiting for INIT" - " to deassert.\n", __FUNCTION__, __LINE__, - CONFIG_SYS_FPGA_WAIT_INIT); - (*fn->abort) (cookie); + CONFIG_FPGA_DELAY(); + if (get_timer(ts) > CONFIG_SYS_FPGA_WAIT_INIT) { + printf("%s:%d: ** Timeout after %d ticks waiting for INIT to deassert.\n", + __func__, __LINE__, + CONFIG_SYS_FPGA_WAIT_INIT); + (*fn->abort)(cookie); return FPGA_FAIL; } - } while ((*fn->init) (cookie) && (*fn->busy) (cookie)); + } while ((*fn->init)(cookie) && (*fn->busy)(cookie)); - (*fn->wr) (true, true, cookie); - (*fn->cs) (true, true, cookie); + (*fn->wr)(true, true, cookie); + (*fn->cs)(true, true, cookie); - udelay (10000); + mdelay(10); /* * Load the data byte by byte */ while (bytecount < bsize) { #ifdef CONFIG_SYS_FPGA_CHECK_CTRLC - if (ctrlc ()) { - (*fn->abort) (cookie); + if (ctrlc()) { + (*fn->abort)(cookie); return FPGA_FAIL; } #endif - if ((*fn->done) (cookie) == FPGA_SUCCESS) { - PRINTF ("%s:%d:done went active early, bytecount = %d\n", - __FUNCTION__, __LINE__, bytecount); - break; + if ((*fn->done)(cookie) == FPGA_SUCCESS) { + PRINTF("%s:%d:done went active early, bytecount = %d\n", + __func__, __LINE__, bytecount); + break; } #ifdef CONFIG_SYS_FPGA_CHECK_ERROR - if ((*fn->init) (cookie)) { - printf ("\n%s:%d: ** Error: INIT asserted during" - " configuration\n", __FUNCTION__, __LINE__); - printf ("%d = buffer offset, %d = buffer size\n", - bytecount, bsize); - (*fn->abort) (cookie); + if ((*fn->init)(cookie)) { + printf("\n%s:%d: ** Error: INIT asserted during configuration\n", + __func__, __LINE__); + printf("%d = buffer offset, %d = buffer size\n", + bytecount, bsize); + (*fn->abort)(cookie); return FPGA_FAIL; } #endif - (*fn->wdata) (data[bytecount++], true, cookie); - CONFIG_FPGA_DELAY (); + (*fn->wdata)(data[bytecount++], true, cookie); + CONFIG_FPGA_DELAY(); /* * Cycle the clock pin */ - (*fn->clk) (false, true, cookie); - CONFIG_FPGA_DELAY (); - (*fn->clk) (true, true, cookie); + (*fn->clk)(false, true, cookie); + CONFIG_FPGA_DELAY(); + (*fn->clk)(true, true, cookie); #ifdef CONFIG_SYS_FPGA_CHECK_BUSY - ts = get_timer (0); - while ((*fn->busy) (cookie)) { - if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT_BUSY) { - printf ("%s:%d: ** Timeout after %d ticks waiting for" - " BUSY to deassert\n", - __FUNCTION__, __LINE__, CONFIG_SYS_FPGA_WAIT_BUSY); - (*fn->abort) (cookie); + ts = get_timer(0); + while ((*fn->busy)(cookie)) { + if (get_timer(ts) > CONFIG_SYS_FPGA_WAIT_BUSY) { + printf("%s:%d: ** Timeout after %d ticks waiting for BUSY to deassert\n", + __func__, __LINE__, + CONFIG_SYS_FPGA_WAIT_BUSY); + (*fn->abort)(cookie); return FPGA_FAIL; } } @@ -295,33 +295,35 @@ static int virtex2_ssm_load(xilinx_desc *desc, const void *buf, size_t bsize) #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK if (bytecount % (bsize / 40) == 0) - putc ('.'); + putc('.'); #endif } /* - * Finished writing the data; deassert FPGA CS_B and WRITE_B signals. + * Finished writing the data; deassert FPGA CS_B and WRITE_B + * signals. */ - CONFIG_FPGA_DELAY (); - (*fn->cs) (false, true, cookie); - (*fn->wr) (false, true, cookie); + CONFIG_FPGA_DELAY(); + (*fn->cs)(false, true, cookie); + (*fn->wr)(false, true, cookie); #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK - putc ('\n'); + putc('\n'); #endif /* - * Check for successful configuration. FPGA INIT_B and DONE should - * both be high upon successful configuration. + * Check for successful configuration. FPGA INIT_B and DONE + * should both be high upon successful configuration. */ - ts = get_timer (0); + ts = get_timer(0); ret_val = FPGA_SUCCESS; - while (((*fn->done) (cookie) == FPGA_FAIL) || (*fn->init) (cookie)) { - if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT_CONFIG) { - printf ("%s:%d: ** Timeout after %d ticks waiting for DONE to" - "assert and INIT to deassert\n", - __FUNCTION__, __LINE__, CONFIG_SYS_FPGA_WAIT_CONFIG); - (*fn->abort) (cookie); + while (((*fn->done)(cookie) == FPGA_FAIL) || + (*fn->init)(cookie)) { + if (get_timer(ts) > CONFIG_SYS_FPGA_WAIT_CONFIG) { + printf("%s:%d: ** Timeout after %d ticks waiting for DONE toassert and INIT to deassert\n", + __func__, __LINE__, + CONFIG_SYS_FPGA_WAIT_CONFIG); + (*fn->abort)(cookie); ret_val = FPGA_FAIL; break; } @@ -329,23 +331,23 @@ static int virtex2_ssm_load(xilinx_desc *desc, const void *buf, size_t bsize) if (ret_val == FPGA_SUCCESS) { #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK - printf ("Initialization of FPGA device %d complete\n", cookie); + printf("Initialization of FPGA device %d complete\n", + cookie); #endif /* * Run the post configuration function if there is one. */ - if (*fn->post) { - (*fn->post) (cookie); - } + if (*fn->post) + (*fn->post)(cookie); } else { #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK - printf ("** Initialization of FPGA device %d FAILED\n", - cookie); + printf("** Initialization of FPGA device %d FAILED\n", + cookie); #endif } } else { - printf ("%s:%d: NULL Interface function table!\n", - __FUNCTION__, __LINE__); + printf("%s:%d: NULL Interface function table!\n", + __func__, __LINE__); } return ret_val; } @@ -359,61 +361,61 @@ static int virtex2_ssm_dump(xilinx_desc *desc, const void *buf, size_t bsize) xilinx_virtex2_slave_selectmap_fns *fn = desc->iface_fns; if (fn) { - unsigned char *data = (unsigned char *) buf; + unsigned char *data = (unsigned char *)buf; size_t bytecount = 0; int cookie = desc->cookie; - printf ("Starting Dump of FPGA Device %d...\n", cookie); + printf("Starting Dump of FPGA Device %d...\n", cookie); - (*fn->cs) (true, true, cookie); - (*fn->clk) (true, true, cookie); + (*fn->cs)(true, true, cookie); + (*fn->clk)(true, true, cookie); while (bytecount < bsize) { #ifdef CONFIG_SYS_FPGA_CHECK_CTRLC - if (ctrlc ()) { - (*fn->abort) (cookie); + if (ctrlc()) { + (*fn->abort)(cookie); return FPGA_FAIL; } #endif /* * Cycle the clock and read the data */ - (*fn->clk) (false, true, cookie); - (*fn->clk) (true, true, cookie); - (*fn->rdata) (&(data[bytecount++]), cookie); + (*fn->clk)(false, true, cookie); + (*fn->clk)(true, true, cookie); + (*fn->rdata)(&data[bytecount++], cookie); #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK if (bytecount % (bsize / 40) == 0) - putc ('.'); + putc('.'); #endif } /* * Deassert CS_B and cycle the clock to deselect the device. */ - (*fn->cs) (false, false, cookie); - (*fn->clk) (false, true, cookie); - (*fn->clk) (true, true, cookie); + (*fn->cs)(false, false, cookie); + (*fn->clk)(false, true, cookie); + (*fn->clk)(true, true, cookie); #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK - putc ('\n'); + putc('\n'); #endif - puts ("Done.\n"); + puts("Done.\n"); } else { - printf ("%s:%d: NULL Interface function table!\n", - __FUNCTION__, __LINE__); + printf("%s:%d: NULL Interface function table!\n", + __func__, __LINE__); } return ret_val; } static int virtex2_ss_load(xilinx_desc *desc, const void *buf, size_t bsize) { - printf ("%s: Slave Serial Loading is unsupported\n", __FUNCTION__); + printf("%s: Slave Serial Loading is unsupported\n", __func__); return FPGA_FAIL; } static int virtex2_ss_dump(xilinx_desc *desc, const void *buf, size_t bsize) { - printf ("%s: Slave Serial Dumping is unsupported\n", __FUNCTION__); + printf("%s: Slave Serial Dumping is unsupported\n", __func__); return FPGA_FAIL; } From 25d63a367794d4c559d910a19566b7b15296c7a1 Mon Sep 17 00:00:00 2001 From: Robert Hancock Date: Tue, 18 Jun 2019 09:47:13 -0600 Subject: [PATCH 12/22] fpga: virtex2: added Kconfig option Add an option to allow this driver to be selected with Kconfig. As noted in the description, this driver should also work with many newer Xilinx FPGA families as the programming methods are essentially the same. Also added a missing FPGA_XILINX dependency to the similar Spartan 3 driver. Signed-off-by: Robert Hancock Signed-off-by: Michal Simek --- drivers/fpga/Kconfig | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig index 8f59193e3c..105a299812 100644 --- a/drivers/fpga/Kconfig +++ b/drivers/fpga/Kconfig @@ -58,9 +58,17 @@ config FPGA_ZYNQMPPL config FPGA_SPARTAN3 bool "Enable Spartan3 FPGA driver" + depends on FPGA_XILINX help Enable Spartan3 FPGA driver for loading in BIT format. +config FPGA_VIRTEX2 + bool "Enable Xilinx Virtex-II and later FPGA driver" + depends on FPGA_XILINX + help + Enable Virtex-II FPGA driver for loading in BIT format. This driver + also supports many newer Xilinx FPGA families. + config FPGA_ZYNQPL bool "Enable Xilinx FPGA for Zynq" depends on ARCH_ZYNQ From 3372081cfd25e2afaaa043d9da78f7de1cf84636 Mon Sep 17 00:00:00 2001 From: Robert Hancock Date: Tue, 18 Jun 2019 09:47:14 -0600 Subject: [PATCH 13/22] fpga: virtex2: Split out image writing from pre/post operations This is in preparation for adding slave serial programming support, which uses the same pre/post operations as slave SelectMAP, to avoid duplicating code. Signed-off-by: Robert Hancock Signed-off-by: Michal Simek --- drivers/fpga/virtex2.c | 349 +++++++++++++++++++++-------------------- 1 file changed, 183 insertions(+), 166 deletions(-) diff --git a/drivers/fpga/virtex2.c b/drivers/fpga/virtex2.c index b01a31f080..2383c69210 100644 --- a/drivers/fpga/virtex2.c +++ b/drivers/fpga/virtex2.c @@ -154,204 +154,221 @@ static int virtex2_info(xilinx_desc *desc) * INIT_B and DONE lines. If both are high, configuration has * succeeded. Congratulations! */ -static int virtex2_ssm_load(xilinx_desc *desc, const void *buf, size_t bsize) +static int virtex2_slave_pre(xilinx_virtex2_slave_selectmap_fns *fn, int cookie) { - int ret_val = FPGA_FAIL; - xilinx_virtex2_slave_selectmap_fns *fn = desc->iface_fns; + unsigned long ts; PRINTF("%s:%d: Start with interface functions @ 0x%p\n", __func__, __LINE__, fn); - if (fn) { - size_t bytecount = 0; - unsigned char *data = (unsigned char *)buf; - int cookie = desc->cookie; - unsigned long ts; + if (!fn) { + printf("%s:%d: NULL Interface function table!\n", + __func__, __LINE__); + return FPGA_FAIL; + } - /* Gotta split this one up (so the stack won't blow??) */ - PRINTF("%s:%d: Function Table:\n" - " base 0x%p\n" - " struct 0x%p\n" - " pre 0x%p\n" - " prog 0x%p\n" - " init 0x%p\n" - " error 0x%p\n", - __func__, __LINE__, - &fn, fn, fn->pre, fn->pgm, fn->init, fn->err); - PRINTF(" clock 0x%p\n" - " cs 0x%p\n" - " write 0x%p\n" - " rdata 0x%p\n" - " wdata 0x%p\n" - " busy 0x%p\n" - " abort 0x%p\n" - " post 0x%p\n\n", - fn->clk, fn->cs, fn->wr, fn->rdata, fn->wdata, - fn->busy, fn->abort, fn->post); + /* Gotta split this one up (so the stack won't blow??) */ + PRINTF("%s:%d: Function Table:\n" + " base 0x%p\n" + " struct 0x%p\n" + " pre 0x%p\n" + " prog 0x%p\n" + " init 0x%p\n" + " error 0x%p\n", + __func__, __LINE__, + &fn, fn, fn->pre, fn->pgm, fn->init, fn->err); + PRINTF(" clock 0x%p\n" + " cs 0x%p\n" + " write 0x%p\n" + " rdata 0x%p\n" + " wdata 0x%p\n" + " busy 0x%p\n" + " abort 0x%p\n" + " post 0x%p\n\n", + fn->clk, fn->cs, fn->wr, fn->rdata, fn->wdata, + fn->busy, fn->abort, fn->post); #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK - printf("Initializing FPGA Device %d...\n", cookie); + printf("Initializing FPGA Device %d...\n", cookie); #endif - /* - * Run the pre configuration function if there is one. - */ - if (*fn->pre) - (*fn->pre)(cookie); + /* + * Run the pre configuration function if there is one. + */ + if (*fn->pre) + (*fn->pre)(cookie); - /* - * Assert the program line. The minimum pulse width for - * Virtex II devices is 300 nS (Tprogram parameter in - * datasheet). There is no maximum value for the pulse width. - * Check to make sure that INIT_B goes low after assertion of - * PROG_B - */ - (*fn->pgm)(true, true, cookie); - udelay(10); - ts = get_timer(0); - do { - if (get_timer(ts) > CONFIG_SYS_FPGA_WAIT_INIT) { - printf("%s:%d: ** Timeout after %d ticks waiting for INIT to assert.\n", - __func__, __LINE__, - CONFIG_SYS_FPGA_WAIT_INIT); - (*fn->abort)(cookie); - return FPGA_FAIL; - } - } while (!(*fn->init)(cookie)); + /* + * Assert the program line. The minimum pulse width for + * Virtex II devices is 300 nS (Tprogram parameter in datasheet). + * There is no maximum value for the pulse width. Check to make + * sure that INIT_B goes low after assertion of PROG_B + */ + (*fn->pgm)(true, true, cookie); + udelay(10); + ts = get_timer(0); + do { + if (get_timer(ts) > CONFIG_SYS_FPGA_WAIT_INIT) { + printf("%s:%d: ** Timeout after %d ticks waiting for INIT to assert.\n", + __func__, __LINE__, CONFIG_SYS_FPGA_WAIT_INIT); + (*fn->abort)(cookie); + return FPGA_FAIL; + } + } while (!(*fn->init)(cookie)); - (*fn->pgm)(false, true, cookie); - CONFIG_FPGA_DELAY(); + (*fn->pgm)(false, true, cookie); + CONFIG_FPGA_DELAY(); + if (fn->clk) (*fn->clk)(true, true, cookie); - /* - * Start a timer and wait for INIT_B to go high - */ - ts = get_timer(0); - do { - CONFIG_FPGA_DELAY(); - if (get_timer(ts) > CONFIG_SYS_FPGA_WAIT_INIT) { - printf("%s:%d: ** Timeout after %d ticks waiting for INIT to deassert.\n", - __func__, __LINE__, - CONFIG_SYS_FPGA_WAIT_INIT); - (*fn->abort)(cookie); - return FPGA_FAIL; - } - } while ((*fn->init)(cookie) && (*fn->busy)(cookie)); + /* + * Start a timer and wait for INIT_B to go high + */ + ts = get_timer(0); + do { + CONFIG_FPGA_DELAY(); + if (get_timer(ts) > CONFIG_SYS_FPGA_WAIT_INIT) { + printf("%s:%d: ** Timeout after %d ticks waiting for INIT to deassert.\n", + __func__, __LINE__, CONFIG_SYS_FPGA_WAIT_INIT); + (*fn->abort)(cookie); + return FPGA_FAIL; + } + } while ((*fn->init)(cookie) && (*fn->busy)(cookie)); + if (fn->wr) (*fn->wr)(true, true, cookie); + if (fn->cs) (*fn->cs)(true, true, cookie); - mdelay(10); + mdelay(10); + return FPGA_SUCCESS; +} - /* - * Load the data byte by byte - */ - while (bytecount < bsize) { -#ifdef CONFIG_SYS_FPGA_CHECK_CTRLC - if (ctrlc()) { - (*fn->abort)(cookie); - return FPGA_FAIL; - } -#endif +static int virtex2_slave_post(xilinx_virtex2_slave_selectmap_fns *fn, + int cookie) +{ + int ret_val = FPGA_SUCCESS; + unsigned long ts; - if ((*fn->done)(cookie) == FPGA_SUCCESS) { - PRINTF("%s:%d:done went active early, bytecount = %d\n", - __func__, __LINE__, bytecount); - break; - } - -#ifdef CONFIG_SYS_FPGA_CHECK_ERROR - if ((*fn->init)(cookie)) { - printf("\n%s:%d: ** Error: INIT asserted during configuration\n", - __func__, __LINE__); - printf("%d = buffer offset, %d = buffer size\n", - bytecount, bsize); - (*fn->abort)(cookie); - return FPGA_FAIL; - } -#endif - - (*fn->wdata)(data[bytecount++], true, cookie); - CONFIG_FPGA_DELAY(); - - /* - * Cycle the clock pin - */ - (*fn->clk)(false, true, cookie); - CONFIG_FPGA_DELAY(); - (*fn->clk)(true, true, cookie); - -#ifdef CONFIG_SYS_FPGA_CHECK_BUSY - ts = get_timer(0); - while ((*fn->busy)(cookie)) { - if (get_timer(ts) > CONFIG_SYS_FPGA_WAIT_BUSY) { - printf("%s:%d: ** Timeout after %d ticks waiting for BUSY to deassert\n", - __func__, __LINE__, - CONFIG_SYS_FPGA_WAIT_BUSY); - (*fn->abort)(cookie); - return FPGA_FAIL; - } - } -#endif - -#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK - if (bytecount % (bsize / 40) == 0) - putc('.'); -#endif - } - - /* - * Finished writing the data; deassert FPGA CS_B and WRITE_B - * signals. - */ - CONFIG_FPGA_DELAY(); + /* + * Finished writing the data; deassert FPGA CS_B and WRITE_B signals. + */ + CONFIG_FPGA_DELAY(); + if (fn->cs) (*fn->cs)(false, true, cookie); + if (fn->wr) (*fn->wr)(false, true, cookie); #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK - putc('\n'); + putc('\n'); #endif + /* + * Check for successful configuration. FPGA INIT_B and DONE + * should both be high upon successful configuration. + */ + ts = get_timer(0); + ret_val = FPGA_SUCCESS; + while (((*fn->done)(cookie) == FPGA_FAIL) || + (*fn->init)(cookie)) { + if (get_timer(ts) > CONFIG_SYS_FPGA_WAIT_CONFIG) { + printf("%s:%d: ** Timeout after %d ticks waiting for DONE to assert and INIT to deassert\n", + __func__, __LINE__, CONFIG_SYS_FPGA_WAIT_CONFIG); + (*fn->abort)(cookie); + ret_val = FPGA_FAIL; + break; + } + } + + if (ret_val == FPGA_SUCCESS) { +#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK + printf("Initialization of FPGA device %d complete\n", cookie); +#endif /* - * Check for successful configuration. FPGA INIT_B and DONE - * should both be high upon successful configuration. + * Run the post configuration function if there is one. */ - ts = get_timer(0); - ret_val = FPGA_SUCCESS; - while (((*fn->done)(cookie) == FPGA_FAIL) || - (*fn->init)(cookie)) { - if (get_timer(ts) > CONFIG_SYS_FPGA_WAIT_CONFIG) { - printf("%s:%d: ** Timeout after %d ticks waiting for DONE toassert and INIT to deassert\n", - __func__, __LINE__, - CONFIG_SYS_FPGA_WAIT_CONFIG); - (*fn->abort)(cookie); - ret_val = FPGA_FAIL; - break; - } - } - - if (ret_val == FPGA_SUCCESS) { -#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK - printf("Initialization of FPGA device %d complete\n", - cookie); -#endif - /* - * Run the post configuration function if there is one. - */ - if (*fn->post) - (*fn->post)(cookie); - } else { -#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK - printf("** Initialization of FPGA device %d FAILED\n", - cookie); -#endif - } + if (*fn->post) + (*fn->post)(cookie); } else { - printf("%s:%d: NULL Interface function table!\n", - __func__, __LINE__); +#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK + printf("** Initialization of FPGA device %d FAILED\n", + cookie); +#endif } return ret_val; } +static int virtex2_ssm_load(xilinx_desc *desc, const void *buf, size_t bsize) +{ + int ret_val = FPGA_FAIL; + xilinx_virtex2_slave_selectmap_fns *fn = desc->iface_fns; + size_t bytecount = 0; + unsigned char *data = (unsigned char *)buf; + int cookie = desc->cookie; + + ret_val = virtex2_slave_pre(fn, cookie); + if (ret_val != FPGA_SUCCESS) + return ret_val; + + /* + * Load the data byte by byte + */ + while (bytecount < bsize) { +#ifdef CONFIG_SYS_FPGA_CHECK_CTRLC + if (ctrlc()) { + (*fn->abort)(cookie); + return FPGA_FAIL; + } +#endif + + if ((*fn->done)(cookie) == FPGA_SUCCESS) { + PRINTF("%s:%d:done went active early, bytecount = %d\n", + __func__, __LINE__, bytecount); + break; + } + +#ifdef CONFIG_SYS_FPGA_CHECK_ERROR + if ((*fn->init)(cookie)) { + printf("\n%s:%d: ** Error: INIT asserted during configuration\n", + __func__, __LINE__); + printf("%zu = buffer offset, %zu = buffer size\n", + bytecount, bsize); + (*fn->abort)(cookie); + return FPGA_FAIL; + } +#endif + + (*fn->wdata)(data[bytecount++], true, cookie); + CONFIG_FPGA_DELAY(); + + /* + * Cycle the clock pin + */ + (*fn->clk)(false, true, cookie); + CONFIG_FPGA_DELAY(); + (*fn->clk)(true, true, cookie); + +#ifdef CONFIG_SYS_FPGA_CHECK_BUSY + ts = get_timer(0); + while ((*fn->busy)(cookie)) { + if (get_timer(ts) > CONFIG_SYS_FPGA_WAIT_BUSY) { + printf("%s:%d: ** Timeout after %d ticks waiting for BUSY to deassert\n", + __func__, __LINE__, + CONFIG_SYS_FPGA_WAIT_BUSY); + (*fn->abort)(cookie); + return FPGA_FAIL; + } + } +#endif + +#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK + if (bytecount % (bsize / 40) == 0) + putc('.'); +#endif + } + + return virtex2_slave_post(fn, cookie); +} + /* * Read the FPGA configuration data */ From a0549f7390d33ec522de3a53e6031189d46a9ce7 Mon Sep 17 00:00:00 2001 From: Robert Hancock Date: Tue, 18 Jun 2019 09:47:15 -0600 Subject: [PATCH 14/22] fpga: virtex2: Add additional clock cycles after DONE assertion Some Xilinx FPGA configuration options can result in the startup sequence extending past the end of the FPGA bitstream. Continue applying CCLK clock cycles for 8 cycles after DONE is asserted in order to ensure the startup sequence is complete, as recommended by Xilinx. Signed-off-by: Robert Hancock Signed-off-by: Michal Simek --- drivers/fpga/virtex2.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/drivers/fpga/virtex2.c b/drivers/fpga/virtex2.c index 2383c69210..502824424c 100644 --- a/drivers/fpga/virtex2.c +++ b/drivers/fpga/virtex2.c @@ -247,6 +247,7 @@ static int virtex2_slave_post(xilinx_virtex2_slave_selectmap_fns *fn, int cookie) { int ret_val = FPGA_SUCCESS; + int num_done = 0; unsigned long ts; /* @@ -264,12 +265,18 @@ static int virtex2_slave_post(xilinx_virtex2_slave_selectmap_fns *fn, /* * Check for successful configuration. FPGA INIT_B and DONE - * should both be high upon successful configuration. + * should both be high upon successful configuration. Continue pulsing + * clock with data set to all ones until DONE is asserted and for 8 + * clock cycles afterwards. */ ts = get_timer(0); - ret_val = FPGA_SUCCESS; - while (((*fn->done)(cookie) == FPGA_FAIL) || - (*fn->init)(cookie)) { + while (true) { + if ((*fn->done)(cookie) == FPGA_SUCCESS && + !((*fn->init)(cookie))) { + if (num_done++ >= 8) + break; + } + if (get_timer(ts) > CONFIG_SYS_FPGA_WAIT_CONFIG) { printf("%s:%d: ** Timeout after %d ticks waiting for DONE to assert and INIT to deassert\n", __func__, __LINE__, CONFIG_SYS_FPGA_WAIT_CONFIG); @@ -277,6 +284,11 @@ static int virtex2_slave_post(xilinx_virtex2_slave_selectmap_fns *fn, ret_val = FPGA_FAIL; break; } + (*fn->wdata) (0xff, true, cookie); + CONFIG_FPGA_DELAY(); + (*fn->clk) (false, true, cookie); + CONFIG_FPGA_DELAY(); + (*fn->clk) (true, true, cookie); } if (ret_val == FPGA_SUCCESS) { From 175dccd710cc87f6046d91cc64896195e3b1edd5 Mon Sep 17 00:00:00 2001 From: Robert Hancock Date: Tue, 18 Jun 2019 09:47:16 -0600 Subject: [PATCH 15/22] fpga: virtex2: Add slave serial programming support This adds support for slave serial programming, in addition to the previously supported slave SelectMAP mode. There are two ways that this can be used: -Using the clk and wdata callbacks in order to write image data one bit at a time using pure bit-banging. This works, but is rather painfully slow with typical image sizes. -By specifying the wbulkdata callback instead, the image loading process can be offloaded to SPI hardware. In this mode the clk and wdata callbacks do not need to be specified. This allows the image to be loaded much faster, taking only a few seconds with even relatively large images. Slave serial programming has been tested on the Kintex-7 series of FPGAs. Signed-off-by: Robert Hancock Signed-off-by: Michal Simek --- drivers/fpga/virtex2.c | 96 ++++++++++++++++++++++++++++++++++++------ include/virtex2.h | 13 ++---- 2 files changed, 86 insertions(+), 23 deletions(-) diff --git a/drivers/fpga/virtex2.c b/drivers/fpga/virtex2.c index 502824424c..395736875f 100644 --- a/drivers/fpga/virtex2.c +++ b/drivers/fpga/virtex2.c @@ -3,6 +3,8 @@ * (C) Copyright 2002 * Rich Ireland, Enterasys Networks, rireland@enterasys.com. * Keith Outwater, keith_outwater@mvis.com + * + * Copyright (c) 2019 SED Systems, a division of Calian Ltd. */ /* @@ -141,8 +143,8 @@ static int virtex2_info(xilinx_desc *desc) } /* - * Virtex-II Slave SelectMap configuration loader. Configuration via - * SelectMap is as follows: + * Virtex-II Slave SelectMap or Serial configuration loader. Configuration + * is as follows: * 1. Set the FPGA's PROG_B line low. * 2. Set the FPGA's PROG_B line high. Wait for INIT_B to go high. * 3. Write data to the SelectMap port. If INIT_B goes low at any time @@ -154,7 +156,7 @@ static int virtex2_info(xilinx_desc *desc) * INIT_B and DONE lines. If both are high, configuration has * succeeded. Congratulations! */ -static int virtex2_slave_pre(xilinx_virtex2_slave_selectmap_fns *fn, int cookie) +static int virtex2_slave_pre(xilinx_virtex2_slave_fns *fn, int cookie) { unsigned long ts; @@ -243,7 +245,7 @@ static int virtex2_slave_pre(xilinx_virtex2_slave_selectmap_fns *fn, int cookie) return FPGA_SUCCESS; } -static int virtex2_slave_post(xilinx_virtex2_slave_selectmap_fns *fn, +static int virtex2_slave_post(xilinx_virtex2_slave_fns *fn, int cookie) { int ret_val = FPGA_SUCCESS; @@ -284,11 +286,16 @@ static int virtex2_slave_post(xilinx_virtex2_slave_selectmap_fns *fn, ret_val = FPGA_FAIL; break; } - (*fn->wdata) (0xff, true, cookie); - CONFIG_FPGA_DELAY(); - (*fn->clk) (false, true, cookie); - CONFIG_FPGA_DELAY(); - (*fn->clk) (true, true, cookie); + if (fn->wbulkdata) { + unsigned char dummy = 0xff; + (*fn->wbulkdata)(&dummy, 1, true, cookie); + } else { + (*fn->wdata)(0xff, true, cookie); + CONFIG_FPGA_DELAY(); + (*fn->clk)(false, true, cookie); + CONFIG_FPGA_DELAY(); + (*fn->clk)(true, true, cookie); + } } if (ret_val == FPGA_SUCCESS) { @@ -312,7 +319,7 @@ static int virtex2_slave_post(xilinx_virtex2_slave_selectmap_fns *fn, static int virtex2_ssm_load(xilinx_desc *desc, const void *buf, size_t bsize) { int ret_val = FPGA_FAIL; - xilinx_virtex2_slave_selectmap_fns *fn = desc->iface_fns; + xilinx_virtex2_slave_fns *fn = desc->iface_fns; size_t bytecount = 0; unsigned char *data = (unsigned char *)buf; int cookie = desc->cookie; @@ -387,7 +394,7 @@ static int virtex2_ssm_load(xilinx_desc *desc, const void *buf, size_t bsize) static int virtex2_ssm_dump(xilinx_desc *desc, const void *buf, size_t bsize) { int ret_val = FPGA_FAIL; - xilinx_virtex2_slave_selectmap_fns *fn = desc->iface_fns; + xilinx_virtex2_slave_fns *fn = desc->iface_fns; if (fn) { unsigned char *data = (unsigned char *)buf; @@ -438,8 +445,71 @@ static int virtex2_ssm_dump(xilinx_desc *desc, const void *buf, size_t bsize) static int virtex2_ss_load(xilinx_desc *desc, const void *buf, size_t bsize) { - printf("%s: Slave Serial Loading is unsupported\n", __func__); - return FPGA_FAIL; + int ret_val = FPGA_FAIL; + xilinx_virtex2_slave_fns *fn = desc->iface_fns; + unsigned char *data = (unsigned char *)buf; + int cookie = desc->cookie; + + ret_val = virtex2_slave_pre(fn, cookie); + if (ret_val != FPGA_SUCCESS) + return ret_val; + + if (fn->wbulkdata) { + /* Load the data in a single chunk */ + (*fn->wbulkdata)(data, bsize, true, cookie); + } else { + size_t bytecount = 0; + + /* + * Load the data bit by bit + */ + while (bytecount < bsize) { + unsigned char curr_data = data[bytecount++]; + int bit; + +#ifdef CONFIG_SYS_FPGA_CHECK_CTRLC + if (ctrlc()) { + (*fn->abort) (cookie); + return FPGA_FAIL; + } +#endif + + if ((*fn->done)(cookie) == FPGA_SUCCESS) { + PRINTF("%s:%d:done went active early, bytecount = %d\n", + __func__, __LINE__, bytecount); + break; + } + +#ifdef CONFIG_SYS_FPGA_CHECK_ERROR + if ((*fn->init)(cookie)) { + printf("\n%s:%d: ** Error: INIT asserted during configuration\n", + __func__, __LINE__); + printf("%zu = buffer offset, %zu = buffer size\n", + bytecount, bsize); + (*fn->abort)(cookie); + return FPGA_FAIL; + } +#endif + + for (bit = 7; bit >= 0; --bit) { + unsigned char curr_bit = (curr_data >> bit) & 1; + (*fn->wdata)(curr_bit, true, cookie); + CONFIG_FPGA_DELAY(); + (*fn->clk)(false, true, cookie); + CONFIG_FPGA_DELAY(); + (*fn->clk)(true, true, cookie); + } + + /* Slave serial never uses a busy pin */ + +#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK + if (bytecount % (bsize / 40) == 0) + putc('.'); +#endif + } + } + + return virtex2_slave_post(fn, cookie); } static int virtex2_ss_dump(xilinx_desc *desc, const void *buf, size_t bsize) diff --git a/include/virtex2.h b/include/virtex2.h index a48113060e..7e8d93f24d 100644 --- a/include/virtex2.h +++ b/include/virtex2.h @@ -11,7 +11,7 @@ #include /* - * Slave SelectMap Implementation function table. + * Slave SelectMap or Serial Implementation function table. */ typedef struct { xilinx_pre_fn pre; @@ -24,18 +24,11 @@ typedef struct { xilinx_wr_fn wr; xilinx_rdata_fn rdata; xilinx_wdata_fn wdata; + xilinx_bwr_fn wbulkdata; xilinx_busy_fn busy; xilinx_abort_fn abort; xilinx_post_fn post; -} xilinx_virtex2_slave_selectmap_fns; - -/* Slave Serial Implementation function table */ -typedef struct { - xilinx_pgm_fn pgm; - xilinx_clk_fn clk; - xilinx_rdata_fn rdata; - xilinx_wdata_fn wdata; -} xilinx_virtex2_slave_serial_fns; +} xilinx_virtex2_slave_fns; #if defined(CONFIG_FPGA_VIRTEX2) extern struct xilinx_fpga_op virtex2_op; From 216dad75073fb11442448147738112e4c8dc6a1f Mon Sep 17 00:00:00 2001 From: Luca Ceresoli Date: Thu, 20 Jun 2019 18:18:16 +0200 Subject: [PATCH 16/22] arm64: zynqmp: add MAINTAINERS entry for Avnet UltraZed-EV The board was added without adding a MAINTAINERS entry. Fixes: $ ./tools/genboardscfg.py -f WARNING: no status info for 'avnet_ultrazedev_cc_v1_0_ultrazedev_som_v1_0' WARNING: no maintainers for 'avnet_ultrazedev_cc_v1_0_ultrazedev_som_v1_0' $ Reported-by: Michal Simek Signed-off-by: Luca Ceresoli Signed-off-by: Michal Simek --- board/xilinx/zynqmp/MAINTAINERS | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/board/xilinx/zynqmp/MAINTAINERS b/board/xilinx/zynqmp/MAINTAINERS index efc1d356d6..04fc7f32fe 100644 --- a/board/xilinx/zynqmp/MAINTAINERS +++ b/board/xilinx/zynqmp/MAINTAINERS @@ -7,3 +7,9 @@ F: board/xilinx/zynqmp/ F: include/configs/xilinx_zynqmp* F: configs/xilinx_zynqmp* F: configs/avnet_ultra96_rev1_defconfig + +ARM ZYNQMP AVNET ULTRAZED EV BOARD +M: Luca Ceresoli +S: Maintained +F: arch/arm/dts/avnet-ultrazedev-* +F: configs/avnet_ultrazedev_cc_v1_0_ultrazedev_som_v1_0_defconfig From 3b2a595fc6595ea35f980b5924ebffecd3a875a5 Mon Sep 17 00:00:00 2001 From: Alexander Dahl Date: Fri, 28 Jun 2019 14:41:20 +0200 Subject: [PATCH 17/22] fpga: altera: Add some more device sizes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There seems to be only one place, where this is checked against: `altera_validate()`. It should be non zero. Otherwise it is only used to display it, so it probably does not really matter at the moment. But we had the datasheet open anyway … Sizes in datasheet are bit counts, display here is in bytes. Signed-off-by: Alexander Dahl --- include/ACEX1K.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/include/ACEX1K.h b/include/ACEX1K.h index 9814bba284..7c5253c66c 100644 --- a/include/ACEX1K.h +++ b/include/ACEX1K.h @@ -60,6 +60,16 @@ typedef struct { #define Altera_EP2C35_SIZE 883905 #define Altera_EP3C5_SIZE 368011 /* .rbf size in bytes */ +#define ALTERA_EP4CE6_SIZE 368011 /* 2944088 Bits */ +#define ALTERA_EP4CE10_SIZE 368011 /* 2944088 Bits */ +#define ALTERA_EP4CE15_SIZE 510856 /* 4086848 Bits */ +#define ALTERA_EP4CE22_SIZE 718569 /* 5748552 Bits */ +#define ALTERA_EP4CE30_SIZE 1191788 /* 9534304 Bits */ +#define ALTERA_EP4CE40_SIZE 1191788 /* 9534304 Bits */ +#define ALTERA_EP4CE55_SIZE 1861195 /* 14889560 Bits */ +#define ALTERA_EP4CE75_SIZE 2495719 /* 19965752 Bits */ +#define ALTERA_EP4CE115_SIZE 3571462 /* 28571696 Bits */ + /* Descriptor Macros *********************************************************************/ /* ACEX1K devices */ From bb2c0fa03e80d4ff131eda28eabbd986f3864107 Mon Sep 17 00:00:00 2001 From: Alexander Dahl Date: Fri, 28 Jun 2019 14:41:21 +0200 Subject: [PATCH 18/22] fpga: altera: cyclon2: Fix most checkpatch warnings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Nothing special, but done before further cleanup. * spacing * braces * __FUNCTION__ → __func__ Suggested-by: Michal Simek Signed-off-by: Alexander Dahl --- drivers/fpga/cyclon2.c | 81 ++++++++++++++++++++---------------------- 1 file changed, 39 insertions(+), 42 deletions(-) diff --git a/drivers/fpga/cyclon2.c b/drivers/fpga/cyclon2.c index 6755956e85..99a64d437c 100644 --- a/drivers/fpga/cyclon2.c +++ b/drivers/fpga/cyclon2.c @@ -11,9 +11,9 @@ /* Define FPGA_DEBUG to get debug printf's */ #ifdef FPGA_DEBUG -#define PRINTF(fmt,args...) printf (fmt ,##args) +#define PRINTF(fmt, args...) printf(fmt, ##args) #else -#define PRINTF(fmt,args...) +#define PRINTF(fmt, args...) #endif /* Note: The assumption is that we cannot possibly run fast enough to @@ -26,7 +26,7 @@ #endif #ifndef CONFIG_SYS_FPGA_WAIT -#define CONFIG_SYS_FPGA_WAIT CONFIG_SYS_HZ/10 /* 100 ms */ +#define CONFIG_SYS_FPGA_WAIT CONFIG_SYS_HZ / 10 /* 100 ms */ #endif static int CYC2_ps_load(Altera_desc *desc, const void *buf, size_t bsize); @@ -41,8 +41,8 @@ int CYC2_load(Altera_desc *desc, const void *buf, size_t bsize) switch (desc->iface) { case passive_serial: - PRINTF ("%s: Launching Passive Serial Loader\n", __FUNCTION__); - ret_val = CYC2_ps_load (desc, buf, bsize); + PRINTF("%s: Launching Passive Serial Loader\n", __func__); + ret_val = CYC2_ps_load(desc, buf, bsize); break; case fast_passive_parallel: @@ -50,16 +50,16 @@ int CYC2_load(Altera_desc *desc, const void *buf, size_t bsize) * done in the write() callback. Use the existing PS load * function for FPP, too. */ - PRINTF ("%s: Launching Fast Passive Parallel Loader\n", - __FUNCTION__); + PRINTF("%s: Launching Fast Passive Parallel Loader\n", + __func__); ret_val = CYC2_ps_load(desc, buf, bsize); break; /* Add new interface types here */ default: - printf ("%s: Unsupported interface type, %d\n", - __FUNCTION__, desc->iface); + printf("%s: Unsupported interface type, %d\n", + __func__, desc->iface); } return ret_val; @@ -71,59 +71,58 @@ int CYC2_dump(Altera_desc *desc, const void *buf, size_t bsize) switch (desc->iface) { case passive_serial: - PRINTF ("%s: Launching Passive Serial Dump\n", __FUNCTION__); - ret_val = CYC2_ps_dump (desc, buf, bsize); + PRINTF("%s: Launching Passive Serial Dump\n", __func__); + ret_val = CYC2_ps_dump(desc, buf, bsize); break; /* Add new interface types here */ default: - printf ("%s: Unsupported interface type, %d\n", - __FUNCTION__, desc->iface); + printf("%s: Unsupported interface type, %d\n", + __func__, desc->iface); } return ret_val; } -int CYC2_info( Altera_desc *desc ) +int CYC2_info(Altera_desc *desc) { return FPGA_SUCCESS; } /* ------------------------------------------------------------------------- */ -/* CYCLON2 Passive Serial Generic Implementation */ +/* CYCLON2 Passive Serial Generic Implementation */ static int CYC2_ps_load(Altera_desc *desc, const void *buf, size_t bsize) { int ret_val = FPGA_FAIL; /* assume the worst */ Altera_CYC2_Passive_Serial_fns *fn = desc->iface_fns; int ret = 0; - PRINTF ("%s: start with interface functions @ 0x%p\n", - __FUNCTION__, fn); + PRINTF("%s: start with interface functions @ 0x%p\n", + __func__, fn); if (fn) { int cookie = desc->cookie; /* make a local copy */ unsigned long ts; /* timestamp */ - PRINTF ("%s: Function Table:\n" + PRINTF("%s: Function Table:\n" "ptr:\t0x%p\n" "struct: 0x%p\n" "config:\t0x%p\n" "status:\t0x%p\n" "write:\t0x%p\n" "done:\t0x%p\n\n", - __FUNCTION__, &fn, fn, fn->config, fn->status, + __func__, &fn, fn, fn->config, fn->status, fn->write, fn->done); #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK - printf ("Loading FPGA Device %d...", cookie); + printf("Loading FPGA Device %d...", cookie); #endif /* * Run the pre configuration function if there is one. */ - if (*fn->pre) { + if (*fn->pre) (*fn->pre) (cookie); - } /* Establish the initial state */ (*fn->config) (false, true, cookie); /* De-assert nCONFIG */ @@ -133,22 +132,23 @@ static int CYC2_ps_load(Altera_desc *desc, const void *buf, size_t bsize) udelay(2); /* T_cfg > 2us */ /* Wait for nSTATUS to be asserted */ - ts = get_timer (0); /* get current time */ + ts = get_timer(0); /* get current time */ do { - CONFIG_FPGA_DELAY (); - if (get_timer (ts) > CONFIG_SYS_FPGA_WAIT) { /* check the time */ - puts ("** Timeout waiting for STATUS to go high.\n"); + CONFIG_FPGA_DELAY(); + if (get_timer(ts) > CONFIG_SYS_FPGA_WAIT) { + /* check the time */ + puts("** Timeout waiting for STATUS to go high.\n"); (*fn->abort) (cookie); return FPGA_FAIL; } } while (!(*fn->status) (cookie)); /* Get ready for the burn */ - CONFIG_FPGA_DELAY (); + CONFIG_FPGA_DELAY(); ret = (*fn->write) (buf, bsize, true, cookie); if (ret) { - puts ("** Write failed.\n"); + puts("** Write failed.\n"); (*fn->abort) (cookie); return FPGA_FAIL; } @@ -156,20 +156,20 @@ static int CYC2_ps_load(Altera_desc *desc, const void *buf, size_t bsize) puts(" OK? ..."); #endif - CONFIG_FPGA_DELAY (); + CONFIG_FPGA_DELAY(); #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK - putc (' '); /* terminate the dotted line */ + putc(' '); /* terminate the dotted line */ #endif /* * Checking FPGA's CONF_DONE signal - correctly booted ? */ - if ( ! (*fn->done) (cookie) ) { - puts ("** Booting failed! CONF_DONE is still deasserted.\n"); + if (!(*fn->done) (cookie)) { + puts("** Booting failed! CONF_DONE is still deasserted.\n"); (*fn->abort) (cookie); - return (FPGA_FAIL); + return FPGA_FAIL; } #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK puts(" OK\n"); @@ -178,17 +178,15 @@ static int CYC2_ps_load(Altera_desc *desc, const void *buf, size_t bsize) ret_val = FPGA_SUCCESS; #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK - if (ret_val == FPGA_SUCCESS) { - puts ("Done.\n"); - } - else { - puts ("Fail.\n"); - } + if (ret_val == FPGA_SUCCESS) + puts("Done.\n"); + else + puts("Fail.\n"); #endif (*fn->post) (cookie); } else { - printf ("%s: NULL Interface function table!\n", __FUNCTION__); + printf("%s: NULL Interface function table!\n", __func__); } return ret_val; @@ -198,7 +196,6 @@ static int CYC2_ps_dump(Altera_desc *desc, const void *buf, size_t bsize) { /* Readback is only available through the Slave Parallel and */ /* boundary-scan interfaces. */ - printf ("%s: Passive Serial Dumping is unavailable\n", - __FUNCTION__); + printf("%s: Passive Serial Dumping is unavailable\n", __func__); return FPGA_FAIL; } From 3911b19cac9dc7d11e7d9e79e80fb62eced74ba7 Mon Sep 17 00:00:00 2001 From: Alexander Dahl Date: Fri, 28 Jun 2019 14:41:22 +0200 Subject: [PATCH 19/22] fpga: altera: cyclon2: Fix indentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some code parts stood too far left … Signed-off-by: Alexander Dahl --- drivers/fpga/cyclon2.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/drivers/fpga/cyclon2.c b/drivers/fpga/cyclon2.c index 99a64d437c..ab979b017a 100644 --- a/drivers/fpga/cyclon2.c +++ b/drivers/fpga/cyclon2.c @@ -162,28 +162,28 @@ static int CYC2_ps_load(Altera_desc *desc, const void *buf, size_t bsize) putc(' '); /* terminate the dotted line */ #endif - /* - * Checking FPGA's CONF_DONE signal - correctly booted ? - */ + /* + * Checking FPGA's CONF_DONE signal - correctly booted ? + */ - if (!(*fn->done) (cookie)) { - puts("** Booting failed! CONF_DONE is still deasserted.\n"); - (*fn->abort) (cookie); - return FPGA_FAIL; - } + if (!(*fn->done) (cookie)) { + puts("** Booting failed! CONF_DONE is still deasserted.\n"); + (*fn->abort) (cookie); + return FPGA_FAIL; + } #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK - puts(" OK\n"); + puts(" OK\n"); #endif - ret_val = FPGA_SUCCESS; + ret_val = FPGA_SUCCESS; #ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK - if (ret_val == FPGA_SUCCESS) - puts("Done.\n"); - else - puts("Fail.\n"); + if (ret_val == FPGA_SUCCESS) + puts("Done.\n"); + else + puts("Fail.\n"); #endif - (*fn->post) (cookie); + (*fn->post) (cookie); } else { printf("%s: NULL Interface function table!\n", __func__); From b283d6ba67a7b4c5914949ef1d756bf88cb3a0e4 Mon Sep 17 00:00:00 2001 From: Alexander Dahl Date: Fri, 28 Jun 2019 14:41:23 +0200 Subject: [PATCH 20/22] fpga: altera: cyclon2: Check function pointer before calling As already done for the 'pre' function, a check is added to not follow a NULL pointer, if somebody has not assigned a 'post' function. Signed-off-by: Alexander Dahl --- drivers/fpga/cyclon2.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/fpga/cyclon2.c b/drivers/fpga/cyclon2.c index ab979b017a..c929cd2cc5 100644 --- a/drivers/fpga/cyclon2.c +++ b/drivers/fpga/cyclon2.c @@ -183,8 +183,12 @@ static int CYC2_ps_load(Altera_desc *desc, const void *buf, size_t bsize) else puts("Fail.\n"); #endif - (*fn->post) (cookie); + /* + * Run the post configuration function if there is one. + */ + if (*fn->post) + (*fn->post) (cookie); } else { printf("%s: NULL Interface function table!\n", __func__); } From 5a4675a9171785475b49eb8ad0778dc28a6d8746 Mon Sep 17 00:00:00 2001 From: Alexander Dahl Date: Fri, 28 Jun 2019 14:41:24 +0200 Subject: [PATCH 21/22] cmd: fpga: Change return value to avoid printing usage text In cmd/fpga.c the commands should return enum command_ret_t, e.g. CMD_RET_USAGE, CMD_RET_SUCCESS, or CMD_RET_FAILURE. What they actually do is passing a return value from different 'fpga_' functions. Passing on a return value of -1 from a called function leads to printing out usage text. In case of actually correct usage with correctly specified parameters but some fail at runtime printing out that usage text is distracting. The reason is most 'fpga_' functions return either FPGA_SUCCESS or FPGA_FAIL, the latter was equal to -1 which is the same value as CMD_RET_USAGE. So just passing on FPGA_FAIL lead to printing out usage. We should only return CMD_RET_USAGE in cases, where the user sent wrong input. Every other case should return CMD_RET_SUCCESS or CMD_RET_FAILURE, and not simply pass an error code. Simply changing FPGA_FAIL from -1 to 1 gets the job done. Suggested-by: Michal Simek Signed-off-by: Alexander Dahl --- include/fpga.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/fpga.h b/include/fpga.h index 51de5c55f8..ec5144334d 100644 --- a/include/fpga.h +++ b/include/fpga.h @@ -15,7 +15,7 @@ /* fpga_xxxx function return value definitions */ #define FPGA_SUCCESS 0 -#define FPGA_FAIL -1 +#define FPGA_FAIL 1 /* device numbers must be non-negative */ #define FPGA_INVALID_DEVICE -1 From cd228cc04afc79c1383be707d0b812f45dfd53aa Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Tue, 30 Jul 2019 17:07:27 +0200 Subject: [PATCH 22/22] arm64: zynqmp: Do not include pm_cfg_obj.o when SPL is disabled xilinx_zynqmp_mini configuration is throwing build error: readlink: missing operand Try 'readlink --help' for more information. because CONFIG_ZYNQMP_SPL_PM_CFG_OBJ_FILE is not defined at all and Makefile pass ifneq condition. Add SPL_BUILD dependency which is also reflected in Kconfig. Signed-off-by: Michal Simek --- board/xilinx/zynqmp/Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/board/xilinx/zynqmp/Makefile b/board/xilinx/zynqmp/Makefile index b4d39edc11..5ace6cc1b4 100644 --- a/board/xilinx/zynqmp/Makefile +++ b/board/xilinx/zynqmp/Makefile @@ -33,10 +33,12 @@ ifneq ($(call ifdef_any_of, CONFIG_ZYNQMP_PSU_INIT_ENABLED CONFIG_SPL_BUILD),) obj-y += $(init-objs) endif +ifdef CONFIG_SPL_BUILD ifneq ($(CONFIG_ZYNQMP_SPL_PM_CFG_OBJ_FILE),"") obj-$(CONFIG_SPL_BUILD) += pm_cfg_obj.o $(obj)/pm_cfg_obj.o: $(shell cd $(srctree); readlink -f $(CONFIG_ZYNQMP_SPL_PM_CFG_OBJ_FILE)) FORCE endif +endif obj-$(CONFIG_MMC_SDHCI_ZYNQ) += tap_delays.o