From d509f8dc5ab95f2be923ff794160213d4347b4b3 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Thu, 21 Jun 2018 09:21:35 +0200 Subject: [PATCH 01/55] gpio: zynq: Use live-tree function Use live-tree function. Signed-off-by: Michal Simek --- drivers/gpio/zynq_gpio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpio/zynq_gpio.c b/drivers/gpio/zynq_gpio.c index 8d84e3f..afba458 100644 --- a/drivers/gpio/zynq_gpio.c +++ b/drivers/gpio/zynq_gpio.c @@ -374,7 +374,7 @@ static int zynq_gpio_ofdata_to_platdata(struct udevice *dev) { struct zynq_gpio_privdata *priv = dev_get_priv(dev); - priv->base = devfdt_get_addr(dev); + priv->base = (phys_addr_t)dev_read_addr(dev); return 0; } From 24e2b20132a9ecba851e0eadd312528a7307e8a2 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Thu, 21 Jun 2018 14:40:09 +0200 Subject: [PATCH 02/55] arm64: zynqmp: Enable usb mass storage command and functionality Enable ums command for zcu100 to enable mass storage gadget. Tested with ums 0 mmc 0 (for SD) and ums 0 usb 0 (for USB flashdisk). Signed-off-by: Michal Simek --- configs/xilinx_zynqmp_zcu100_revC_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/configs/xilinx_zynqmp_zcu100_revC_defconfig b/configs/xilinx_zynqmp_zcu100_revC_defconfig index 7ddb835..154fffb 100644 --- a/configs/xilinx_zynqmp_zcu100_revC_defconfig +++ b/configs/xilinx_zynqmp_zcu100_revC_defconfig @@ -34,6 +34,7 @@ CONFIG_CMD_I2C=y CONFIG_CMD_MMC=y CONFIG_CMD_SPI=y CONFIG_CMD_USB=y +CONFIG_CMD_USB_MASS_STORAGE=y CONFIG_CMD_TFTPPUT=y CONFIG_CMD_TIME=y CONFIG_MP=y From 3723324042ec92739d802604558a3ebe3d5616dc Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Mon, 4 Jun 2018 13:29:49 +0200 Subject: [PATCH 03/55] common: command: Use command_ret_t enum values instead of values Use enum command_ret_t types in cmd_process_error(). Signed-off-by: Michal Simek Reviewed-by: Simon Glass --- common/command.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/common/command.c b/common/command.c index 52d47c1..a4a8dc6 100644 --- a/common/command.c +++ b/common/command.c @@ -549,8 +549,8 @@ int cmd_process_error(cmd_tbl_t *cmdtp, int err) { if (err) { printf("Command '%s' failed: Error %d\n", cmdtp->name, err); - return 1; + return CMD_RET_FAILURE; } - return 0; + return CMD_RET_SUCCESS; } From 27eb7bce3943111dd70c19569b60d9a047f06811 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Thu, 21 Jun 2018 14:49:26 +0200 Subject: [PATCH 04/55] common: command: Handle USAGE failure separately command_ret_t enum contains 3 return values but only two are handled now. Extend cmd_process_error() and handle CMD_RET_USAGE separately. These commands are affected by this change. cmd/demo.c cmd/efi.c cmd/gpio.c cmd/qfw.c cmd/x86/fsp.c test/dm/cmd_dm.c And scripts shouldn't be affected because return value is not 0. But every command implementation can choose what it is correct to pass. I would expect that RET_USAGE is called when parameters are not correctly passed (have incorrect value, missing parameters) and RET_FAILURE when correct parameters are passed but command fails. Signed-off-by: Michal Simek Reviewed-by: Simon Glass --- common/command.c | 3 +++ include/command.h | 4 +++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/common/command.c b/common/command.c index a4a8dc6..2433a89 100644 --- a/common/command.c +++ b/common/command.c @@ -547,6 +547,9 @@ enum command_ret_t cmd_process(int flag, int argc, char * const argv[], int cmd_process_error(cmd_tbl_t *cmdtp, int err) { + if (err == CMD_RET_USAGE) + return CMD_RET_USAGE; + if (err) { printf("Command '%s' failed: Error %d\n", cmdtp->name, err); return CMD_RET_FAILURE; diff --git a/include/command.h b/include/command.h index 04cd1e7..5b1577f 100644 --- a/include/command.h +++ b/include/command.h @@ -67,7 +67,9 @@ extern int cmd_auto_complete(const char *const prompt, char *buf, int *np, int * * * @cmdtp: Command which caused the error * @err: Error code (0 if none, -ve for error, like -EIO) - * @return 0 if there is not error, 1 (CMD_RET_FAILURE) if an error is found + * @return 0 (CMD_RET_SUCCESX) if there is not error, + * 1 (CMD_RET_FAILURE) if an error is found + * -1 (CMD_RET_USAGE) if 'usage' error is found */ int cmd_process_error(cmd_tbl_t *cmdtp, int err); From 5da7b8cb08dbae06bb11f72449d425fdc20d1f81 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Fri, 22 Jun 2018 08:10:41 +0200 Subject: [PATCH 05/55] hush: Remove default CONFIG_SYS_PROMPT_HUSH_PS2 setting from board files There is no reason to define default option for this macro which is already done in common/cli_hush.c. 86 #ifndef CONFIG_SYS_PROMPT_HUSH_PS2 87 #define CONFIG_SYS_PROMPT_HUSH_PS2 "> " 88 #endif Signed-off-by: Michal Simek Reviewed-by: York Sun --- include/configs/ls1021aiot.h | 2 -- include/configs/ls1088a_common.h | 1 - include/configs/s32v234evb.h | 1 - include/configs/tplink_wdr4300.h | 1 - 4 files changed, 5 deletions(-) diff --git a/include/configs/ls1021aiot.h b/include/configs/ls1021aiot.h index 0c900eb..97792be 100644 --- a/include/configs/ls1021aiot.h +++ b/include/configs/ls1021aiot.h @@ -209,8 +209,6 @@ /* * Miscellaneous configurable options */ -#define CONFIG_SYS_PROMPT_HUSH_PS2 "> " - #define CONFIG_CMD_GREPENV #define CONFIG_CMD_MEMINFO diff --git a/include/configs/ls1088a_common.h b/include/configs/ls1088a_common.h index c70474c..137a181 100644 --- a/include/configs/ls1088a_common.h +++ b/include/configs/ls1088a_common.h @@ -215,7 +215,6 @@ unsigned long long get_qixis_addr(void); #define CONFIG_SYS_CBSIZE 512 /* Console I/O Buffer Size */ #define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + \ sizeof(CONFIG_SYS_PROMPT) + 16) -#define CONFIG_SYS_PROMPT_HUSH_PS2 "> " #define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE /* Boot args buffer */ #define CONFIG_SYS_MAXARGS 64 /* max command args */ diff --git a/include/configs/s32v234evb.h b/include/configs/s32v234evb.h index 48c979f..c6fb909 100644 --- a/include/configs/s32v234evb.h +++ b/include/configs/s32v234evb.h @@ -148,7 +148,6 @@ #include /* Miscellaneous configurable options */ -#define CONFIG_SYS_PROMPT_HUSH_PS2 "> " #define CONFIG_SYS_PROMPT "=> " #define CONFIG_SYS_MEMTEST_START (DDR_BASE_ADDR) diff --git a/include/configs/tplink_wdr4300.h b/include/configs/tplink_wdr4300.h index 0982d3e..4367158 100644 --- a/include/configs/tplink_wdr4300.h +++ b/include/configs/tplink_wdr4300.h @@ -44,7 +44,6 @@ #define CONFIG_SYS_MAXARGS 32 /* Max number of command args */ #define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE /* Boot argument buffer size */ -#define CONFIG_SYS_PROMPT_HUSH_PS2 "> " /* USB, USB storage, USB ethernet */ #define CONFIG_EHCI_MMIO_BIG_ENDIAN From 6da4f67ad09cd8b311d77b2b04e557b7ef65b56c Mon Sep 17 00:00:00 2001 From: Luca Ceresoli Date: Fri, 22 Jun 2018 12:40:16 +0200 Subject: [PATCH 06/55] arm/arm64: zynq/zynqmp: pass the PS init file as a kconfig variable U-Boot needs to link ps7_init_gpl.c on Zynq or psu_init_gpl.c on ZynqMP (PS init for short). The current logic to locate this file for both platforms is: 1. if a board-specific file exists in board/xilinx/zynq[mp]/$(CONFIG_DEFAULT_DEVICE_TREE)/ps?_init_gpl.c then use it 2. otherwise use board/xilinx/zynq/ps?_init_gpl.c In the latter case the file does not exist in the U-Boot sources and must be copied in the source tree from the outside before starting the build. This is typical when it is generated from Xilinx tools while developing a custom hardware. However making sure that a board-specific file is _not_ found (and used) requires some trickery such as removing or overwriting all PS init files (e.g.: the current meta-xilinx yocto layer). This generates a few problems: * if the source tree is shared among different out-of-tree builds, they will pollute (and potentially corrupt) each other * the source tree cannot be read-only * any buildsystem must add a command to copy the PS init file binary * overwriting or deleting files in the source tree is ugly as hell Simplify usage by allowing to pass the path to the desired PS init file in kconfig variable XILINX_PS_INIT_FILE. It can be an absolute path or relative to $(srctree). If the variable is set, the user-specified file will always be used without being copied around. If the the variable is left empty, for backward compatibility fall back to the old behaviour. Since the issue is the same for Zynq and ZynqMP, add one kconfig variable in a common place and use it for both. Also use the new kconfig help text to document all the ways to give U-Boot the PS init file. Build-tested with all combinations of: - platform: zynq or zynqmp - PS init file: from XILINX_PS_INIT_FILE (absolute, relative path, non-existing), in-tree board-specific, in board/xilinx/zynq[mp]/ - building in-tree, in subdir, in other directory Signed-off-by: Luca Ceresoli Cc: Albert Aribaud Cc: Michal Simek Cc: Nathan Rossi Signed-off-by: Michal Simek --- arch/arm/Kconfig | 1 + board/xilinx/Kconfig | 41 +++++++++++++++++++++++++++++++++++++++++ board/xilinx/zynq/Makefile | 10 +++++++++- board/xilinx/zynqmp/Makefile | 10 +++++++++- 4 files changed, 60 insertions(+), 2 deletions(-) create mode 100644 board/xilinx/Kconfig diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 5b3746c..3086e5c 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1474,6 +1474,7 @@ source "board/toradex/colibri_pxa270/Kconfig" source "board/vscom/baltos/Kconfig" source "board/woodburn/Kconfig" source "board/work-microwave/work_92105/Kconfig" +source "board/xilinx/Kconfig" source "board/xilinx/zynqmp/Kconfig" source "board/zipitz2/Kconfig" diff --git a/board/xilinx/Kconfig b/board/xilinx/Kconfig new file mode 100644 index 0000000..37bec5f --- /dev/null +++ b/board/xilinx/Kconfig @@ -0,0 +1,41 @@ +# SPDX-License-Identifier: GPL-2.0 +# +# Copyright (c) 2018, Luca Ceresoli + +if ARCH_ZYNQ || ARCH_ZYNQMP + +config XILINX_PS_INIT_FILE + string "Zynq/ZynqMP PS init file(s) location" + help + On Zynq and ZynqMP U-Boot SPL (or U-Boot proper if + ZYNQMP_PSU_INIT_ENABLED is set) is responsible for some + basic initializations, such as enabling peripherals and + configuring pinmuxes. The PS init file (called + psu_init_gpl.c on ZynqMP, ps7_init_gpl.c for Zynq-7000) + contains the code for such initializations. + + U-Boot contains PS init files for some boards, but each of + them describes only one specific configuration. Users of a + different board, or needing a different configuration, can + generate custom files using the Xilinx development tools. + + There are three ways to give a PS init file to U-Boot: + + 1. Set this variable to the path, either relative to the + source tree or absolute, where the psu_init_gpl.c or + ps7_init_gpl.c file is located. U-Boot will build this + file. + + 2. If you leave an empty string here, U-Boot will use + board/xilinx/zynq/$(CONFIG_DEFAULT_DEVICE_TREE)/ps7_init_gpl.c + for Zynq-7000, or + board/xilinx/zynqmp/$(CONFIG_DEFAULT_DEVICE_TREE)/psu_init_gpl.c + for ZynqMP. + + 3. If the above file does not exist, U-Boot will use + board/xilinx/zynq/ps7_init_gpl.c for Zynq-7000, or + board/xilinx/zynqmp/psu_init_gpl.c for ZynqMP. This file + is not provided by U-Boot, you have to copy it there + before the build. + +endif diff --git a/board/xilinx/zynq/Makefile b/board/xilinx/zynq/Makefile index 5a76a26..03ad5f0 100644 --- a/board/xilinx/zynq/Makefile +++ b/board/xilinx/zynq/Makefile @@ -5,10 +5,18 @@ obj-y := board.o -hw-platform-y :=$(shell echo $(CONFIG_DEFAULT_DEVICE_TREE)) +ifneq ($(CONFIG_XILINX_PS_INIT_FILE),"") +PS_INIT_FILE := $(shell cd $(srctree); readlink -f $(CONFIG_XILINX_PS_INIT_FILE)) +init-objs := ps_init_gpl.o +spl/board/xilinx/zynq/ps_init_gpl.o board/xilinx/zynq/ps_init_gpl.o: $(PS_INIT_FILE) + $(CC) $(c_flags) -I $(srctree)/$(src) -c -o $@ $^ +endif +ifeq ($(init-objs),) +hw-platform-y :=$(shell echo $(CONFIG_DEFAULT_DEVICE_TREE)) init-objs := $(if $(wildcard $(srctree)/$(src)/$(hw-platform-y)/ps7_init_gpl.c),\ $(hw-platform-y)/ps7_init_gpl.o) +endif ifeq ($(init-objs),) ifneq ($(wildcard $(srctree)/$(src)/ps7_init_gpl.c),) diff --git a/board/xilinx/zynqmp/Makefile b/board/xilinx/zynqmp/Makefile index 05ccd25..960b81f 100644 --- a/board/xilinx/zynqmp/Makefile +++ b/board/xilinx/zynqmp/Makefile @@ -5,10 +5,18 @@ obj-y := zynqmp.o -hw-platform-y :=$(shell echo $(CONFIG_DEFAULT_DEVICE_TREE)) +ifneq ($(CONFIG_XILINX_PS_INIT_FILE),"") +PS_INIT_FILE := $(shell cd $(srctree); readlink -f $(CONFIG_XILINX_PS_INIT_FILE)) +init-objs := ps_init_gpl.o +spl/board/xilinx/zynqmp/ps_init_gpl.o board/xilinx/zynqmp/ps_init_gpl.o: $(PS_INIT_FILE) + $(CC) $(c_flags) -I $(srctree)/$(src) -c -o $@ $^ +endif +ifeq ($(init-objs),) +hw-platform-y :=$(shell echo $(CONFIG_DEFAULT_DEVICE_TREE)) init-objs := $(if $(wildcard $(srctree)/$(src)/$(hw-platform-y)/psu_init_gpl.c),\ $(hw-platform-y)/psu_init_gpl.o) +endif ifeq ($(init-objs),) ifneq ($(wildcard $(srctree)/$(src)/psu_init_gpl.c),) From b4f015845a5814ab56aee136bf2c7175c205c6c2 Mon Sep 17 00:00:00 2001 From: Vipul Kumar Date: Wed, 27 Jun 2018 10:44:45 +0530 Subject: [PATCH 07/55] clk: zynqmp: Fixed the same if/else part error reported by coverity This patch fixed the same if/else part error by adding the required source select on the basis of is_pre_src check. Signed-off-by: Vipul Kumar Signed-off-by: Michal Simek --- drivers/clk/clk_zynqmp.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/clk/clk_zynqmp.c b/drivers/clk/clk_zynqmp.c index a9e4500..167f3f7 100644 --- a/drivers/clk/clk_zynqmp.c +++ b/drivers/clk/clk_zynqmp.c @@ -103,6 +103,8 @@ static const resource_size_t zynqmp_crl_apb_clkc_base = 0xff5e0020; #define PLLCTRL_BYPASS_SHFT 3 #define PLLCTRL_POST_SRC_SHFT 24 #define PLLCTRL_POST_SRC_MASK (0x7 << PLLCTRL_POST_SRC_SHFT) +#define PLLCTRL_PRE_SRC_SHFT 20 +#define PLLCTRL_PRE_SRC_MASK (0x7 << PLLCTRL_PRE_SRC_SHFT) #define NUM_MIO_PINS 77 @@ -310,8 +312,8 @@ static ulong zynqmp_clk_get_pll_src(ulong clk_ctrl, u32 src_sel; if (is_pre_src) - src_sel = (clk_ctrl & PLLCTRL_POST_SRC_MASK) >> - PLLCTRL_POST_SRC_SHFT; + src_sel = (clk_ctrl & PLLCTRL_PRE_SRC_MASK) >> + PLLCTRL_PRE_SRC_SHFT; else src_sel = (clk_ctrl & PLLCTRL_POST_SRC_MASK) >> PLLCTRL_POST_SRC_SHFT; From f8f3e0e539e08da381e397ba58fcc2df195ae2ec Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Wed, 27 Jun 2018 14:16:54 +0200 Subject: [PATCH 08/55] usb_kbd: Add support for watchdog There is need to service watchdog in while loop or system will be restarted when idlying. Signed-off-by: Michal Simek --- common/usb_kbd.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/common/usb_kbd.c b/common/usb_kbd.c index 8b2fccf..406bd37 100644 --- a/common/usb_kbd.c +++ b/common/usb_kbd.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -387,8 +388,10 @@ static int usb_kbd_getc(struct stdio_dev *sdev) usb_kbd_dev = (struct usb_device *)dev->priv; data = usb_kbd_dev->privptr; - while (data->usb_in_pointer == data->usb_out_pointer) + while (data->usb_in_pointer == data->usb_out_pointer) { + WATCHDOG_RESET(); usb_kbd_poll_for_event(usb_kbd_dev); + } if (data->usb_out_pointer == USB_KBD_BUFFER_LEN - 1) data->usb_out_pointer = 0; From 4fb67f47f123bb301e1ffbbb345d8f6fe46ec3cd Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Wed, 27 Jun 2018 14:35:07 +0200 Subject: [PATCH 09/55] usb_kdb: Get stdio_dev directly from sdev pointer Driver supports only one instance of usb keyboard. Remove the first dependency on generic usbkbd DEVNAME. Signed-off-by: Michal Simek --- common/usb_kbd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/common/usb_kbd.c b/common/usb_kbd.c index 406bd37..fdeb2ae 100644 --- a/common/usb_kbd.c +++ b/common/usb_kbd.c @@ -368,7 +368,7 @@ static int usb_kbd_testc(struct stdio_dev *sdev) return 0; kbd_testc_tms = get_timer(0); #endif - dev = stdio_get_by_name(DEVNAME); + dev = stdio_get_by_name(sdev->name); usb_kbd_dev = (struct usb_device *)dev->priv; data = usb_kbd_dev->privptr; @@ -384,7 +384,7 @@ static int usb_kbd_getc(struct stdio_dev *sdev) struct usb_device *usb_kbd_dev; struct usb_kbd_pdata *data; - dev = stdio_get_by_name(DEVNAME); + dev = stdio_get_by_name(sdev->name); usb_kbd_dev = (struct usb_device *)dev->priv; data = usb_kbd_dev->privptr; From 6bdf0a992c962e15ab637a096d7f7d5601e0b4c5 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Thu, 14 Jun 2018 10:32:27 +0200 Subject: [PATCH 10/55] serial: zynq: Use platdata for storing static data instead of priv Explanation from Simon Glass "Private data is created when the device is probed and freed when the device is removed. Platform data is created when the device is bound, and survives probe/remove cycles. Strictly speaking, platform data should be used to hold the decoded device tree properties. Private data should be used for run-time things the device needs to keep track of." Based on description the driver needs to be switch to use platdata instead of priv. Signed-off-by: Michal Simek Reviewed-by: Simon Glass --- drivers/serial/serial_zynq.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/drivers/serial/serial_zynq.c b/drivers/serial/serial_zynq.c index a191772..f689015 100644 --- a/drivers/serial/serial_zynq.c +++ b/drivers/serial/serial_zynq.c @@ -39,7 +39,7 @@ struct uart_zynq { u32 baud_rate_divider; /* 0x34 - Baud Rate Divider [7:0] */ }; -struct zynq_uart_priv { +struct zynq_uart_platdata { struct uart_zynq *regs; }; @@ -105,7 +105,7 @@ static int _uart_zynq_serial_putc(struct uart_zynq *regs, const char c) static int zynq_serial_setbrg(struct udevice *dev, int baudrate) { - struct zynq_uart_priv *priv = dev_get_priv(dev); + struct zynq_uart_platdata *platdata = dev_get_platdata(dev); unsigned long clock; int ret; @@ -130,28 +130,28 @@ static int zynq_serial_setbrg(struct udevice *dev, int baudrate) return ret; } - _uart_zynq_serial_setbrg(priv->regs, clock, baudrate); + _uart_zynq_serial_setbrg(platdata->regs, clock, baudrate); return 0; } static int zynq_serial_probe(struct udevice *dev) { - struct zynq_uart_priv *priv = dev_get_priv(dev); + struct zynq_uart_platdata *platdata = dev_get_platdata(dev); /* No need to reinitialize the UART after relocation */ if (gd->flags & GD_FLG_RELOC) return 0; - _uart_zynq_serial_init(priv->regs); + _uart_zynq_serial_init(platdata->regs); return 0; } static int zynq_serial_getc(struct udevice *dev) { - struct zynq_uart_priv *priv = dev_get_priv(dev); - struct uart_zynq *regs = priv->regs; + struct zynq_uart_platdata *platdata = dev_get_platdata(dev); + struct uart_zynq *regs = platdata->regs; if (readl(®s->channel_sts) & ZYNQ_UART_SR_RXEMPTY) return -EAGAIN; @@ -161,15 +161,15 @@ static int zynq_serial_getc(struct udevice *dev) static int zynq_serial_putc(struct udevice *dev, const char ch) { - struct zynq_uart_priv *priv = dev_get_priv(dev); + struct zynq_uart_platdata *platdata = dev_get_platdata(dev); - return _uart_zynq_serial_putc(priv->regs, ch); + return _uart_zynq_serial_putc(platdata->regs, ch); } static int zynq_serial_pending(struct udevice *dev, bool input) { - struct zynq_uart_priv *priv = dev_get_priv(dev); - struct uart_zynq *regs = priv->regs; + struct zynq_uart_platdata *platdata = dev_get_platdata(dev); + struct uart_zynq *regs = platdata->regs; if (input) return !(readl(®s->channel_sts) & ZYNQ_UART_SR_RXEMPTY); @@ -179,11 +179,11 @@ static int zynq_serial_pending(struct udevice *dev, bool input) static int zynq_serial_ofdata_to_platdata(struct udevice *dev) { - struct zynq_uart_priv *priv = dev_get_priv(dev); + struct zynq_uart_platdata *platdata = dev_get_platdata(dev); - priv->regs = (struct uart_zynq *)dev_read_addr(dev); - if (IS_ERR(priv->regs)) - return PTR_ERR(priv->regs); + platdata->regs = (struct uart_zynq *)dev_read_addr(dev); + if (IS_ERR(platdata->regs)) + return PTR_ERR(platdata->regs); return 0; } @@ -207,7 +207,7 @@ U_BOOT_DRIVER(serial_zynq) = { .id = UCLASS_SERIAL, .of_match = zynq_serial_ids, .ofdata_to_platdata = zynq_serial_ofdata_to_platdata, - .priv_auto_alloc_size = sizeof(struct zynq_uart_priv), + .platdata_auto_alloc_size = sizeof(struct zynq_uart_platdata), .probe = zynq_serial_probe, .ops = &zynq_serial_ops, .flags = DM_FLAG_PRE_RELOC, From 37e3a36a54755d15e36b52ee47caaf1cdfdc37aa Mon Sep 17 00:00:00 2001 From: Siva Durga Prasad Paladugu Date: Tue, 26 Jun 2018 15:02:19 +0530 Subject: [PATCH 11/55] xilinx: zynq: Add support to secure images This patch basically adds two new commands for loadig secure images. 1. zynq rsa adds support to load secure image which can be both authenticated or encrypted or both authenticated and encrypted image in xilinx bootimage(BOOT.bin) format. 2. zynq aes command adds support to decrypt and load encrypted image back to DDR as per destination address. The image has to be encrypted using xilinx bootgen tool and to get only the encrypted image from tool use -split option while invoking bootgen. Signed-off-by: Siva Durga Prasad Paladugu Signed-off-by: Michal Simek --- arch/arm/Kconfig | 1 + arch/arm/mach-zynq/include/mach/hardware.h | 1 + board/xilinx/zynq/Kconfig | 33 ++ board/xilinx/zynq/Makefile | 5 + board/xilinx/zynq/bootimg.c | 143 ++++++++ board/xilinx/zynq/cmds.c | 513 +++++++++++++++++++++++++++++ configs/zynq_cse_qspi_defconfig | 1 + drivers/fpga/zynqpl.c | 45 +++ include/u-boot/rsa-mod-exp.h | 4 + include/zynq_bootimg.h | 33 ++ include/zynqpl.h | 4 + lib/rsa/rsa-mod-exp.c | 51 +++ 12 files changed, 834 insertions(+) create mode 100644 board/xilinx/zynq/Kconfig create mode 100644 board/xilinx/zynq/bootimg.c create mode 100644 board/xilinx/zynq/cmds.c create mode 100644 include/zynq_bootimg.h diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 3086e5c..64d58a6 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1475,6 +1475,7 @@ source "board/vscom/baltos/Kconfig" source "board/woodburn/Kconfig" source "board/work-microwave/work_92105/Kconfig" source "board/xilinx/Kconfig" +source "board/xilinx/zynq/Kconfig" source "board/xilinx/zynqmp/Kconfig" source "board/zipitz2/Kconfig" diff --git a/arch/arm/mach-zynq/include/mach/hardware.h b/arch/arm/mach-zynq/include/mach/hardware.h index f69cf00..3ff3c10 100644 --- a/arch/arm/mach-zynq/include/mach/hardware.h +++ b/arch/arm/mach-zynq/include/mach/hardware.h @@ -20,6 +20,7 @@ #define ZYNQ_EFUSE_BASEADDR 0xF800D000 #define ZYNQ_USB_BASEADDR0 0xE0002000 #define ZYNQ_USB_BASEADDR1 0xE0003000 +#define ZYNQ_OCM_BASEADDR 0xFFFC0000 /* Bootmode setting values */ #define ZYNQ_BM_MASK 0x7 diff --git a/board/xilinx/zynq/Kconfig b/board/xilinx/zynq/Kconfig new file mode 100644 index 0000000..d6f4063 --- /dev/null +++ b/board/xilinx/zynq/Kconfig @@ -0,0 +1,33 @@ +# SPDX-License-Identifier: GPL-2.0 +# +# Copyright (c) 2018, Xilinx, Inc. + +if ARCH_ZYNQ + +config CMD_ZYNQ + bool "Enable Zynq specific commands" + default y + help + Enables Zynq specific commands. + +config CMD_ZYNQ_AES + bool "Enable zynq aes command for decryption of encrypted images" + depends on CMD_ZYNQ + depends on FPGA_ZYNQPL + help + Decrypts the encrypted image present in source address + and places the decrypted image at destination address. + +config CMD_ZYNQ_RSA + bool "Enable zynq rsa command for loading secure images" + default y + depends on CMD_ZYNQ + depends on CMD_ZYNQ_AES + help + Enabling this will support zynq secure image verification. + The secure image is a xilinx specific BOOT.BIN with + either authentication or encryption or both encryption + and authentication feature enabled while generating + BOOT.BIN using Xilinx bootgen tool. + +endif diff --git a/board/xilinx/zynq/Makefile b/board/xilinx/zynq/Makefile index 03ad5f0..e7645be 100644 --- a/board/xilinx/zynq/Makefile +++ b/board/xilinx/zynq/Makefile @@ -26,6 +26,11 @@ $(warning Put custom ps7_init_gpl.c/h to board/xilinx/zynq/custom_hw_platform/)) endif endif +ifndef CONFIG_SPL_BUILD +obj-$(CONFIG_CMD_ZYNQ) += cmds.o +obj-$(CONFIG_CMD_ZYNQ_RSA) += bootimg.o +endif + obj-$(CONFIG_SPL_BUILD) += $(init-objs) # Suppress "warning: function declaration isn't a prototype" diff --git a/board/xilinx/zynq/bootimg.c b/board/xilinx/zynq/bootimg.c new file mode 100644 index 0000000..56d69cd --- /dev/null +++ b/board/xilinx/zynq/bootimg.c @@ -0,0 +1,143 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2018 Xilinx, Inc. + */ + +#include +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +#define ZYNQ_IMAGE_PHDR_OFFSET 0x09C +#define ZYNQ_IMAGE_FSBL_LEN_OFFSET 0x040 +#define ZYNQ_PART_HDR_CHKSUM_WORD_COUNT 0x0F +#define ZYNQ_PART_HDR_WORD_COUNT 0x10 +#define ZYNQ_MAXIMUM_IMAGE_WORD_LEN 0x40000000 +#define MD5_CHECKSUM_SIZE 16 + +struct headerarray { + u32 fields[16]; +}; + +/* + * Check whether the given partition is last partition or not + */ +static int zynq_islastpartition(struct headerarray *head) +{ + int index; + + debug("%s\n", __func__); + if (head->fields[ZYNQ_PART_HDR_CHKSUM_WORD_COUNT] != 0xFFFFFFFF) + return -1; + + for (index = 0; index < ZYNQ_PART_HDR_WORD_COUNT - 1; index++) { + if (head->fields[index] != 0x0) + return -1; + } + + return 0; +} + +/* + * Get the partition count from the partition header + */ +int zynq_get_part_count(struct partition_hdr *part_hdr_info) +{ + u32 count; + struct headerarray *hap; + + debug("%s\n", __func__); + + for (count = 0; count < ZYNQ_MAX_PARTITION_NUMBER; count++) { + hap = (struct headerarray *)&part_hdr_info[count]; + if (zynq_islastpartition(hap) != -1) + break; + } + + return count; +} + +/* + * Get the partition info of all the partitions available. + */ +int zynq_get_partition_info(u32 image_base_addr, u32 *fsbl_len, + struct partition_hdr *part_hdr) +{ + u32 parthdroffset; + + *fsbl_len = *((u32 *)(image_base_addr + ZYNQ_IMAGE_FSBL_LEN_OFFSET)); + + parthdroffset = *((u32 *)(image_base_addr + ZYNQ_IMAGE_PHDR_OFFSET)); + + parthdroffset += image_base_addr; + + memcpy(part_hdr, (u32 *)parthdroffset, + (sizeof(struct partition_hdr) * ZYNQ_MAX_PARTITION_NUMBER)); + + return 0; +} + +/* + * Check whether the partition header is valid or not + */ +int zynq_validate_hdr(struct partition_hdr *header) +{ + struct headerarray *hap; + u32 index; + u32 checksum; + + debug("%s\n", __func__); + + hap = (struct headerarray *)header; + + for (index = 0; index < ZYNQ_PART_HDR_WORD_COUNT; index++) { + if (hap->fields[index]) + break; + } + if (index == ZYNQ_PART_HDR_WORD_COUNT) + return -1; + + checksum = 0; + for (index = 0; index < ZYNQ_PART_HDR_CHKSUM_WORD_COUNT; index++) + checksum += hap->fields[index]; + + checksum ^= 0xFFFFFFFF; + + if (hap->fields[ZYNQ_PART_HDR_CHKSUM_WORD_COUNT] != checksum) { + printf("Error: Checksum 0x%8.8x != 0x%8.8x\n", + checksum, hap->fields[ZYNQ_PART_HDR_CHKSUM_WORD_COUNT]); + return -1; + } + + if (header->imagewordlen > ZYNQ_MAXIMUM_IMAGE_WORD_LEN) { + printf("INVALID_PARTITION_LENGTH\n"); + return -1; + } + + return 0; +} + +/* + * Validate the partition by calculationg the md5 checksum for the + * partition and compare with checksum present in checksum offset of + * partition + */ +int zynq_validate_partition(u32 start_addr, u32 len, u32 chksum_off) +{ + u8 checksum[MD5_CHECKSUM_SIZE]; + u8 calchecksum[MD5_CHECKSUM_SIZE]; + + memcpy(&checksum[0], (u32 *)chksum_off, MD5_CHECKSUM_SIZE); + + md5_wd((u8 *)start_addr, len, &calchecksum[0], 0x10000); + + if (!memcmp(checksum, calchecksum, MD5_CHECKSUM_SIZE)) + return 0; + + printf("Error: Partition DataChecksum\n"); + return -1; +} diff --git a/board/xilinx/zynq/cmds.c b/board/xilinx/zynq/cmds.c new file mode 100644 index 0000000..0b2a817 --- /dev/null +++ b/board/xilinx/zynq/cmds.c @@ -0,0 +1,513 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2018 Xilinx, Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +#ifdef CONFIG_CMD_ZYNQ_RSA + +#define ZYNQ_EFUSE_RSA_ENABLE_MASK 0x400 +#define ZYNQ_ATTRIBUTE_PL_IMAGE_MASK 0x20 +#define ZYNQ_ATTRIBUTE_CHECKSUM_TYPE_MASK 0x7000 +#define ZYNQ_ATTRIBUTE_RSA_PRESENT_MASK 0x8000 +#define ZYNQ_ATTRIBUTE_RSA_PART_OWNER_MASK 0x30000 + +#define ZYNQ_RSA_MODULAR_SIZE 256 +#define ZYNQ_RSA_MODULAR_EXT_SIZE 256 +#define ZYNQ_RSA_EXPO_SIZE 64 +#define ZYNQ_RSA_SPK_SIGNATURE_SIZE 256 +#define ZYNQ_RSA_PARTITION_SIGNATURE_SIZE 256 +#define ZYNQ_RSA_SIGNATURE_SIZE 0x6C0 +#define ZYNQ_RSA_HEADER_SIZE 4 +#define ZYNQ_RSA_MAGIC_WORD_SIZE 60 +#define ZYNQ_RSA_PART_OWNER_UBOOT 1 +#define ZYNQ_RSA_ALIGN_PPK_START 64 + +#define WORD_LENGTH_SHIFT 2 + +static u8 *ppkmodular; +static u8 *ppkmodularex; + +struct zynq_rsa_public_key { + uint len; /* Length of modulus[] in number of u32 */ + u32 n0inv; /* -1 / modulus[0] mod 2^32 */ + u32 *modulus; /* modulus as little endian array */ + u32 *rr; /* R^2 as little endian array */ +}; + +static struct zynq_rsa_public_key public_key; + +static struct partition_hdr part_hdr[ZYNQ_MAX_PARTITION_NUMBER]; + +/* + * Extract the primary public key components from already autheticated FSBL + */ +static void zynq_extract_ppk(u32 fsbl_len) +{ + u32 padsize; + u8 *ppkptr; + + debug("%s\n", __func__); + + /* + * Extract the authenticated PPK from OCM i.e at end of the FSBL + */ + ppkptr = (u8 *)(fsbl_len + ZYNQ_OCM_BASEADDR); + padsize = ((u32)ppkptr % ZYNQ_RSA_ALIGN_PPK_START); + if (padsize) + ppkptr += (ZYNQ_RSA_ALIGN_PPK_START - padsize); + + ppkptr += ZYNQ_RSA_HEADER_SIZE; + + ppkptr += ZYNQ_RSA_MAGIC_WORD_SIZE; + + ppkmodular = (u8 *)ppkptr; + ppkptr += ZYNQ_RSA_MODULAR_SIZE; + ppkmodularex = (u8 *)ppkptr; + ppkptr += ZYNQ_RSA_MODULAR_EXT_SIZE; +} + +/* + * Calculate the inverse(-1 / modulus[0] mod 2^32 ) for the PPK + */ +static u32 zynq_calc_inv(void) +{ + u32 modulus = public_key.modulus[0]; + u32 tmp = BIT(1); + u32 inverse; + + inverse = modulus & BIT(0); + + while (tmp) { + inverse *= 2 - modulus * inverse; + tmp *= tmp; + } + + return ~(inverse - 1); +} + +/* + * Recreate the signature by padding the bytes and verify with hash value + */ +static int zynq_pad_and_check(u8 *signature, u8 *hash) +{ + u8 padding[] = {0x30, 0x31, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, + 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, + 0x20}; + u8 *pad_ptr = signature + 256; + u32 pad = 202; + u32 ii; + + /* + * Re-Create PKCS#1v1.5 Padding + * MSB ----------------------------------------------------LSB + * 0x0 || 0x1 || 0xFF(for 202 bytes) || 0x0 || T_padding || SHA256 Hash + */ + if (*--pad_ptr != 0 || *--pad_ptr != 1) + return -1; + + for (ii = 0; ii < pad; ii++) { + if (*--pad_ptr != 0xFF) + return -1; + } + + if (*--pad_ptr != 0) + return -1; + + for (ii = 0; ii < sizeof(padding); ii++) { + if (*--pad_ptr != padding[ii]) + return -1; + } + + for (ii = 0; ii < 32; ii++) { + if (*--pad_ptr != hash[ii]) + return -1; + } + return 0; +} + +/* + * Verify and extract the hash value from signature using the public key + * and compare it with calculated hash value. + */ +static int zynq_rsa_verify_key(const struct zynq_rsa_public_key *key, + const u8 *sig, const u32 sig_len, const u8 *hash) +{ + int status; + void *buf; + + if (!key || !sig || !hash) + return -1; + + if (sig_len != (key->len * sizeof(u32))) { + printf("Signature is of incorrect length %d\n", sig_len); + return -1; + } + + /* Sanity check for stack size */ + if (sig_len > ZYNQ_RSA_SPK_SIGNATURE_SIZE) { + printf("Signature length %u exceeds maximum %d\n", sig_len, + ZYNQ_RSA_SPK_SIGNATURE_SIZE); + return -1; + } + + buf = malloc(sig_len); + if (!buf) + return -1; + + memcpy(buf, sig, sig_len); + + status = zynq_pow_mod((u32 *)key, (u32 *)buf); + if (status == -1) { + free(buf); + return status; + } + + status = zynq_pad_and_check((u8 *)buf, (u8 *)hash); + + free(buf); + return status; +} + +/* + * Authenticate the partition + */ +static int zynq_authenticate_part(u8 *buffer, u32 size) +{ + u8 hash_signature[32]; + u8 *spk_modular; + u8 *spk_modular_ex; + u8 *signature_ptr; + u32 status; + + debug("%s\n", __func__); + + signature_ptr = (u8 *)(buffer + size - ZYNQ_RSA_SIGNATURE_SIZE); + + signature_ptr += ZYNQ_RSA_HEADER_SIZE; + + signature_ptr += ZYNQ_RSA_MAGIC_WORD_SIZE; + + ppkmodular = (u8 *)signature_ptr; + signature_ptr += ZYNQ_RSA_MODULAR_SIZE; + ppkmodularex = signature_ptr; + signature_ptr += ZYNQ_RSA_MODULAR_EXT_SIZE; + signature_ptr += ZYNQ_RSA_EXPO_SIZE; + + sha256_csum_wd((const unsigned char *)signature_ptr, + (ZYNQ_RSA_MODULAR_EXT_SIZE + ZYNQ_RSA_EXPO_SIZE + + ZYNQ_RSA_MODULAR_SIZE), + (unsigned char *)hash_signature, 0x1000); + + spk_modular = (u8 *)signature_ptr; + signature_ptr += ZYNQ_RSA_MODULAR_SIZE; + spk_modular_ex = (u8 *)signature_ptr; + signature_ptr += ZYNQ_RSA_MODULAR_EXT_SIZE; + signature_ptr += ZYNQ_RSA_EXPO_SIZE; + + public_key.len = ZYNQ_RSA_MODULAR_SIZE / sizeof(u32); + public_key.modulus = (u32 *)ppkmodular; + public_key.rr = (u32 *)ppkmodularex; + public_key.n0inv = zynq_calc_inv(); + + status = zynq_rsa_verify_key(&public_key, signature_ptr, + ZYNQ_RSA_SPK_SIGNATURE_SIZE, + hash_signature); + if (status) + return status; + + signature_ptr += ZYNQ_RSA_SPK_SIGNATURE_SIZE; + + sha256_csum_wd((const unsigned char *)buffer, + (size - ZYNQ_RSA_PARTITION_SIGNATURE_SIZE), + (unsigned char *)hash_signature, 0x1000); + + public_key.len = ZYNQ_RSA_MODULAR_SIZE / sizeof(u32); + public_key.modulus = (u32 *)spk_modular; + public_key.rr = (u32 *)spk_modular_ex; + public_key.n0inv = zynq_calc_inv(); + + return zynq_rsa_verify_key(&public_key, (u8 *)signature_ptr, + ZYNQ_RSA_PARTITION_SIGNATURE_SIZE, + (u8 *)hash_signature); +} + +/* + * Parses the partition header and verfies the authenticated and + * encrypted image. + */ +static int zynq_verify_image(u32 src_ptr) +{ + u32 silicon_ver, image_base_addr, status; + u32 partition_num = 0; + u32 efuseval, srcaddr, size, fsbl_len; + struct partition_hdr *hdr_ptr; + u32 part_data_len, part_img_len, part_attr; + u32 part_load_addr, part_dst_addr, part_chksum_offset; + u32 part_start_addr, part_total_size, partitioncount; + bool encrypt_part_flag = false; + bool part_chksum_flag = false; + bool signed_part_flag = false; + + image_base_addr = src_ptr; + + silicon_ver = zynq_get_silicon_version(); + + /* RSA not supported in silicon versions 1.0 and 2.0 */ + if (silicon_ver == 0 || silicon_ver == 1) + return -1; + + zynq_get_partition_info(image_base_addr, &fsbl_len, + &part_hdr[0]); + + /* Extract ppk if efuse was blown Otherwise return error */ + efuseval = readl(&efuse_base->status); + if (!(efuseval & ZYNQ_EFUSE_RSA_ENABLE_MASK)) + return -1; + + zynq_extract_ppk(fsbl_len); + + partitioncount = zynq_get_part_count(&part_hdr[0]); + + /* + * As the first two partitions are related to fsbl, + * we can ignore those two in bootimage and the below + * code doesn't need to validate it as fsbl is already + * done by now + */ + if (partitioncount <= 2 || + partitioncount > ZYNQ_MAX_PARTITION_NUMBER) + return -1; + + while (partition_num < partitioncount) { + if (((part_hdr[partition_num].partitionattr & + ZYNQ_ATTRIBUTE_RSA_PART_OWNER_MASK) >> 16) != + ZYNQ_RSA_PART_OWNER_UBOOT) { + printf("UBOOT is not Owner for partition %d\n", + partition_num); + partition_num++; + continue; + } + hdr_ptr = &part_hdr[partition_num]; + status = zynq_validate_hdr(hdr_ptr); + if (status) + return status; + + part_data_len = hdr_ptr->datawordlen; + part_img_len = hdr_ptr->imagewordlen; + part_attr = hdr_ptr->partitionattr; + part_load_addr = hdr_ptr->loadaddr; + part_chksum_offset = hdr_ptr->checksumoffset; + part_start_addr = hdr_ptr->partitionstart; + part_total_size = hdr_ptr->partitionwordlen; + + if (part_data_len != part_img_len) { + debug("Encrypted\n"); + encrypt_part_flag = true; + } + + if (part_attr & ZYNQ_ATTRIBUTE_CHECKSUM_TYPE_MASK) + part_chksum_flag = true; + + if (part_attr & ZYNQ_ATTRIBUTE_RSA_PRESENT_MASK) { + debug("RSA Signed\n"); + signed_part_flag = true; + size = part_total_size << WORD_LENGTH_SHIFT; + } else { + size = part_img_len; + } + + if (!signed_part_flag && !part_chksum_flag) { + printf("Partition not signed & no chksum\n"); + partition_num++; + continue; + } + + srcaddr = image_base_addr + + (part_start_addr << WORD_LENGTH_SHIFT); + + /* + * This validation is just for PS DDR. + * TODO: Update this for PL DDR check as well. + */ + if (part_load_addr < gd->bd->bi_dram[0].start && + ((part_load_addr + part_data_len) > + (gd->bd->bi_dram[0].start + + gd->bd->bi_dram[0].size))) { + printf("INVALID_LOAD_ADDRESS_FAIL\n"); + return -1; + } + + if (part_attr & ZYNQ_ATTRIBUTE_PL_IMAGE_MASK) + part_load_addr = srcaddr; + else + memcpy((u32 *)part_load_addr, (u32 *)srcaddr, + size); + + if (part_chksum_flag) { + part_chksum_offset = image_base_addr + + (part_chksum_offset << + WORD_LENGTH_SHIFT); + status = zynq_validate_partition(part_load_addr, + (part_total_size << + WORD_LENGTH_SHIFT), + part_chksum_offset); + if (status != 0) { + printf("PART_CHKSUM_FAIL\n"); + return -1; + } + debug("Partition Validation Done\n"); + } + + if (signed_part_flag) { + status = zynq_authenticate_part((u8 *)part_load_addr, + size); + if (status != 0) { + printf("AUTHENTICATION_FAIL\n"); + return -1; + } + debug("Authentication Done\n"); + } + + if (encrypt_part_flag) { + debug("DECRYPTION\n"); + + part_dst_addr = part_load_addr; + + if (part_attr & ZYNQ_ATTRIBUTE_PL_IMAGE_MASK) { + partition_num++; + continue; + } + + status = zynq_decrypt_load(part_load_addr, + part_img_len, + part_dst_addr, + part_data_len); + if (status != 0) { + printf("DECRYPTION_FAIL\n"); + return -1; + } + } + partition_num++; + } + + return 0; +} + +static int do_zynq_rsa(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]) +{ + u32 src_ptr; + char *endp; + + src_ptr = simple_strtoul(argv[2], &endp, 16); + if (*argv[2] == 0 || *endp != 0) + return CMD_RET_USAGE; + if (zynq_verify_image(src_ptr)) + return CMD_RET_FAILURE; + + return CMD_RET_SUCCESS; +} +#endif + +#ifdef CONFIG_CMD_ZYNQ_AES +static int zynq_decrypt_image(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]) +{ + char *endp; + u32 srcaddr, srclen, dstaddr, dstlen; + int status; + + srcaddr = simple_strtoul(argv[2], &endp, 16); + if (*argv[2] == 0 || *endp != 0) + return CMD_RET_USAGE; + srclen = simple_strtoul(argv[3], &endp, 16); + if (*argv[3] == 0 || *endp != 0) + return CMD_RET_USAGE; + dstaddr = simple_strtoul(argv[4], &endp, 16); + if (*argv[4] == 0 || *endp != 0) + return CMD_RET_USAGE; + dstlen = simple_strtoul(argv[5], &endp, 16); + if (*argv[5] == 0 || *endp != 0) + return CMD_RET_USAGE; + + /* + * Roundup source and destination lengths to + * word size + */ + if (srclen % 4) + srclen = roundup(srclen, 4); + if (dstlen % 4) + dstlen = roundup(dstlen, 4); + + status = zynq_decrypt_load(srcaddr, srclen >> 2, dstaddr, dstlen >> 2); + if (status != 0) + return CMD_RET_FAILURE; + + return CMD_RET_SUCCESS; +} +#endif + +static cmd_tbl_t zynq_commands[] = { +#ifdef CONFIG_CMD_ZYNQ_RSA + U_BOOT_CMD_MKENT(rsa, 3, 1, do_zynq_rsa, "", ""), +#endif +#ifdef CONFIG_CMD_ZYNQ_AES + U_BOOT_CMD_MKENT(aes, 6, 1, zynq_decrypt_image, "", ""), +#endif +}; + +static int do_zynq(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + cmd_tbl_t *zynq_cmd; + int ret; + + if (!ARRAY_SIZE(zynq_commands)) { + puts("No zynq specific command enabled\n"); + return CMD_RET_USAGE; + } + + if (argc < 2) + return CMD_RET_USAGE; + zynq_cmd = find_cmd_tbl(argv[1], zynq_commands, + ARRAY_SIZE(zynq_commands)); + if (!zynq_cmd || argc != zynq_cmd->maxargs) + return CMD_RET_USAGE; + + ret = zynq_cmd->cmd(zynq_cmd, flag, argc, argv); + + return cmd_process_error(zynq_cmd, ret); +} + +static char zynq_help_text[] = + "" +#ifdef CONFIG_CMD_ZYNQ_RSA + "rsa - Verifies the authenticated and encrypted\n" + " zynq images and loads them back to load\n" + " addresses as specified in BOOT image(BOOT.BIN)\n" +#endif +#ifdef CONFIG_CMD_ZYNQ_AES + "aes \n" + " - Decrypts the encrypted image present in source\n" + " address and places the decrypted image at\n" + " destination address\n" +#endif + ; + +U_BOOT_CMD(zynq, 6, 0, do_zynq, + "Zynq specific commands", zynq_help_text +); diff --git a/configs/zynq_cse_qspi_defconfig b/configs/zynq_cse_qspi_defconfig index 2425dfa..df6ebdc 100644 --- a/configs/zynq_cse_qspi_defconfig +++ b/configs/zynq_cse_qspi_defconfig @@ -7,6 +7,7 @@ CONFIG_DEBUG_UART_BASE=0x0 CONFIG_DEBUG_UART_CLOCK=0 CONFIG_SPL_STACK_R_ADDR=0x200000 # CONFIG_ZYNQ_DDRC_INIT is not set +# CONFIG_CMD_ZYNQ is not set CONFIG_DEFAULT_DEVICE_TREE="zynq-cse-qspi-single" CONFIG_DEBUG_UART=y CONFIG_DISTRO_DEFAULTS=y diff --git a/drivers/fpga/zynqpl.c b/drivers/fpga/zynqpl.c index fd37d18..6409d30 100644 --- a/drivers/fpga/zynqpl.c +++ b/drivers/fpga/zynqpl.c @@ -17,6 +17,7 @@ #define DEVCFG_CTRL_PCFG_PROG_B 0x40000000 #define DEVCFG_CTRL_PCFG_AES_EFUSE_MASK 0x00001000 +#define DEVCFG_CTRL_PCAP_RATE_EN_MASK 0x02000000 #define DEVCFG_ISR_FATAL_ERROR_MASK 0x00740040 #define DEVCFG_ISR_ERROR_FLAGS_MASK 0x00340840 #define DEVCFG_ISR_RX_FIFO_OV 0x00040000 @@ -497,3 +498,47 @@ struct xilinx_fpga_op zynq_op = { .loadfs = zynq_loadfs, #endif }; + +#ifdef CONFIG_CMD_ZYNQ_AES +/* + * Load the encrypted image from src addr and decrypt the image and + * place it back the decrypted image into dstaddr. + */ +int zynq_decrypt_load(u32 srcaddr, u32 srclen, u32 dstaddr, u32 dstlen) +{ + if (srcaddr < SZ_1M || dstaddr < SZ_1M) { + printf("%s: src and dst addr should be > 1M\n", + __func__); + return FPGA_FAIL; + } + + if (zynq_dma_xfer_init(BIT_NONE)) { + printf("%s: zynq_dma_xfer_init FAIL\n", __func__); + return FPGA_FAIL; + } + + writel((readl(&devcfg_base->ctrl) | DEVCFG_CTRL_PCAP_RATE_EN_MASK), + &devcfg_base->ctrl); + + debug("%s: Source = 0x%08X\n", __func__, (u32)srcaddr); + debug("%s: Size = %zu\n", __func__, srclen); + + /* flush(clean & invalidate) d-cache range buf */ + flush_dcache_range((u32)srcaddr, (u32)srcaddr + + roundup(srclen << 2, ARCH_DMA_MINALIGN)); + /* + * Flush destination address range only if image is not + * bitstream. + */ + flush_dcache_range((u32)dstaddr, (u32)dstaddr + + roundup(dstlen << 2, ARCH_DMA_MINALIGN)); + + if (zynq_dma_transfer(srcaddr | 1, srclen, dstaddr | 1, dstlen)) + return FPGA_FAIL; + + writel((readl(&devcfg_base->ctrl) & ~DEVCFG_CTRL_PCAP_RATE_EN_MASK), + &devcfg_base->ctrl); + + return FPGA_SUCCESS; +} +#endif diff --git a/include/u-boot/rsa-mod-exp.h b/include/u-boot/rsa-mod-exp.h index 3253614..8a428c4 100644 --- a/include/u-boot/rsa-mod-exp.h +++ b/include/u-boot/rsa-mod-exp.h @@ -42,6 +42,10 @@ int rsa_mod_exp_sw(const uint8_t *sig, uint32_t sig_len, int rsa_mod_exp(struct udevice *dev, const uint8_t *sig, uint32_t sig_len, struct key_prop *node, uint8_t *out); +#if defined(CONFIG_CMD_ZYNQ_RSA) +int zynq_pow_mod(u32 *keyptr, u32 *inout); +#endif + /** * struct struct mod_exp_ops - Driver model for RSA Modular Exponentiation * operations diff --git a/include/zynq_bootimg.h b/include/zynq_bootimg.h new file mode 100644 index 0000000..c39c0bf --- /dev/null +++ b/include/zynq_bootimg.h @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2018 Xilinx, Inc. + */ + +#ifndef _ZYNQ_BOOTIMG_H_ +#define _ZYNQ_BOOTIMG_H_ + +#define ZYNQ_MAX_PARTITION_NUMBER 0xE + +struct partition_hdr { + u32 imagewordlen; /* 0x0 */ + u32 datawordlen; /* 0x4 */ + u32 partitionwordlen; /* 0x8 */ + u32 loadaddr; /* 0xC */ + u32 execaddr; /* 0x10 */ + u32 partitionstart; /* 0x14 */ + u32 partitionattr; /* 0x18 */ + u32 sectioncount; /* 0x1C */ + u32 checksumoffset; /* 0x20 */ + u32 pads1[1]; + u32 acoffset; /* 0x28 */ + u32 pads2[4]; + u32 checksum; /* 0x3C */ +}; + +int zynq_get_part_count(struct partition_hdr *part_hdr_info); +int zynq_get_partition_info(u32 image_base_addr, u32 *fsbl_len, + struct partition_hdr *part_hdr); +int zynq_validate_hdr(struct partition_hdr *header); +int zynq_validate_partition(u32 start_addr, u32 len, u32 chksum_off); + +#endif /* _ZYNQ_BOOTIMG_H_ */ diff --git a/include/zynqpl.h b/include/zynqpl.h index cdfd8a2..766e691 100644 --- a/include/zynqpl.h +++ b/include/zynqpl.h @@ -11,6 +11,10 @@ #include +#ifdef CONFIG_CMD_ZYNQ_AES +int zynq_decrypt_load(u32 srcaddr, u32 dstaddr, u32 srclen, u32 dstlen); +#endif + extern struct xilinx_fpga_op zynq_op; #define XILINX_ZYNQ_XC7Z007S 0x3 diff --git a/lib/rsa/rsa-mod-exp.c b/lib/rsa/rsa-mod-exp.c index 031c710..420ab2e 100644 --- a/lib/rsa/rsa-mod-exp.c +++ b/lib/rsa/rsa-mod-exp.c @@ -300,3 +300,54 @@ int rsa_mod_exp_sw(const uint8_t *sig, uint32_t sig_len, return 0; } + +#if defined(CONFIG_CMD_ZYNQ_RSA) +/** + * zynq_pow_mod - in-place public exponentiation + * + * @keyptr: RSA key + * @inout: Big-endian word array containing value and result + * @return 0 on successful calculation, otherwise failure error code + * + * FIXME: Use pow_mod() instead of zynq_pow_mod() + * pow_mod calculation required for zynq is bit different from + * pw_mod above here, hence defined zynq specific routine. + */ +int zynq_pow_mod(u32 *keyptr, u32 *inout) +{ + u32 *result, *ptr; + uint i; + struct rsa_public_key *key; + u32 val[RSA2048_BYTES], acc[RSA2048_BYTES], tmp[RSA2048_BYTES]; + + key = (struct rsa_public_key *)keyptr; + + /* Sanity check for stack size - key->len is in 32-bit words */ + if (key->len > RSA_MAX_KEY_BITS / 32) { + debug("RSA key words %u exceeds maximum %d\n", key->len, + RSA_MAX_KEY_BITS / 32); + return -EINVAL; + } + + result = tmp; /* Re-use location. */ + + for (i = 0, ptr = inout; i < key->len; i++, ptr++) + val[i] = *(ptr); + + montgomery_mul(key, acc, val, key->rr); /* axx = a * RR / R mod M */ + for (i = 0; i < 16; i += 2) { + montgomery_mul(key, tmp, acc, acc); /* tmp = acc^2 / R mod M */ + montgomery_mul(key, acc, tmp, tmp); /* acc = tmp^2 / R mod M */ + } + montgomery_mul(key, result, acc, val); /* result = XX * a / R mod M */ + + /* Make sure result < mod; result is at most 1x mod too large. */ + if (greater_equal_modulus(key, result)) + subtract_modulus(key, result); + + for (i = 0, ptr = inout; i < key->len; i++, ptr++) + *ptr = result[i]; + + return 0; +} +#endif From 4ab11ecaaa5f24ffef32b7606c5452b1f83e75af Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Thu, 28 Jun 2018 10:41:56 +0200 Subject: [PATCH 12/55] microblaze: Use default implementation from include/linux/io.h There is no reason not to use default ioremap/iounmap io functions. The patch remove Microblaze macros. Signed-off-by: Michal Simek --- arch/microblaze/include/asm/io.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/arch/microblaze/include/asm/io.h b/arch/microblaze/include/asm/io.h index c7516a4..26a437c 100644 --- a/arch/microblaze/include/asm/io.h +++ b/arch/microblaze/include/asm/io.h @@ -120,9 +120,6 @@ io_outsl (unsigned long port, const void *src, unsigned long count) #define insw(a,b,l) io_insw(a,b,l) #define insl(a,b,l) io_insl(a,b,l) - -#define iounmap(addr) ((void)0) -#define ioremap(physaddr, size) (physaddr) #define ioremap_nocache(physaddr, size) (physaddr) #define ioremap_writethrough(physaddr, size) (physaddr) #define ioremap_fullcache(physaddr, size) (physaddr) From d6c856c008a3f24a4606e14bbf3039a7355ec42a Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Thu, 28 Jun 2018 10:30:05 +0200 Subject: [PATCH 13/55] microblaze: Guard do_reset by CONFIG_SYSRESET sysreset uclass have own do_reset function which should be used instead of board/platform specific. Signed-off-by: Michal Simek --- board/xilinx/microblaze-generic/microblaze-generic.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/board/xilinx/microblaze-generic/microblaze-generic.c b/board/xilinx/microblaze-generic/microblaze-generic.c index 58ca1d7..889695f 100644 --- a/board/xilinx/microblaze-generic/microblaze-generic.c +++ b/board/xilinx/microblaze-generic/microblaze-generic.c @@ -58,6 +58,7 @@ int dram_init(void) return 0; }; +#if !defined(CONFIG_SYSRESET) || defined(CONFIG_SPL_BUILD) int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { #ifndef CONFIG_SPL_BUILD @@ -76,6 +77,7 @@ int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) return 0; } +#endif static int gpio_init(void) { From 3c3dee373a1a03b4f2390978bfaef260fc8f5622 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Wed, 27 Jun 2018 15:54:18 +0200 Subject: [PATCH 14/55] arm64: zcu100: Enable USB host ether and ASIX via defconfig There is no reason to keep these configs in platform config file. Signed-off-by: Michal Simek --- configs/xilinx_zynqmp_zcu100_revC_defconfig | 2 ++ include/configs/xilinx_zynqmp_zcu100.h | 3 --- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/configs/xilinx_zynqmp_zcu100_revC_defconfig b/configs/xilinx_zynqmp_zcu100_revC_defconfig index 154fffb..8e2ebc3 100644 --- a/configs/xilinx_zynqmp_zcu100_revC_defconfig +++ b/configs/xilinx_zynqmp_zcu100_revC_defconfig @@ -82,6 +82,8 @@ CONFIG_USB_ULPI=y CONFIG_USB_STORAGE=y CONFIG_USB_GADGET=y CONFIG_USB_GADGET_DOWNLOAD=y +CONFIG_USB_HOST_ETHER=y +CONFIG_USB_ETHER_ASIX=y CONFIG_WDT=y CONFIG_WDT_CDNS=y CONFIG_OF_LIBFDT_OVERLAY=y diff --git a/include/configs/xilinx_zynqmp_zcu100.h b/include/configs/xilinx_zynqmp_zcu100.h index b65d0c1..5ad9e1b 100644 --- a/include/configs/xilinx_zynqmp_zcu100.h +++ b/include/configs/xilinx_zynqmp_zcu100.h @@ -24,9 +24,6 @@ {0, {{I2C_MUX_PCA9548, 0x75, 7} } }, \ } -#define CONFIG_USB_HOST_ETHER -#define CONFIG_USB_ETHER_ASIX - #include #endif /* __CONFIG_ZYNQMP_ZCU100_H */ From 9713fac1eb104e87f8e2fe578c29c96bddef304c Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Wed, 11 Jul 2018 08:24:43 +0200 Subject: [PATCH 15/55] watchdog: dm: Change uclass name to watchdog and enable DM_UC_FLAG_SEQ_ALIAS uclass name is used by dev_read_alias_seq which return seq number when aliases are used. Code fragment: 168 int dev_read_alias_seq(struct udevice *dev, int *devnump) 169 { 170 ofnode node = dev_ofnode(dev); 171 const char *uc_name = dev->uclass->uc_drv->name; 172 int ret; 173 174 if (ofnode_is_np(node)) { 175 ret = of_alias_get_id(ofnode_to_np(node), uc_name); Also this patch enables DM_UC_FLAG_SEQ_ALIAS to be in sync with Linux which is also using watchdog name for watchdog aliases. drivers/watchdog/watchdog_core.c:215: ret = of_alias_get_id(wdd->parent->of_node, "watchdog"); Signed-off-by: Michal Simek Reviewed-by: Simon Glass --- drivers/watchdog/wdt-uclass.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/watchdog/wdt-uclass.c b/drivers/watchdog/wdt-uclass.c index 4a619f7..f6f2fe3 100644 --- a/drivers/watchdog/wdt-uclass.c +++ b/drivers/watchdog/wdt-uclass.c @@ -65,5 +65,6 @@ int wdt_expire_now(struct udevice *dev, ulong flags) UCLASS_DRIVER(wdt) = { .id = UCLASS_WDT, - .name = "wdt", + .name = "watchdog", + .flags = DM_UC_FLAG_SEQ_ALIAS, }; From f238b3f0fbc9ebc3a9702ddfc5ef22dff09f35d8 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Wed, 11 Jul 2018 15:42:25 +0200 Subject: [PATCH 16/55] watchdog: dm: Support manual relocation for watchdogs Relocate watchdog ops as was done by: "dm: Add support for all targets which requires MANUAL_RELOC" (sha1: 484fdf5ba058b07be5ca82763aa2b72063540ef3) Signed-off-by: Michal Simek Reviewed-by: Simon Glass --- drivers/watchdog/wdt-uclass.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/drivers/watchdog/wdt-uclass.c b/drivers/watchdog/wdt-uclass.c index f6f2fe3..23b7e33 100644 --- a/drivers/watchdog/wdt-uclass.c +++ b/drivers/watchdog/wdt-uclass.c @@ -63,8 +63,31 @@ int wdt_expire_now(struct udevice *dev, ulong flags) return ret; } +static int wdt_post_bind(struct udevice *dev) +{ +#if defined(CONFIG_NEEDS_MANUAL_RELOC) + struct wdt_ops *ops = (struct wdt_ops *)device_get_ops(dev); + static int reloc_done; + + if (!reloc_done) { + if (ops->start) + ops->start += gd->reloc_off; + if (ops->stop) + ops->stop += gd->reloc_off; + if (ops->reset) + ops->reset += gd->reloc_off; + if (ops->expire_now) + ops->expire_now += gd->reloc_off; + + reloc_done++; + } +#endif + return 0; +} + UCLASS_DRIVER(wdt) = { .id = UCLASS_WDT, .name = "watchdog", .flags = DM_UC_FLAG_SEQ_ALIAS, + .post_bind = wdt_post_bind, }; From b68e40e64130379e5b5fcd2fca0b86eb311c065c Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Thu, 12 Jul 2018 07:50:59 +0200 Subject: [PATCH 17/55] arm64: zynqmp: Sync defconfigs in connection to DEFINE_TCM_OCM_MMAP CONFIG_MP was added to Kconfig with enabling CONFIG_DEFINE_TCM_OCM_MMAP=y for zynqmp boards. This option is enabled by default that's why it shouldn't be in defconfig. Signed-off-by: Michal Simek --- configs/xilinx_zynqmp_zc1232_revA_defconfig | 1 - configs/xilinx_zynqmp_zc1254_revA_defconfig | 1 - configs/xilinx_zynqmp_zc1275_revA_defconfig | 1 - configs/xilinx_zynqmp_zc1275_revB_defconfig | 1 - configs/xilinx_zynqmp_zc1751_xm015_dc1_defconfig | 1 - configs/xilinx_zynqmp_zc1751_xm016_dc2_defconfig | 1 - configs/xilinx_zynqmp_zc1751_xm017_dc3_defconfig | 1 - configs/xilinx_zynqmp_zc1751_xm018_dc4_defconfig | 1 - configs/xilinx_zynqmp_zc1751_xm019_dc5_defconfig | 1 - configs/xilinx_zynqmp_zcu100_revC_defconfig | 1 - configs/xilinx_zynqmp_zcu102_rev1_0_defconfig | 1 - configs/xilinx_zynqmp_zcu102_revA_defconfig | 1 - configs/xilinx_zynqmp_zcu102_revB_defconfig | 1 - configs/xilinx_zynqmp_zcu104_revA_defconfig | 1 - configs/xilinx_zynqmp_zcu104_revC_defconfig | 1 - configs/xilinx_zynqmp_zcu106_revA_defconfig | 1 - configs/xilinx_zynqmp_zcu111_revA_defconfig | 1 - 17 files changed, 17 deletions(-) diff --git a/configs/xilinx_zynqmp_zc1232_revA_defconfig b/configs/xilinx_zynqmp_zc1232_revA_defconfig index b4a8004..10f4896 100644 --- a/configs/xilinx_zynqmp_zc1232_revA_defconfig +++ b/configs/xilinx_zynqmp_zc1232_revA_defconfig @@ -7,7 +7,6 @@ CONFIG_DEBUG_UART_BASE=0xff000000 CONFIG_DEBUG_UART_CLOCK=100000000 # CONFIG_SPL_FAT_SUPPORT is not set # CONFIG_SPL_LIBDISK_SUPPORT is not set -CONFIG_DEFINE_TCM_OCM_MMAP=y CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zc1232-revA" CONFIG_DEBUG_UART=y CONFIG_DISTRO_DEFAULTS=y diff --git a/configs/xilinx_zynqmp_zc1254_revA_defconfig b/configs/xilinx_zynqmp_zc1254_revA_defconfig index cd2214c..d039251 100644 --- a/configs/xilinx_zynqmp_zc1254_revA_defconfig +++ b/configs/xilinx_zynqmp_zc1254_revA_defconfig @@ -7,7 +7,6 @@ CONFIG_DEBUG_UART_BASE=0xff000000 CONFIG_DEBUG_UART_CLOCK=100000000 # CONFIG_SPL_FAT_SUPPORT is not set # CONFIG_SPL_LIBDISK_SUPPORT is not set -CONFIG_DEFINE_TCM_OCM_MMAP=y CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zc1254-revA" CONFIG_DEBUG_UART=y CONFIG_DISTRO_DEFAULTS=y diff --git a/configs/xilinx_zynqmp_zc1275_revA_defconfig b/configs/xilinx_zynqmp_zc1275_revA_defconfig index a4543fb..c66b9c0 100644 --- a/configs/xilinx_zynqmp_zc1275_revA_defconfig +++ b/configs/xilinx_zynqmp_zc1275_revA_defconfig @@ -7,7 +7,6 @@ CONFIG_DEBUG_UART_BASE=0xff000000 CONFIG_DEBUG_UART_CLOCK=100000000 # CONFIG_SPL_FAT_SUPPORT is not set # CONFIG_SPL_LIBDISK_SUPPORT is not set -CONFIG_DEFINE_TCM_OCM_MMAP=y CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zc1275-revA" CONFIG_DEBUG_UART=y CONFIG_DISTRO_DEFAULTS=y diff --git a/configs/xilinx_zynqmp_zc1275_revB_defconfig b/configs/xilinx_zynqmp_zc1275_revB_defconfig index 93be68f..b3a4bff 100644 --- a/configs/xilinx_zynqmp_zc1275_revB_defconfig +++ b/configs/xilinx_zynqmp_zc1275_revB_defconfig @@ -8,7 +8,6 @@ CONFIG_DEBUG_UART_BASE=0xff000000 CONFIG_DEBUG_UART_CLOCK=100000000 # CONFIG_SPL_FAT_SUPPORT is not set # CONFIG_SPL_LIBDISK_SUPPORT is not set -CONFIG_DEFINE_TCM_OCM_MMAP=y CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zc1275-revB" CONFIG_DEBUG_UART=y CONFIG_DISTRO_DEFAULTS=y diff --git a/configs/xilinx_zynqmp_zc1751_xm015_dc1_defconfig b/configs/xilinx_zynqmp_zc1751_xm015_dc1_defconfig index 7258733..3a65cd9 100644 --- a/configs/xilinx_zynqmp_zc1751_xm015_dc1_defconfig +++ b/configs/xilinx_zynqmp_zc1751_xm015_dc1_defconfig @@ -7,7 +7,6 @@ CONFIG_SPL=y CONFIG_DEBUG_UART_BASE=0xff000000 CONFIG_DEBUG_UART_CLOCK=100000000 CONFIG_ZYNQMP_USB=y -CONFIG_DEFINE_TCM_OCM_MMAP=y CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zc1751-xm015-dc1" CONFIG_DEBUG_UART=y CONFIG_AHCI=y diff --git a/configs/xilinx_zynqmp_zc1751_xm016_dc2_defconfig b/configs/xilinx_zynqmp_zc1751_xm016_dc2_defconfig index f9246a1..e5e719d 100644 --- a/configs/xilinx_zynqmp_zc1751_xm016_dc2_defconfig +++ b/configs/xilinx_zynqmp_zc1751_xm016_dc2_defconfig @@ -8,7 +8,6 @@ CONFIG_DEBUG_UART_CLOCK=100000000 # CONFIG_SPL_FAT_SUPPORT is not set # CONFIG_SPL_LIBDISK_SUPPORT is not set CONFIG_ZYNQMP_USB=y -CONFIG_DEFINE_TCM_OCM_MMAP=y CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zc1751-xm016-dc2" CONFIG_DEBUG_UART=y CONFIG_DISTRO_DEFAULTS=y diff --git a/configs/xilinx_zynqmp_zc1751_xm017_dc3_defconfig b/configs/xilinx_zynqmp_zc1751_xm017_dc3_defconfig index cd752f4..7e8b180 100644 --- a/configs/xilinx_zynqmp_zc1751_xm017_dc3_defconfig +++ b/configs/xilinx_zynqmp_zc1751_xm017_dc3_defconfig @@ -7,7 +7,6 @@ CONFIG_SPL=y CONFIG_DEBUG_UART_BASE=0xff010000 CONFIG_DEBUG_UART_CLOCK=100000000 CONFIG_ZYNQMP_USB=y -CONFIG_DEFINE_TCM_OCM_MMAP=y CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zc1751-xm017-dc3" CONFIG_DEBUG_UART=y CONFIG_AHCI=y diff --git a/configs/xilinx_zynqmp_zc1751_xm018_dc4_defconfig b/configs/xilinx_zynqmp_zc1751_xm018_dc4_defconfig index baa3f38..efb0b20 100644 --- a/configs/xilinx_zynqmp_zc1751_xm018_dc4_defconfig +++ b/configs/xilinx_zynqmp_zc1751_xm018_dc4_defconfig @@ -5,7 +5,6 @@ CONFIG_SYS_MALLOC_F_LEN=0x8000 CONFIG_SPL=y CONFIG_DEBUG_UART_BASE=0xff000000 CONFIG_DEBUG_UART_CLOCK=100000000 -CONFIG_DEFINE_TCM_OCM_MMAP=y CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zc1751-xm018-dc4" CONFIG_DEBUG_UART=y CONFIG_DISTRO_DEFAULTS=y diff --git a/configs/xilinx_zynqmp_zc1751_xm019_dc5_defconfig b/configs/xilinx_zynqmp_zc1751_xm019_dc5_defconfig index ca19e93..1a6124b 100644 --- a/configs/xilinx_zynqmp_zc1751_xm019_dc5_defconfig +++ b/configs/xilinx_zynqmp_zc1751_xm019_dc5_defconfig @@ -6,7 +6,6 @@ CONFIG_SYS_MALLOC_F_LEN=0x8000 CONFIG_SPL=y CONFIG_DEBUG_UART_BASE=0xff000000 CONFIG_DEBUG_UART_CLOCK=100000000 -CONFIG_DEFINE_TCM_OCM_MMAP=y CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zc1751-xm019-dc5" CONFIG_DEBUG_UART=y CONFIG_DISTRO_DEFAULTS=y diff --git a/configs/xilinx_zynqmp_zcu100_revC_defconfig b/configs/xilinx_zynqmp_zcu100_revC_defconfig index 8e2ebc3..802f4e7 100644 --- a/configs/xilinx_zynqmp_zcu100_revC_defconfig +++ b/configs/xilinx_zynqmp_zcu100_revC_defconfig @@ -8,7 +8,6 @@ CONFIG_DEBUG_UART_BASE=0xff010000 CONFIG_DEBUG_UART_CLOCK=100000000 CONFIG_ZYNQ_SDHCI_MAX_FREQ=15000000 CONFIG_ZYNQMP_USB=y -CONFIG_DEFINE_TCM_OCM_MMAP=y CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zcu100-revC" CONFIG_DEBUG_UART=y CONFIG_DISTRO_DEFAULTS=y diff --git a/configs/xilinx_zynqmp_zcu102_rev1_0_defconfig b/configs/xilinx_zynqmp_zcu102_rev1_0_defconfig index 5a7d91d..5dea5ce 100644 --- a/configs/xilinx_zynqmp_zcu102_rev1_0_defconfig +++ b/configs/xilinx_zynqmp_zcu102_rev1_0_defconfig @@ -7,7 +7,6 @@ CONFIG_SPL=y CONFIG_DEBUG_UART_BASE=0xff000000 CONFIG_DEBUG_UART_CLOCK=100000000 CONFIG_ZYNQMP_USB=y -CONFIG_DEFINE_TCM_OCM_MMAP=y CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zcu102-rev1.0" CONFIG_DEBUG_UART=y CONFIG_AHCI=y diff --git a/configs/xilinx_zynqmp_zcu102_revA_defconfig b/configs/xilinx_zynqmp_zcu102_revA_defconfig index 5b67ff9..49a9a4f 100644 --- a/configs/xilinx_zynqmp_zcu102_revA_defconfig +++ b/configs/xilinx_zynqmp_zcu102_revA_defconfig @@ -7,7 +7,6 @@ CONFIG_SPL=y CONFIG_DEBUG_UART_BASE=0xff000000 CONFIG_DEBUG_UART_CLOCK=100000000 CONFIG_ZYNQMP_USB=y -CONFIG_DEFINE_TCM_OCM_MMAP=y CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zcu102-revA" CONFIG_DEBUG_UART=y CONFIG_AHCI=y diff --git a/configs/xilinx_zynqmp_zcu102_revB_defconfig b/configs/xilinx_zynqmp_zcu102_revB_defconfig index deaae6c..589c8e3 100644 --- a/configs/xilinx_zynqmp_zcu102_revB_defconfig +++ b/configs/xilinx_zynqmp_zcu102_revB_defconfig @@ -7,7 +7,6 @@ CONFIG_SPL=y CONFIG_DEBUG_UART_BASE=0xff000000 CONFIG_DEBUG_UART_CLOCK=100000000 CONFIG_ZYNQMP_USB=y -CONFIG_DEFINE_TCM_OCM_MMAP=y CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zcu102-revB" CONFIG_DEBUG_UART=y CONFIG_AHCI=y diff --git a/configs/xilinx_zynqmp_zcu104_revA_defconfig b/configs/xilinx_zynqmp_zcu104_revA_defconfig index 18d12a6..34ea79b 100644 --- a/configs/xilinx_zynqmp_zcu104_revA_defconfig +++ b/configs/xilinx_zynqmp_zcu104_revA_defconfig @@ -7,7 +7,6 @@ CONFIG_SPL=y CONFIG_DEBUG_UART_BASE=0xff000000 CONFIG_DEBUG_UART_CLOCK=100000000 CONFIG_ZYNQMP_USB=y -CONFIG_DEFINE_TCM_OCM_MMAP=y CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zcu104-revA" CONFIG_DEBUG_UART=y CONFIG_AHCI=y diff --git a/configs/xilinx_zynqmp_zcu104_revC_defconfig b/configs/xilinx_zynqmp_zcu104_revC_defconfig index ec8218c..9d072a3 100644 --- a/configs/xilinx_zynqmp_zcu104_revC_defconfig +++ b/configs/xilinx_zynqmp_zcu104_revC_defconfig @@ -7,7 +7,6 @@ CONFIG_SPL=y CONFIG_DEBUG_UART_BASE=0xff000000 CONFIG_DEBUG_UART_CLOCK=100000000 CONFIG_ZYNQMP_USB=y -CONFIG_DEFINE_TCM_OCM_MMAP=y CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zcu104-revC" CONFIG_DEBUG_UART=y CONFIG_AHCI=y diff --git a/configs/xilinx_zynqmp_zcu106_revA_defconfig b/configs/xilinx_zynqmp_zcu106_revA_defconfig index 15eeb95..c8a50d3 100644 --- a/configs/xilinx_zynqmp_zcu106_revA_defconfig +++ b/configs/xilinx_zynqmp_zcu106_revA_defconfig @@ -7,7 +7,6 @@ CONFIG_SPL=y CONFIG_DEBUG_UART_BASE=0xff000000 CONFIG_DEBUG_UART_CLOCK=100000000 CONFIG_ZYNQMP_USB=y -CONFIG_DEFINE_TCM_OCM_MMAP=y CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zcu106-revA" CONFIG_DEBUG_UART=y CONFIG_AHCI=y diff --git a/configs/xilinx_zynqmp_zcu111_revA_defconfig b/configs/xilinx_zynqmp_zcu111_revA_defconfig index 55232e1..a9adfbe 100644 --- a/configs/xilinx_zynqmp_zcu111_revA_defconfig +++ b/configs/xilinx_zynqmp_zcu111_revA_defconfig @@ -7,7 +7,6 @@ CONFIG_SPL=y CONFIG_DEBUG_UART_BASE=0xff000000 CONFIG_DEBUG_UART_CLOCK=100000000 CONFIG_ZYNQMP_USB=y -CONFIG_DEFINE_TCM_OCM_MMAP=y CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zcu111-revA" CONFIG_DEBUG_UART=y CONFIG_AHCI=y From 71c52f2949b1b4e657e08d7130e50f315b857dc7 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Thu, 12 Jul 2018 08:46:11 +0200 Subject: [PATCH 18/55] microblaze: Remove unused XILINX_BOARD_NAME macro This macro is not used anywhere that's why remove it. Signed-off-by: Michal Simek --- board/xilinx/microblaze-generic/xparameters.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/board/xilinx/microblaze-generic/xparameters.h b/board/xilinx/microblaze-generic/xparameters.h index 51bca40..57998ed 100644 --- a/board/xilinx/microblaze-generic/xparameters.h +++ b/board/xilinx/microblaze-generic/xparameters.h @@ -10,8 +10,6 @@ * the generated file from your Xilinx design flow. */ -#define XILINX_BOARD_NAME microblaze-generic - /* Microblaze is microblaze_0 */ #define XILINX_FSL_NUMBER 3 From 946205a8570bd5bf961aa0da8d82e0d0aa26f8c6 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Thu, 12 Jul 2018 12:30:34 +0200 Subject: [PATCH 19/55] gpio: zynq: Fix typo in one error message Just fix error message. Signed-off-by: Michal Simek --- drivers/gpio/zynq_gpio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpio/zynq_gpio.c b/drivers/gpio/zynq_gpio.c index afba458..9a91554 100644 --- a/drivers/gpio/zynq_gpio.c +++ b/drivers/gpio/zynq_gpio.c @@ -178,7 +178,7 @@ static inline void zynq_gpio_get_bank_pin(unsigned int pin_num, } if (bank >= priv->p_data->max_bank) { - printf("Inavlid bank and pin num\n"); + printf("Invalid bank and pin num\n"); *bank_num = 0; *bank_pin_num = 0; } From 758de97bb8be091e0b1ab25af6bb9965d54fa839 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Thu, 12 Jul 2018 10:36:07 +0200 Subject: [PATCH 20/55] sysreset: dm: Support manual relocation for sysreset Relocate sysreset ops as was done by: "dm: Add support for all targets which requires MANUAL_RELOC" (sha1: 484fdf5ba058b07be5ca82763aa2b72063540ef3) Signed-off-by: Michal Simek Reviewed-by: Simon Glass --- drivers/sysreset/sysreset-uclass.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/drivers/sysreset/sysreset-uclass.c b/drivers/sysreset/sysreset-uclass.c index 7e06c3c..840eab6 100644 --- a/drivers/sysreset/sysreset-uclass.c +++ b/drivers/sysreset/sysreset-uclass.c @@ -74,7 +74,23 @@ int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) return 0; } +static int sysreset_post_bind(struct udevice *dev) +{ +#if defined(CONFIG_NEEDS_MANUAL_RELOC) + struct sysreset_ops *ops = sysreset_get_ops(dev); + static int reloc_done; + + if (!reloc_done) { + if (ops->request) + ops->request += gd->reloc_off; + reloc_done++; + } +#endif + return 0; +} + UCLASS_DRIVER(sysreset) = { .id = UCLASS_SYSRESET, .name = "sysreset", + .post_bind = sysreset_post_bind, }; From 1b4c2aa25bdfe327b3c496e7bfe3c98b0ad4de44 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Thu, 12 Jul 2018 12:42:27 +0200 Subject: [PATCH 21/55] gpio: dm: Support manual relocation for gpio Relocate gpio ops as was done by: "dm: Add support for all targets which requires MANUAL_RELOC" (sha1: 484fdf5ba058b07be5ca82763aa2b72063540ef3) Signed-off-by: Michal Simek Reviewed-by: Simon Glass --- drivers/gpio/gpio-uclass.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/drivers/gpio/gpio-uclass.c b/drivers/gpio/gpio-uclass.c index e9d08e2..da5e9ba 100644 --- a/drivers/gpio/gpio-uclass.c +++ b/drivers/gpio/gpio-uclass.c @@ -854,11 +854,46 @@ static int gpio_pre_remove(struct udevice *dev) return gpio_renumber(dev); } +static int gpio_post_bind(struct udevice *dev) +{ +#if defined(CONFIG_NEEDS_MANUAL_RELOC) + struct dm_gpio_ops *ops = (struct dm_gpio_ops *)device_get_ops(dev); + static int reloc_done; + + if (!reloc_done) { + if (ops->request) + ops->request += gd->reloc_off; + if (ops->free) + ops->free += gd->reloc_off; + if (ops->direction_input) + ops->direction_input += gd->reloc_off; + if (ops->direction_output) + ops->direction_output += gd->reloc_off; + if (ops->get_value) + ops->get_value += gd->reloc_off; + if (ops->set_value) + ops->set_value += gd->reloc_off; + if (ops->get_open_drain) + ops->get_open_drain += gd->reloc_off; + if (ops->set_open_drain) + ops->set_open_drain += gd->reloc_off; + if (ops->get_function) + ops->get_function += gd->reloc_off; + if (ops->xlate) + ops->xlate += gd->reloc_off; + + reloc_done++; + } +#endif + return 0; +} + UCLASS_DRIVER(gpio) = { .id = UCLASS_GPIO, .name = "gpio", .flags = DM_UC_FLAG_SEQ_ALIAS, .post_probe = gpio_post_probe, + .post_bind = gpio_post_bind, .pre_remove = gpio_pre_remove, .per_device_auto_alloc_size = sizeof(struct gpio_dev_priv), }; From 0df9bea4340ae64ec82004852ab325e869c371b8 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Thu, 12 Jul 2018 10:58:04 +0200 Subject: [PATCH 22/55] gpio: zynq: Read of mach data in platdata with dev_get_driver_data Remove bogus zynq_gpio_getplat_data() and read driver data directly. Signed-off-by: Michal Simek Reviewed-by: Simon Glass --- drivers/gpio/zynq_gpio.c | 29 ++--------------------------- 1 file changed, 2 insertions(+), 27 deletions(-) diff --git a/drivers/gpio/zynq_gpio.c b/drivers/gpio/zynq_gpio.c index 9a91554..26f69b1 100644 --- a/drivers/gpio/zynq_gpio.c +++ b/drivers/gpio/zynq_gpio.c @@ -15,8 +15,6 @@ #include #include -DECLARE_GLOBAL_DATA_PTR; - /* Maximum banks */ #define ZYNQ_GPIO_MAX_BANK 4 @@ -334,36 +332,11 @@ static const struct udevice_id zynq_gpio_ids[] = { { } }; -static void zynq_gpio_getplat_data(struct udevice *dev) -{ - const struct udevice_id *of_match = zynq_gpio_ids; - int ret; - struct zynq_gpio_privdata *priv = dev_get_priv(dev); - - while (of_match->compatible) { - ret = fdt_node_offset_by_compatible(gd->fdt_blob, -1, - of_match->compatible); - if (ret >= 0) { - priv->p_data = - (struct zynq_platform_data *)of_match->data; - break; - } else { - of_match++; - continue; - } - } - - if (!priv->p_data) - printf("No Platform data found\n"); -} - static int zynq_gpio_probe(struct udevice *dev) { struct zynq_gpio_privdata *priv = dev_get_priv(dev); struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); - zynq_gpio_getplat_data(dev); - if (priv->p_data) uc_priv->gpio_count = priv->p_data->ngpio; @@ -376,6 +349,8 @@ static int zynq_gpio_ofdata_to_platdata(struct udevice *dev) priv->base = (phys_addr_t)dev_read_addr(dev); + priv->p_data = (struct zynq_platform_data *)dev_get_driver_data(dev); + return 0; } From 35670665d6b6176566b5701c078d5103c1ec4c86 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Wed, 11 Jul 2018 14:08:26 +0200 Subject: [PATCH 23/55] microblaze: Do not call timer init that early Timer needs to be converted to DM but as of now it can't be called so early because intc controller is not ready. Call it later in board_r.c. Before this patch timer_init is called twice which is wrong. The patch is blocking initialization before relocation. Signed-off-by: Michal Simek Reviewed-by: Simon Glass --- arch/microblaze/cpu/timer.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/microblaze/cpu/timer.c b/arch/microblaze/cpu/timer.c index ef22902..58e5c30 100644 --- a/arch/microblaze/cpu/timer.c +++ b/arch/microblaze/cpu/timer.c @@ -51,6 +51,10 @@ int timer_init (void) debug("TIMER: Initialization\n"); + /* Do not init before relocation */ + if (!(gd->flags & GD_FLG_RELOC)) + return 0; + node = fdt_node_offset_by_compatible(blob, node, "xlnx,xps-timer-1.00.a"); if (node != -1) { From 0d6fabb82df100d709cef306a7d8c05025d5fa39 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Thu, 21 Jun 2018 13:58:56 +0200 Subject: [PATCH 24/55] gpio: zynq: Setup bank_name to dev->name There should be proper bank name setup to distinguish between different gpio drivers. Use dev->name for it. Signed-off-by: Michal Simek Reviewed-by: Simon Glass --- drivers/gpio/zynq_gpio.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpio/zynq_gpio.c b/drivers/gpio/zynq_gpio.c index 26f69b1..f793ee5 100644 --- a/drivers/gpio/zynq_gpio.c +++ b/drivers/gpio/zynq_gpio.c @@ -337,6 +337,8 @@ static int zynq_gpio_probe(struct udevice *dev) struct zynq_gpio_privdata *priv = dev_get_priv(dev); struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); + uc_priv->bank_name = dev->name; + if (priv->p_data) uc_priv->gpio_count = priv->p_data->ngpio; From 1fbca0db5d4785eb1e3e4e914bcd4a9864df3e53 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Wed, 11 Jul 2018 08:30:07 +0200 Subject: [PATCH 25/55] arm64: zynqmp: Try to enable the first watchdog via aliases Add support for enabling the first watchdog pointed via aliases. DT fragment: aliases { ... watchdog0 = &watchdog0; watchdog1 = &watchdog_lpd; ... }; dm tree fragment for above configuration with patch applied: ZynqMP> dm tree Class index Probed Driver Name ----------------------------------------- ... watchdog 0 [ ] cdns_wdt | |-- watchdog@ff150000 watchdog 1 [ + ] cdns_wdt | `-- watchdog@fd4d0000 ... dm uclass fragment: ZynqMP> dm uclass ... uclass 75: watchdog 0 watchdog@ff150000 @ 7df02f40, seq -1, (req 1) 1 * watchdog@fd4d0000 @ 7df02ff0, seq 0, (req 0) ... It is visible that index 1 is IP with seq 0 which means that FPD watchdog (@fd4d0000) is in DT below LPD watchdog (@ff150000). Till this patch the first watchdog found in DT was used and started which is not enabling all possible configuration based on user request. Signed-off-by: Michal Simek --- board/xilinx/zynqmp/zynqmp.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/board/xilinx/zynqmp/zynqmp.c b/board/xilinx/zynqmp/zynqmp.c index 81c10fc..06cdcbd 100644 --- a/board/xilinx/zynqmp/zynqmp.c +++ b/board/xilinx/zynqmp/zynqmp.c @@ -312,12 +312,16 @@ int board_init(void) #endif #if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_WDT) - if (uclass_get_device(UCLASS_WDT, 0, &watchdog_dev)) { - puts("Watchdog: Not found!\n"); - } else { - wdt_start(watchdog_dev, 0, 0); - puts("Watchdog: Started\n"); + if (uclass_get_device_by_seq(UCLASS_WDT, 0, &watchdog_dev)) { + debug("Watchdog: Not found by seq!\n"); + if (uclass_get_device(UCLASS_WDT, 0, &watchdog_dev)) { + puts("Watchdog: Not found!\n"); + return 0; + } } + + wdt_start(watchdog_dev, 0, 0); + puts("Watchdog: Started\n"); #endif return 0; From 501fc50a2964210412cb39679d0ac8e994c40ef8 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Wed, 11 Jul 2018 08:35:22 +0200 Subject: [PATCH 26/55] arm: zynq: Try to enable the first watchdog via aliases The same change as was done for zynqmp with this description: Add support for enabling the first watchdog pointed via aliases. DT fragment: aliases { ... watchdog0= &watchdog0; watchdog1 = &watchdog_lpd; ... }; Till this patch the first watchdog found in DT was used and started which is not enabling all possible configuration based on user request. Signed-off-by: Michal Simek --- board/xilinx/zynq/board.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/board/xilinx/zynq/board.c b/board/xilinx/zynq/board.c index 1106f5c..9c005e4 100644 --- a/board/xilinx/zynq/board.c +++ b/board/xilinx/zynq/board.c @@ -36,12 +36,16 @@ int board_early_init_f(void) int board_init(void) { #if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_WDT) - if (uclass_get_device(UCLASS_WDT, 0, &watchdog_dev)) { - puts("Watchdog: Not found!\n"); - } else { - wdt_start(watchdog_dev, 0, 0); - puts("Watchdog: Started\n"); + if (uclass_get_device_by_seq(UCLASS_WDT, 0, &watchdog_dev)) { + debug("Watchdog: Not found by seq!\n"); + if (uclass_get_device(UCLASS_WDT, 0, &watchdog_dev)) { + puts("Watchdog: Not found!\n"); + return 0; + } } + + wdt_start(watchdog_dev, 0, 0); + puts("Watchdog: Started\n"); # endif return 0; From 0d832b322109e76953bc58e4d2723d2c73dfb604 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Fri, 13 Jul 2018 11:04:56 +0200 Subject: [PATCH 27/55] sysreset: Add support for gpio-restart The Linux kernel has binding for gpio-restart node. This patch is adding basic support without supporting any optional properties. This driver was tested on Microblaze system where gpio is connected to SoC reset logic. Output value is handled via gpios cells values. In gpio_reboot_request() set_value is writing 1 because dm_gpio_set_value() is capable to changing it when it is ACTIVE_LOW. ... if (desc->flags & GPIOD_ACTIVE_LOW) value = !value; ... Signed-off-by: Michal Simek Reviewed-by: Philipp Tomsich Reviewed-by: Simon Glass --- MAINTAINERS | 1 + drivers/sysreset/Kconfig | 8 ++++++ drivers/sysreset/Makefile | 1 + drivers/sysreset/sysreset_gpio.c | 59 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 69 insertions(+) create mode 100644 drivers/sysreset/sysreset_gpio.c diff --git a/MAINTAINERS b/MAINTAINERS index 570bc6d..91e4ad7 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -419,6 +419,7 @@ F: drivers/net/xilinx_axi_emac.c F: drivers/net/xilinx_emaclite.c F: drivers/serial/serial_xuartlite.c F: drivers/spi/xilinx_spi.c +F: drivers/sysreset/sysreset_gpio.c F: drivers/watchdog/xilinx_tb_wdt.c N: xilinx diff --git a/drivers/sysreset/Kconfig b/drivers/sysreset/Kconfig index a6d48e8..cec612e 100644 --- a/drivers/sysreset/Kconfig +++ b/drivers/sysreset/Kconfig @@ -15,6 +15,14 @@ config SYSRESET if SYSRESET +config SYSRESET_GPIO + bool "Enable support for GPIO reset driver" + select GPIO + help + Reset support via GPIO pin connected reset logic. This is used for + example on Microblaze where reset logic can be controlled via GPIO + pin which triggers cpu reset. + config SYSRESET_PSCI bool "Enable support for PSCI System Reset" depends on ARM_PSCI_FW diff --git a/drivers/sysreset/Makefile b/drivers/sysreset/Makefile index 0da58a1..ca533cf 100644 --- a/drivers/sysreset/Makefile +++ b/drivers/sysreset/Makefile @@ -3,6 +3,7 @@ # (C) Copyright 2016 Cadence Design Systems Inc. obj-$(CONFIG_SYSRESET) += sysreset-uclass.o +obj-$(CONFIG_SYSRESET_GPIO) += sysreset_gpio.o obj-$(CONFIG_SYSRESET_PSCI) += sysreset_psci.o obj-$(CONFIG_SYSRESET_SYSCON) += sysreset_syscon.o obj-$(CONFIG_SYSRESET_WATCHDOG) += sysreset_watchdog.o diff --git a/drivers/sysreset/sysreset_gpio.c b/drivers/sysreset/sysreset_gpio.c new file mode 100644 index 0000000..ed9a49a --- /dev/null +++ b/drivers/sysreset/sysreset_gpio.c @@ -0,0 +1,59 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2018 Xilinx, Inc. - Michal Simek + */ + +#include +#include +#include +#include +#include + +struct gpio_reboot_priv { + struct gpio_desc gpio; +}; + +static int gpio_reboot_request(struct udevice *dev, enum sysreset_t type) +{ + struct gpio_reboot_priv *priv = dev_get_priv(dev); + + /* + * When debug log is enabled please make sure that chars won't end up + * in output fifo. Or you can append udelay(); to get enough time + * to HW to emit output fifo. + */ + debug("GPIO reset\n"); + + /* Writing 1 respects polarity (active high/low) based on gpio->flags */ + return dm_gpio_set_value(&priv->gpio, 1); +} + +static struct sysreset_ops gpio_reboot_ops = { + .request = gpio_reboot_request, +}; + +int gpio_reboot_probe(struct udevice *dev) +{ + struct gpio_reboot_priv *priv = dev_get_priv(dev); + + /* + * Linux kernel DT binding contain others optional properties + * which are not supported now + */ + + return gpio_request_by_name(dev, "gpios", 0, &priv->gpio, GPIOD_IS_OUT); +} + +static const struct udevice_id led_gpio_ids[] = { + { .compatible = "gpio-restart" }, + { } +}; + +U_BOOT_DRIVER(gpio_reboot) = { + .id = UCLASS_SYSRESET, + .name = "gpio_restart", + .of_match = led_gpio_ids, + .ops = &gpio_reboot_ops, + .priv_auto_alloc_size = sizeof(struct gpio_reboot_priv), + .probe = gpio_reboot_probe, +}; From cae39ae365ed98b7cd0805fcb57ca4ee280b5ebe Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Fri, 13 Jul 2018 17:00:13 +0200 Subject: [PATCH 28/55] sysreset: Add support for Microblaze soft reset jump Microblaze is storing reset vector at address 0x0. It means soft reset can be done by just jumping to this address. This code was in platform code but sysreset interface is providing enough capabilities to have more options how to reset the system. It can go from gpio reset through watchdog reset till soft reset. The driver has not compatible string because this is cpu specific and DM core is not able to detect compatible string in DT root that's why this driver will be instantiated from platform code by calling device_bind_driver(gd->dm_root, "mb_soft_reset", "reset_soft", NULL); It should be bind as the last reset method to ensure that hw reset is called before this. Signed-off-by: Michal Simek --- drivers/sysreset/Kconfig | 6 ++++++ drivers/sysreset/Makefile | 1 + drivers/sysreset/sysreset_microblaze.c | 30 ++++++++++++++++++++++++++++++ 3 files changed, 37 insertions(+) create mode 100644 drivers/sysreset/sysreset_microblaze.c diff --git a/drivers/sysreset/Kconfig b/drivers/sysreset/Kconfig index cec612e..f2524c1 100644 --- a/drivers/sysreset/Kconfig +++ b/drivers/sysreset/Kconfig @@ -23,6 +23,12 @@ config SYSRESET_GPIO example on Microblaze where reset logic can be controlled via GPIO pin which triggers cpu reset. +config SYSRESET_MICROBLAZE + bool "Enable support for Microblaze soft reset" + depends on MICROBLAZE + help + This is soft reset on Microblaze which does jump to 0x0 address. + config SYSRESET_PSCI bool "Enable support for PSCI System Reset" depends on ARM_PSCI_FW diff --git a/drivers/sysreset/Makefile b/drivers/sysreset/Makefile index ca533cf..223a071 100644 --- a/drivers/sysreset/Makefile +++ b/drivers/sysreset/Makefile @@ -4,6 +4,7 @@ obj-$(CONFIG_SYSRESET) += sysreset-uclass.o obj-$(CONFIG_SYSRESET_GPIO) += sysreset_gpio.o +obj-$(CONFIG_SYSRESET_MICROBLAZE) += sysreset_microblaze.o obj-$(CONFIG_SYSRESET_PSCI) += sysreset_psci.o obj-$(CONFIG_SYSRESET_SYSCON) += sysreset_syscon.o obj-$(CONFIG_SYSRESET_WATCHDOG) += sysreset_watchdog.o diff --git a/drivers/sysreset/sysreset_microblaze.c b/drivers/sysreset/sysreset_microblaze.c new file mode 100644 index 0000000..514c958 --- /dev/null +++ b/drivers/sysreset/sysreset_microblaze.c @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2018 Xilinx, Inc. - Michal Simek + */ + +#include +#include +#include +#include +#include + +static int microblaze_sysreset_request(struct udevice *dev, + enum sysreset_t type) +{ + puts("Microblaze soft reset sysreset\n"); + __asm__ __volatile__ (" mts rmsr, r0;" \ + "bra r0"); + + return -EINPROGRESS; +} + +static struct sysreset_ops microblaze_sysreset = { + .request = microblaze_sysreset_request, +}; + +U_BOOT_DRIVER(sysreset_microblaze) = { + .id = UCLASS_SYSRESET, + .name = "mb_soft_reset", + .ops = µblaze_sysreset, +}; From 10441ec9224d0d269dc512819a32c0785a6338d3 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Thu, 12 Jul 2018 16:05:46 +0200 Subject: [PATCH 29/55] gpio: xilinx: Convert driver to DM This patch is enabling GPIO_DM support to have an option to use this driver together with zynq gpio driver. !DM part is kept there till Microblaze is cleanup which will be done hopefully soon. Just a note: There is no reason to initialize uc-priv->name because it is completely unused. Signed-off-by: Michal Simek --- drivers/gpio/xilinx_gpio.c | 265 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 264 insertions(+), 1 deletion(-) diff --git a/drivers/gpio/xilinx_gpio.c b/drivers/gpio/xilinx_gpio.c index 74c5be0..48b52c9 100644 --- a/drivers/gpio/xilinx_gpio.c +++ b/drivers/gpio/xilinx_gpio.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0+ /* - * Copyright (c) 2013 Xilinx, Michal Simek + * Copyright (c) 2013 - 2018 Xilinx, Michal Simek */ #include @@ -9,6 +9,7 @@ #include #include #include +#include static LIST_HEAD(gpio_list); @@ -23,6 +24,8 @@ struct gpio_regs { u32 gpiodir; }; +#if !defined(CONFIG_DM_GPIO) + #define GPIO_NAME_SIZE 10 struct gpio_names { @@ -345,3 +348,263 @@ int gpio_alloc_dual(u32 baseaddr, const char *name, u32 gpio_no0, u32 gpio_no1) /* Return the first gpio allocated for this device */ return ret; } +#else +#include + +#define XILINX_GPIO_MAX_BANK 2 + +struct xilinx_gpio_platdata { + struct gpio_regs *regs; + int bank_max[XILINX_GPIO_MAX_BANK]; + int bank_input[XILINX_GPIO_MAX_BANK]; + int bank_output[XILINX_GPIO_MAX_BANK]; +}; + +static int xilinx_gpio_get_bank_pin(unsigned offset, u32 *bank_num, + u32 *bank_pin_num, struct udevice *dev) +{ + struct xilinx_gpio_platdata *platdata = dev_get_platdata(dev); + u32 bank, max_pins; + /* the first gpio is 0 not 1 */ + u32 pin_num = offset; + + for (bank = 0; bank < XILINX_GPIO_MAX_BANK; bank++) { + max_pins = platdata->bank_max[bank]; + if (pin_num < max_pins) { + debug("%s: found at bank 0x%x pin 0x%x\n", __func__, + bank, pin_num); + *bank_num = bank; + *bank_pin_num = pin_num; + return 0; + } + pin_num -= max_pins; + } + + return -EINVAL; +} + +static int xilinx_gpio_set_value(struct udevice *dev, unsigned offset, + int value) +{ + struct xilinx_gpio_platdata *platdata = dev_get_platdata(dev); + int val, ret; + u32 bank, pin; + + ret = xilinx_gpio_get_bank_pin(offset, &bank, &pin, dev); + if (ret) + return ret; + + debug("%s: regs: %lx, value: %x, gpio: %x, bank %x, pin %x\n", + __func__, (ulong)platdata->regs, value, offset, bank, pin); + + if (value) { + val = readl(&platdata->regs->gpiodata + bank * 2); + val = val | (1 << pin); + writel(val, &platdata->regs->gpiodata + bank * 2); + } else { + val = readl(&platdata->regs->gpiodata + bank * 2); + val = val & ~(1 << pin); + writel(val, &platdata->regs->gpiodata + bank * 2); + } + + return val; +}; + +static int xilinx_gpio_get_value(struct udevice *dev, unsigned offset) +{ + struct xilinx_gpio_platdata *platdata = dev_get_platdata(dev); + int val, ret; + u32 bank, pin; + + ret = xilinx_gpio_get_bank_pin(offset, &bank, &pin, dev); + if (ret) + return ret; + + debug("%s: regs: %lx, gpio: %x, bank %x, pin %x\n", __func__, + (ulong)platdata->regs, offset, bank, pin); + + val = readl(&platdata->regs->gpiodata + bank * 2); + val = !!(val & (1 << pin)); + + return val; +}; + +static int xilinx_gpio_get_function(struct udevice *dev, unsigned offset) +{ + struct xilinx_gpio_platdata *platdata = dev_get_platdata(dev); + int val, ret; + u32 bank, pin; + + /* Check if all pins are inputs */ + if (platdata->bank_input[bank]) + return GPIOF_INPUT; + + /* Check if all pins are outputs */ + if (platdata->bank_output[bank]) + return GPIOF_OUTPUT; + + ret = xilinx_gpio_get_bank_pin(offset, &bank, &pin, dev); + if (ret) + return ret; + + /* FIXME test on dual */ + val = readl(&platdata->regs->gpiodir + bank * 2); + val = !(val & (1 << pin)); + + /* input is 1 in reg but GPIOF_INPUT is 0 */ + /* output is 0 in reg but GPIOF_OUTPUT is 1 */ + + return val; +} + +static int xilinx_gpio_direction_output(struct udevice *dev, unsigned offset, + int value) +{ + struct xilinx_gpio_platdata *platdata = dev_get_platdata(dev); + int val, ret; + u32 bank, pin; + + ret = xilinx_gpio_get_bank_pin(offset, &bank, &pin, dev); + if (ret) + return ret; + + /* can't change it if all is input by default */ + if (platdata->bank_input[bank]) + return -EINVAL; + + if (!platdata->bank_output[bank]) { + val = readl(&platdata->regs->gpiodir + bank * 2); + val = val & ~(1 << pin); + writel(val, &platdata->regs->gpiodir + bank * 2); + } + + xilinx_gpio_set_value(dev, offset, value); + + return 0; +} + +static int xilinx_gpio_direction_input(struct udevice *dev, unsigned offset) +{ + struct xilinx_gpio_platdata *platdata = dev_get_platdata(dev); + int val, ret; + u32 bank, pin; + + ret = xilinx_gpio_get_bank_pin(offset, &bank, &pin, dev); + if (ret) + return ret; + + /* Already input */ + if (platdata->bank_input[bank]) + return 0; + + /* can't change it if all is output by default */ + if (platdata->bank_output[bank]) + return -EINVAL; + + val = readl(&platdata->regs->gpiodir + bank * 2); + val = val | (1 << pin); + writel(val, &platdata->regs->gpiodir + bank * 2); + + return 0; +} + +static int xilinx_gpio_xlate(struct udevice *dev, struct gpio_desc *desc, + struct ofnode_phandle_args *args) +{ + struct xilinx_gpio_platdata *platdata = dev_get_platdata(dev); + + desc->offset = args->args[0]; + + debug("%s: argc: %x, [0]: %x, [1]: %x, [2]: %x\n", __func__, + args->args_count, args->args[0], args->args[1], args->args[2]); + + /* + * The second cell is channel offset: + * 0 is first channel, 8 is second channel + * + * U-Boot driver just combine channels together that's why simply + * add amount of pins in second channel if present. + */ + if (args->args[1]) { + if (!platdata->bank_max[1]) { + printf("%s: %s has no second channel\n", + __func__, dev->name); + return -EINVAL; + } + + desc->offset += platdata->bank_max[0]; + } + + /* The third cell is optional */ + if (args->args_count > 2) + desc->flags = (args->args[2] & + GPIO_ACTIVE_LOW ? GPIOD_ACTIVE_LOW : 0); + + debug("%s: offset %x, flags %lx\n", + __func__, desc->offset, desc->flags); + return 0; +} + +static const struct dm_gpio_ops xilinx_gpio_ops = { + .direction_input = xilinx_gpio_direction_input, + .direction_output = xilinx_gpio_direction_output, + .get_value = xilinx_gpio_get_value, + .set_value = xilinx_gpio_set_value, + .get_function = xilinx_gpio_get_function, + .xlate = xilinx_gpio_xlate, +}; + +static int xilinx_gpio_probe(struct udevice *dev) +{ + struct xilinx_gpio_platdata *platdata = dev_get_platdata(dev); + struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); + + uc_priv->bank_name = dev->name; + + uc_priv->gpio_count = platdata->bank_max[0] + platdata->bank_max[1]; + + return 0; +} + +static int xilinx_gpio_ofdata_to_platdata(struct udevice *dev) +{ + struct xilinx_gpio_platdata *platdata = dev_get_platdata(dev); + int is_dual; + + platdata->regs = (struct gpio_regs *)dev_read_addr(dev); + + platdata->bank_max[0] = dev_read_u32_default(dev, + "xlnx,gpio-width", 0); + platdata->bank_input[0] = dev_read_u32_default(dev, + "xlnx,all-inputs", 0); + platdata->bank_output[0] = dev_read_u32_default(dev, + "xlnx,all-outputs", 0); + + is_dual = dev_read_u32_default(dev, "xlnx,is-dual", 0); + if (is_dual) { + platdata->bank_max[1] = dev_read_u32_default(dev, + "xlnx,gpio2-width", 0); + platdata->bank_input[1] = dev_read_u32_default(dev, + "xlnx,all-inputs-2", 0); + platdata->bank_output[1] = dev_read_u32_default(dev, + "xlnx,all-outputs-2", 0); + } + + return 0; +} + +static const struct udevice_id xilinx_gpio_ids[] = { + { .compatible = "xlnx,xps-gpio-1.00.a",}, + { } +}; + +U_BOOT_DRIVER(xilinx_gpio) = { + .name = "xlnx_gpio", + .id = UCLASS_GPIO, + .ops = &xilinx_gpio_ops, + .of_match = xilinx_gpio_ids, + .ofdata_to_platdata = xilinx_gpio_ofdata_to_platdata, + .probe = xilinx_gpio_probe, + .platdata_auto_alloc_size = sizeof(struct xilinx_gpio_platdata), +}; +#endif From 8c258e6245cb8510359db4e3769098dc53079351 Mon Sep 17 00:00:00 2001 From: Vipul Kumar Date: Wed, 11 Jul 2018 15:18:28 +0530 Subject: [PATCH 30/55] arm64: zynqmp: Changed zynqmp command to handle subcommands with U_BOOT_CMD_MKENT This patch changed zynqmp command to handle subcommands with U_BOOT_CMD_MKENT. Signed-off-by: Vipul Kumar Signed-off-by: Michal Simek --- board/xilinx/zynqmp/cmds.c | 65 +++++++++++++++++++++++++--------------------- 1 file changed, 35 insertions(+), 30 deletions(-) diff --git a/board/xilinx/zynqmp/cmds.c b/board/xilinx/zynqmp/cmds.c index d914653..1f6a5de 100644 --- a/board/xilinx/zynqmp/cmds.c +++ b/board/xilinx/zynqmp/cmds.c @@ -9,24 +9,37 @@ #include #include -static int zynqmp_verify_secure(u8 *key_ptr, u8 *src_ptr, u32 len) +static int do_zynqmp_verify_secure(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]) { + u64 src_addr, addr; + u32 len, src_lo, src_hi; + u8 *key_ptr = NULL; int ret; - u32 src_lo, src_hi; u32 key_lo = 0; u32 key_hi = 0; u32 ret_payload[PAYLOAD_ARG_CNT]; - u64 addr; - if ((ulong)src_ptr != ALIGN((ulong)src_ptr, - CONFIG_SYS_CACHELINE_SIZE)) { - printf("Failed: source address not aligned:%p\n", src_ptr); + if (argc < 4) + return CMD_RET_USAGE; + + src_addr = simple_strtoull(argv[2], NULL, 16); + len = simple_strtoul(argv[3], NULL, 16); + + if (argc == 5) + key_ptr = (uint8_t *)(uintptr_t)simple_strtoull(argv[4], + NULL, 16); + + if ((ulong)src_addr != ALIGN((ulong)src_addr, + CONFIG_SYS_CACHELINE_SIZE)) { + printf("Failed: source address not aligned:%lx\n", + (ulong)src_addr); return -EINVAL; } - src_lo = lower_32_bits((ulong)src_ptr); - src_hi = upper_32_bits((ulong)src_ptr); - flush_dcache_range((ulong)src_ptr, (ulong)(src_ptr + len)); + src_lo = lower_32_bits((ulong)src_addr); + src_hi = upper_32_bits((ulong)src_addr); + flush_dcache_range((ulong)src_addr, (ulong)(src_addr + len)); if (key_ptr) { key_lo = lower_32_bits((ulong)key_ptr); @@ -48,6 +61,10 @@ static int zynqmp_verify_secure(u8 *key_ptr, u8 *src_ptr, u32 len) return ret; } +static cmd_tbl_t cmd_zynqmp_sub[] = { + U_BOOT_CMD_MKENT(secure, 5, 0, do_zynqmp_verify_secure, "", ""), +}; + /** * do_zynqmp - Handle the "zynqmp" command-line command * @cmdtp: Command data struct pointer @@ -62,30 +79,18 @@ static int zynqmp_verify_secure(u8 *key_ptr, u8 *src_ptr, u32 len) static int do_zynqmp(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) { - u64 src_addr; - u32 len; - u8 *key_ptr = NULL; - u8 *src_ptr; - int ret; + cmd_tbl_t *c; - if (argc > 5 || argc < 4 || strncmp(argv[1], "secure", 6)) + if (argc < 2) return CMD_RET_USAGE; - src_addr = simple_strtoull(argv[2], NULL, 16); - - len = simple_strtoul(argv[3], NULL, 16); - - if (argc > 4) - key_ptr = (uint8_t *)(uintptr_t)simple_strtoull(argv[4], - NULL, 16); - - src_ptr = (uint8_t *)(uintptr_t)src_addr; + c = find_cmd_tbl(argv[1], &cmd_zynqmp_sub[0], + ARRAY_SIZE(cmd_zynqmp_sub)); - ret = zynqmp_verify_secure(key_ptr, src_ptr, len); - if (ret) - return CMD_RET_FAILURE; - - return CMD_RET_SUCCESS; + if (c) + return c->cmd(c, flag, argc, argv); + else + return CMD_RET_USAGE; } /***************************************************/ @@ -99,6 +104,6 @@ static char zynqmp_help_text[] = U_BOOT_CMD( zynqmp, 5, 1, do_zynqmp, - "Verify and load secure images", + "ZynqMP sub-system", zynqmp_help_text ) From 35912528a86ad15dd6931d03ec4ac275e24581a2 Mon Sep 17 00:00:00 2001 From: Shreenidhi Shedi Date: Sun, 15 Jul 2018 02:34:35 +0530 Subject: [PATCH 31/55] microblaze: Cosmetic changes in Microblaze related files Signed-off-by: Shreenidhi Shedi Signed-off-by: Michal Simek --- arch/microblaze/include/asm/io.h | 94 +++++++++++++--------- .../xilinx/microblaze-generic/microblaze-generic.c | 8 +- include/configs/microblaze-generic.h | 2 +- 3 files changed, 60 insertions(+), 44 deletions(-) diff --git a/arch/microblaze/include/asm/io.h b/arch/microblaze/include/asm/io.h index 26a437c..8e6be0a 100644 --- a/arch/microblaze/include/asm/io.h +++ b/arch/microblaze/include/asm/io.h @@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * include/asm-microblaze/io.h -- Misc I/O operations * @@ -21,39 +22,42 @@ #define IO_SPACE_LIMIT 0xFFFFFFFF #define readb(addr) \ - ({ unsigned char __v = (*(volatile unsigned char *) (addr)); __v; }) + ({ unsigned char __v = (*(volatile unsigned char *)(addr)); __v; }) + #define readw(addr) \ - ({ unsigned short __v = (*(volatile unsigned short *) (addr)); __v; }) + ({ unsigned short __v = (*(volatile unsigned short *)(addr)); __v; }) + #define readl(addr) \ - ({ unsigned int __v = (*(volatile unsigned int *) (addr)); __v; }) + ({ unsigned int __v = (*(volatile unsigned int *)(addr)); __v; }) #define writeb(b, addr) \ - (void)((*(volatile unsigned char *) (addr)) = (b)) + (void)((*(volatile unsigned char *)(addr)) = (b)) + #define writew(b, addr) \ - (void)((*(volatile unsigned short *) (addr)) = (b)) + (void)((*(volatile unsigned short *)(addr)) = (b)) + #define writel(b, addr) \ - (void)((*(volatile unsigned int *) (addr)) = (b)) + (void)((*(volatile unsigned int *)(addr)) = (b)) -#define memset_io(a,b,c) memset((void *)(a),(b),(c)) -#define memcpy_fromio(a,b,c) memcpy((a),(void *)(b),(c)) -#define memcpy_toio(a,b,c) memcpy((void *)(a),(b),(c)) +#define memset_io(a, b, c) memset((void *)(a), (b), (c)) +#define memcpy_fromio(a, b, c) memcpy((a), (void *)(b), (c)) +#define memcpy_toio(a, b, c) memcpy((void *)(a), (b), (c)) -#define inb(addr) readb (addr) -#define inw(addr) readw (addr) -#define inl(addr) readl (addr) -#define outb(x, addr) ((void) writeb (x, addr)) -#define outw(x, addr) ((void) writew (x, addr)) -#define outl(x, addr) ((void) writel (x, addr)) +#define inb(addr) readb(addr) +#define inw(addr) readw(addr) +#define inl(addr) readl(addr) +#define outb(x, addr) ((void)writeb(x, addr)) +#define outw(x, addr) ((void)writew(x, addr)) +#define outl(x, addr) ((void)writel(x, addr)) /* Some #definitions to keep strange Xilinx code happy */ -#define in_8(addr) readb (addr) -#define in_be16(addr) readw (addr) -#define in_be32(addr) readl (addr) - -#define out_8(addr,x ) outb (x,addr) -#define out_be16(addr,x ) outw (x,addr) -#define out_be32(addr,x ) outl (x,addr) +#define in_8(addr) readb(addr) +#define in_be16(addr) readw(addr) +#define in_be32(addr) readl(addr) +#define out_8(addr, x) outb(x, addr) +#define out_be16(addr, x) outw(x, addr) +#define out_be32(addr, x) outl(x, addr) #define inb_p(port) inb((port)) #define outb_p(val, port) outb((val), (port)) @@ -71,54 +75,64 @@ #define __raw_writew writew #define __raw_writel writel -static inline void io_insb (unsigned long port, void *dst, unsigned long count) +static inline void io_insb(unsigned long port, void *dst, unsigned long count) { unsigned char *p = dst; + while (count--) - *p++ = inb (port); + *p++ = inb(port); } -static inline void io_insw (unsigned long port, void *dst, unsigned long count) + +static inline void io_insw(unsigned long port, void *dst, unsigned long count) { unsigned short *p = dst; + while (count--) - *p++ = inw (port); + *p++ = inw(port); } -static inline void io_insl (unsigned long port, void *dst, unsigned long count) + +static inline void io_insl(unsigned long port, void *dst, unsigned long count) { unsigned long *p = dst; + while (count--) - *p++ = inl (port); + *p++ = inl(port); } static inline void -io_outsb (unsigned long port, const void *src, unsigned long count) +io_outsb(unsigned long port, const void *src, unsigned long count) { const unsigned char *p = src; + while (count--) - outb (*p++, port); + outb(*p++, port); } + static inline void -io_outsw (unsigned long port, const void *src, unsigned long count) +io_outsw(unsigned long port, const void *src, unsigned long count) { const unsigned short *p = src; + while (count--) - outw (*p++, port); + outw(*p++, port); } + static inline void -io_outsl (unsigned long port, const void *src, unsigned long count) +io_outsl(unsigned long port, const void *src, unsigned long count) { const unsigned long *p = src; + while (count--) - outl (*p++, port); + outl(*p++, port); } -#define outsb(a,b,l) io_outsb(a,b,l) -#define outsw(a,b,l) io_outsw(a,b,l) -#define outsl(a,b,l) io_outsl(a,b,l) +#define outsb(a, b, l) io_outsb(a, b, l) +#define outsw(a, b, l) io_outsw(a, b, l) +#define outsl(a, b, l) io_outsl(a, b, l) -#define insb(a,b,l) io_insb(a,b,l) -#define insw(a,b,l) io_insw(a,b,l) -#define insl(a,b,l) io_insl(a,b,l) +#define insb(a, b, l) io_insb(a, b, l) +#define insw(a, b, l) io_insw(a, b, l) +#define insl(a, b, l) io_insl(a, b, l) #define ioremap_nocache(physaddr, size) (physaddr) #define ioremap_writethrough(physaddr, size) (physaddr) diff --git a/board/xilinx/microblaze-generic/microblaze-generic.c b/board/xilinx/microblaze-generic/microblaze-generic.c index 889695f..9be2cce 100644 --- a/board/xilinx/microblaze-generic/microblaze-generic.c +++ b/board/xilinx/microblaze-generic/microblaze-generic.c @@ -5,8 +5,10 @@ * Michal SIMEK */ -/* This is a board specific file. It's OK to include board specific - * header files */ +/* + * This is a board specific file. It's OK to include board specific + * header files + */ #include #include @@ -71,7 +73,7 @@ int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) hw_watchdog_disable(); #endif #endif - puts ("Reseting board\n"); + puts("Resetting board\n"); __asm__ __volatile__ (" mts rmsr, r0;" \ "bra r0"); diff --git a/include/configs/microblaze-generic.h b/include/configs/microblaze-generic.h index 966feee..7f16700 100644 --- a/include/configs/microblaze-generic.h +++ b/include/configs/microblaze-generic.h @@ -217,7 +217,7 @@ #define CONFIG_SYS_FDT_BASE (CONFIG_SYS_FLASH_BASE + \ 0x40000) -#define CONFIG_SYS_FDT_SIZE (16<<10) +#define CONFIG_SYS_FDT_SIZE (16 << 10) #define CONFIG_SYS_SPL_ARGS_ADDR (CONFIG_SYS_TEXT_BASE + \ 0x1000000) From 88811bb5a11b1d29196694fdcfa26a4e6ebd87d4 Mon Sep 17 00:00:00 2001 From: Shreenidhi Shedi Date: Sun, 15 Jul 2018 02:05:39 +0530 Subject: [PATCH 32/55] microblaze: Delete Xilinx watchdog related macros These macros are not required anymore. These will be taken from configuration file. Signed-off-by: Shreenidhi Shedi Signed-off-by: Michal Simek --- board/xilinx/microblaze-generic/xparameters.h | 4 ---- include/configs/microblaze-generic.h | 10 ---------- 2 files changed, 14 deletions(-) diff --git a/board/xilinx/microblaze-generic/xparameters.h b/board/xilinx/microblaze-generic/xparameters.h index 57998ed..01116d8 100644 --- a/board/xilinx/microblaze-generic/xparameters.h +++ b/board/xilinx/microblaze-generic/xparameters.h @@ -19,7 +19,3 @@ /* Flash Memory is FLASH_2Mx32 */ #define XILINX_FLASH_START 0x2c000000 #define XILINX_FLASH_SIZE 0x00800000 - -/* Watchdog IP is wxi_timebase_wdt_0 */ -#define XILINX_WATCHDOG_BASEADDR 0x50000000 -#define XILINX_WATCHDOG_IRQ 1 diff --git a/include/configs/microblaze-generic.h b/include/configs/microblaze-generic.h index 7f16700..6a049cf 100644 --- a/include/configs/microblaze-generic.h +++ b/include/configs/microblaze-generic.h @@ -43,16 +43,6 @@ # define CONFIG_SYS_GPIO_0_ADDR XILINX_GPIO_BASEADDR #endif -/* watchdog */ -#if defined(XILINX_WATCHDOG_BASEADDR) && defined(XILINX_WATCHDOG_IRQ) -# define CONFIG_WATCHDOG_BASEADDR XILINX_WATCHDOG_BASEADDR -# define CONFIG_WATCHDOG_IRQ XILINX_WATCHDOG_IRQ -# ifndef CONFIG_SPL_BUILD -# define CONFIG_HW_WATCHDOG -# define CONFIG_XILINX_TB_WATCHDOG -# endif -#endif - #define CONFIG_SYS_MALLOC_LEN 0xC0000 /* Stack location before relocation */ From 6ec6f5841d7ee9f4f398f5c617a50a14f2f446ef Mon Sep 17 00:00:00 2001 From: Shreenidhi Shedi Date: Sun, 15 Jul 2018 02:05:40 +0530 Subject: [PATCH 33/55] microblaze: Support for watchdog_reset in init We should support watchdog reset so that WATCHDOG_RESET will function properly. Signed-off-by: Shreenidhi Shedi Signed-off-by: Michal Simek --- .../xilinx/microblaze-generic/microblaze-generic.c | 47 ++++++++++++++++++++-- 1 file changed, 43 insertions(+), 4 deletions(-) diff --git a/board/xilinx/microblaze-generic/microblaze-generic.c b/board/xilinx/microblaze-generic/microblaze-generic.c index 9be2cce..556d0de 100644 --- a/board/xilinx/microblaze-generic/microblaze-generic.c +++ b/board/xilinx/microblaze-generic/microblaze-generic.c @@ -17,6 +17,8 @@ #include #include #include +#include +#include DECLARE_GLOBAL_DATA_PTR; @@ -24,6 +26,10 @@ DECLARE_GLOBAL_DATA_PTR; static int reset_pin = -1; #endif +#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_WDT) +static struct udevice *watchdog_dev; +#endif /* !CONFIG_SPL_BUILD && CONFIG_WDT */ + ulong ram_base; int dram_init_banksize(void) @@ -68,10 +74,6 @@ int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) if (reset_pin != -1) gpio_direction_output(reset_pin, 1); #endif - -#ifdef CONFIG_XILINX_TB_WATCHDOG - hw_watchdog_disable(); -#endif #endif puts("Resetting board\n"); __asm__ __volatile__ (" mts rmsr, r0;" \ @@ -91,9 +93,46 @@ static int gpio_init(void) return 0; } +#ifdef CONFIG_WDT +/* Called by macro WATCHDOG_RESET */ +void watchdog_reset(void) +{ +#if !defined(CONFIG_SPL_BUILD) + ulong now; + static ulong next_reset; + + if (!watchdog_dev) + return; + + now = timer_get_us(); + + /* Do not reset the watchdog too often */ + if (now > next_reset) { + wdt_reset(watchdog_dev); + next_reset = now + 1000; + } +#endif /* !CONFIG_SPL_BUILD */ +} +#endif /* CONFIG_WDT */ + int board_late_init(void) { gpio_init(); +#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_WDT) + watchdog_dev = NULL; + + if (uclass_get_device_by_seq(UCLASS_WDT, 0, &watchdog_dev)) { + debug("Watchdog: Not found by seq!\n"); + if (uclass_get_device(UCLASS_WDT, 0, &watchdog_dev)) { + puts("Watchdog: Not found!\n"); + return 0; + } + } + + wdt_start(watchdog_dev, 0, 0); + puts("Watchdog: Started\n"); +#endif /* !CONFIG_SPL_BUILD && CONFIG_WDT */ + return 0; } From e0e9caae6b660d1d79eed449177d8312112ae3b0 Mon Sep 17 00:00:00 2001 From: Shreenidhi Shedi Date: Sun, 15 Jul 2018 02:05:41 +0530 Subject: [PATCH 34/55] watchdog: Convert Xilinx Axi watchdog driver to driver model Xilinx Axi wdt driver conversion to driver model & Kconfig update for the same. Signed-off-by: Shreenidhi Shedi Signed-off-by: Michal Simek --- drivers/watchdog/Kconfig | 8 +++ drivers/watchdog/xilinx_tb_wdt.c | 111 ++++++++++++++++++++++++++++++--------- 2 files changed, 93 insertions(+), 26 deletions(-) diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 148c6a0..d545b3e 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -103,4 +103,12 @@ config WDT_CDNS Select this to enable Cadence watchdog timer, which can be found on some Xilinx Microzed Platform. +config XILINX_TB_WATCHDOG + bool "Xilinx Axi watchdog timer support" + depends on WDT + imply WATCHDOG + help + Select this to enable Xilinx Axi watchdog timer, which can be found on some + Xilinx Microblaze Platforms. + endmenu diff --git a/drivers/watchdog/xilinx_tb_wdt.c b/drivers/watchdog/xilinx_tb_wdt.c index 2274123..929c8e6 100644 --- a/drivers/watchdog/xilinx_tb_wdt.c +++ b/drivers/watchdog/xilinx_tb_wdt.c @@ -1,13 +1,17 @@ // SPDX-License-Identifier: GPL-2.0+ /* - * Copyright (c) 2011-2013 Xilinx Inc. + * Xilinx AXI platforms watchdog timer driver. + * + * Author(s): Michal Simek + * Shreenidhi Shedi + * + * Copyright (c) 2011-2018 Xilinx Inc. */ #include -#include -#include -#include -#include +#include +#include +#include #define XWT_CSR0_WRS_MASK 0x00000008 /* Reset status Mask */ #define XWT_CSR0_WDS_MASK 0x00000004 /* Timer state Mask */ @@ -20,49 +24,104 @@ struct watchdog_regs { u32 tbr; /* 0x8 */ }; -static struct watchdog_regs *watchdog_base = - (struct watchdog_regs *)CONFIG_WATCHDOG_BASEADDR; +struct xlnx_wdt_platdata { + bool enable_once; + struct watchdog_regs *regs; +}; -void hw_watchdog_reset(void) +static int xlnx_wdt_reset(struct udevice *dev) { u32 reg; + struct xlnx_wdt_platdata *platdata = dev_get_platdata(dev); + + debug("%s ", __func__); /* Read the current contents of TCSR0 */ - reg = readl(&watchdog_base->twcsr0); + reg = readl(&platdata->regs->twcsr0); /* Clear the watchdog WDS bit */ if (reg & (XWT_CSR0_EWDT1_MASK | XWT_CSRX_EWDT2_MASK)) - writel(reg | XWT_CSR0_WDS_MASK, &watchdog_base->twcsr0); + writel(reg | XWT_CSR0_WDS_MASK, &platdata->regs->twcsr0); + + return 0; } -void hw_watchdog_disable(void) +static int xlnx_wdt_stop(struct udevice *dev) { u32 reg; + struct xlnx_wdt_platdata *platdata = dev_get_platdata(dev); + + if (platdata->enable_once) { + debug("Can't stop Xilinx watchdog.\n"); + return -EBUSY; + } /* Read the current contents of TCSR0 */ - reg = readl(&watchdog_base->twcsr0); + reg = readl(&platdata->regs->twcsr0); + + writel(reg & ~XWT_CSR0_EWDT1_MASK, &platdata->regs->twcsr0); + writel(~XWT_CSRX_EWDT2_MASK, &platdata->regs->twcsr1); - writel(reg & ~XWT_CSR0_EWDT1_MASK, &watchdog_base->twcsr0); - writel(~XWT_CSRX_EWDT2_MASK, &watchdog_base->twcsr1); + debug("Watchdog disabled!\n"); - puts("Watchdog disabled!\n"); + return 0; } -static void hw_watchdog_isr(void *arg) +static int xlnx_wdt_start(struct udevice *dev, u64 timeout, ulong flags) { - hw_watchdog_reset(); + struct xlnx_wdt_platdata *platdata = dev_get_platdata(dev); + + debug("%s:\n", __func__); + + writel((XWT_CSR0_WRS_MASK | XWT_CSR0_WDS_MASK | XWT_CSR0_EWDT1_MASK), + &platdata->regs->twcsr0); + + writel(XWT_CSRX_EWDT2_MASK, &platdata->regs->twcsr1); + + return 0; } -void hw_watchdog_init(void) +static int xlnx_wdt_probe(struct udevice *dev) { - int ret; + debug("%s: Probing wdt%u\n", __func__, dev->seq); - writel((XWT_CSR0_WRS_MASK | XWT_CSR0_WDS_MASK | XWT_CSR0_EWDT1_MASK), - &watchdog_base->twcsr0); - writel(XWT_CSRX_EWDT2_MASK, &watchdog_base->twcsr1); + return 0; +} - ret = install_interrupt_handler(CONFIG_WATCHDOG_IRQ, - hw_watchdog_isr, NULL); - if (ret) - puts("Watchdog IRQ registration failed."); +static int xlnx_wdt_ofdata_to_platdata(struct udevice *dev) +{ + struct xlnx_wdt_platdata *platdata = dev_get_platdata(dev); + + platdata->regs = (struct watchdog_regs *)dev_read_addr(dev); + if (IS_ERR(platdata->regs)) + return PTR_ERR(platdata->regs); + + platdata->enable_once = dev_read_u32_default(dev, + "xlnx,wdt-enable-once", 0); + + debug("%s: wdt-enable-once %d\n", __func__, platdata->enable_once); + + return 0; } + +static const struct wdt_ops xlnx_wdt_ops = { + .start = xlnx_wdt_start, + .reset = xlnx_wdt_reset, + .stop = xlnx_wdt_stop, +}; + +static const struct udevice_id xlnx_wdt_ids[] = { + { .compatible = "xlnx,xps-timebase-wdt-1.00.a", }, + { .compatible = "xlnx,xps-timebase-wdt-1.01.a", }, + {}, +}; + +U_BOOT_DRIVER(xlnx_wdt) = { + .name = "xlnx_wdt", + .id = UCLASS_WDT, + .of_match = xlnx_wdt_ids, + .probe = xlnx_wdt_probe, + .platdata_auto_alloc_size = sizeof(struct xlnx_wdt_platdata), + .ofdata_to_platdata = xlnx_wdt_ofdata_to_platdata, + .ops = &xlnx_wdt_ops, +}; From 704849900a657a0a03bfe2f129c1544e954a618d Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Mon, 16 Jul 2018 13:03:21 +0200 Subject: [PATCH 35/55] microblaze: Enable watchdog via defconfig DM watchdog should be enabled by default. Signed-off-by: Michal Simek --- configs/microblaze-generic_defconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/configs/microblaze-generic_defconfig b/configs/microblaze-generic_defconfig index 6ba7022..c366a80 100644 --- a/configs/microblaze-generic_defconfig +++ b/configs/microblaze-generic_defconfig @@ -56,3 +56,5 @@ CONFIG_XILINX_AXIEMAC=y CONFIG_XILINX_EMACLITE=y CONFIG_SYS_NS16550=y CONFIG_XILINX_UARTLITE=y +CONFIG_WDT=y +CONFIG_XILINX_TB_WATCHDOG=y From c7e794892489316c035e6a0c9e3753306f79d4c0 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Thu, 31 May 2018 09:50:10 +0200 Subject: [PATCH 36/55] arm64: xilinx: Setup default number of chipselects for zcu100 There is only one chipselect on each connector. Define it directly in board dts file. There should be an option to use more chipselects via gpios. Signed-off-by: Michal Simek --- arch/arm/dts/zynqmp-zcu100-revC.dts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/dts/zynqmp-zcu100-revC.dts b/arch/arm/dts/zynqmp-zcu100-revC.dts index 6e575a0..2fffe17 100644 --- a/arch/arm/dts/zynqmp-zcu100-revC.dts +++ b/arch/arm/dts/zynqmp-zcu100-revC.dts @@ -280,11 +280,13 @@ &spi0 { /* Low Speed connector */ status = "okay"; label = "LS-SPI0"; + num-cs = <1>; }; &spi1 { /* High Speed connector */ status = "okay"; label = "HS-SPI1"; + num-cs = <1>; }; &uart0 { From 4a693669670fffd9a614c8c5c9f5ba027fd0185e Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Fri, 13 Jul 2018 08:26:28 +0200 Subject: [PATCH 37/55] microblaze: Convert generic platform to DM gpio Converting GPIO to DM requires to do changes in reset subsystem that's why support for Microblaze soft reset via sysreset and GPIO sysreset support was added. These two patches enables enabling GPIO DM. Microblaze soft reset is bind at last reset method. GPIO reset is handled via sysreset with adding this fragment to DT. gpio-restart { compatible = "gpio-restart"; gpios = <&reset_gpio 0 0 0>; /* 3rd cell ACTIVE_HIGH = 0, ACTIVE_LOW = 1 */ }; hard-reset-gpio property is not documented and also handled. Conversion is required. Unfortunately do_reset is required for SPL that's why use only soft microblaze reset for now. Signed-off-by: Michal Simek --- arch/microblaze/Kconfig | 1 + arch/microblaze/cpu/spl.c | 8 ++++ arch/microblaze/include/asm/gpio.h | 13 ------ .../xilinx/microblaze-generic/microblaze-generic.c | 46 ++++++---------------- board/xilinx/microblaze-generic/xparameters.h | 3 -- configs/microblaze-generic_defconfig | 3 ++ drivers/gpio/Kconfig | 1 + include/configs/microblaze-generic.h | 5 --- 8 files changed, 24 insertions(+), 56 deletions(-) diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig index f791c00..dcc502b 100644 --- a/arch/microblaze/Kconfig +++ b/arch/microblaze/Kconfig @@ -16,6 +16,7 @@ config TARGET_MICROBLAZE_GENERIC select DM select DM_SERIAL select ENV_IS_IN_FLASH + select SYSRESET endchoice diff --git a/arch/microblaze/cpu/spl.c b/arch/microblaze/cpu/spl.c index d3c523d..070c12c 100644 --- a/arch/microblaze/cpu/spl.c +++ b/arch/microblaze/cpu/spl.c @@ -47,3 +47,11 @@ int spl_start_uboot(void) return 1; } + +int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + __asm__ __volatile__ ("mts rmsr, r0;" \ + "bra r0"); + + return 0; +} diff --git a/arch/microblaze/include/asm/gpio.h b/arch/microblaze/include/asm/gpio.h index 4762de0..306ab4c 100644 --- a/arch/microblaze/include/asm/gpio.h +++ b/arch/microblaze/include/asm/gpio.h @@ -1,14 +1 @@ -#ifndef _ASM_MICROBLAZE_GPIO_H_ -#define _ASM_MICROBLAZE_GPIO_H_ - #include - -/* Allocation functions */ -extern int gpio_alloc_dual(u32 baseaddr, const char *name, u32 gpio_no0, - u32 gpio_no1); -extern int gpio_alloc(u32 baseaddr, const char *name, u32 gpio_no); - -#define gpio_status() gpio_info() -extern void gpio_info(void); - -#endif diff --git a/board/xilinx/microblaze-generic/microblaze-generic.c b/board/xilinx/microblaze-generic/microblaze-generic.c index 556d0de..44fb48b 100644 --- a/board/xilinx/microblaze-generic/microblaze-generic.c +++ b/board/xilinx/microblaze-generic/microblaze-generic.c @@ -1,8 +1,8 @@ // SPDX-License-Identifier: GPL-2.0+ /* - * (C) Copyright 2007 Michal Simek + * (C) Copyright 2007-2018 Michal Simek * - * Michal SIMEK + * Michal SIMEK */ /* @@ -12,6 +12,8 @@ #include #include +#include +#include #include #include #include @@ -22,10 +24,6 @@ DECLARE_GLOBAL_DATA_PTR; -#ifdef CONFIG_XILINX_GPIO -static int reset_pin = -1; -#endif - #if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_WDT) static struct udevice *watchdog_dev; #endif /* !CONFIG_SPL_BUILD && CONFIG_WDT */ @@ -66,33 +64,6 @@ int dram_init(void) return 0; }; -#if !defined(CONFIG_SYSRESET) || defined(CONFIG_SPL_BUILD) -int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) -{ -#ifndef CONFIG_SPL_BUILD -#ifdef CONFIG_XILINX_GPIO - if (reset_pin != -1) - gpio_direction_output(reset_pin, 1); -#endif -#endif - puts("Resetting board\n"); - __asm__ __volatile__ (" mts rmsr, r0;" \ - "bra r0"); - - return 0; -} -#endif - -static int gpio_init(void) -{ -#ifdef CONFIG_XILINX_GPIO - reset_pin = gpio_alloc(CONFIG_SYS_GPIO_0_ADDR, "reset", 1); - if (reset_pin != -1) - gpio_request(reset_pin, "reset_pin"); -#endif - return 0; -} - #ifdef CONFIG_WDT /* Called by macro WATCHDOG_RESET */ void watchdog_reset(void) @@ -117,8 +88,6 @@ void watchdog_reset(void) int board_late_init(void) { - gpio_init(); - #if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_WDT) watchdog_dev = NULL; @@ -133,6 +102,13 @@ int board_late_init(void) wdt_start(watchdog_dev, 0, 0); puts("Watchdog: Started\n"); #endif /* !CONFIG_SPL_BUILD && CONFIG_WDT */ +#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_SYSRESET_MICROBLAZE) + int ret; + ret = device_bind_driver(gd->dm_root, "mb_soft_reset", + "reset_soft", NULL); + if (ret) + printf("Warning: No reset driver: ret=%d\n", ret); +#endif return 0; } diff --git a/board/xilinx/microblaze-generic/xparameters.h b/board/xilinx/microblaze-generic/xparameters.h index 01116d8..5e0911f 100644 --- a/board/xilinx/microblaze-generic/xparameters.h +++ b/board/xilinx/microblaze-generic/xparameters.h @@ -13,9 +13,6 @@ /* Microblaze is microblaze_0 */ #define XILINX_FSL_NUMBER 3 -/* GPIO is LEDs_4Bit*/ -#define XILINX_GPIO_BASEADDR 0x40000000 - /* Flash Memory is FLASH_2Mx32 */ #define XILINX_FLASH_START 0x2c000000 #define XILINX_FLASH_SIZE 0x00800000 diff --git a/configs/microblaze-generic_defconfig b/configs/microblaze-generic_defconfig index c366a80..b1d0193 100644 --- a/configs/microblaze-generic_defconfig +++ b/configs/microblaze-generic_defconfig @@ -39,6 +39,7 @@ CONFIG_SPL_OF_CONTROL=y CONFIG_OF_EMBED=y CONFIG_NETCONSOLE=y CONFIG_SPL_DM=y +CONFIG_DM_GPIO=y CONFIG_XILINX_GPIO=y CONFIG_MTD_NOR_FLASH=y CONFIG_PHY_ATHEROS=y @@ -56,5 +57,7 @@ CONFIG_XILINX_AXIEMAC=y CONFIG_XILINX_EMACLITE=y CONFIG_SYS_NS16550=y CONFIG_XILINX_UARTLITE=y +CONFIG_SYSRESET_GPIO=y +CONFIG_SYSRESET_MICROBLAZE=y CONFIG_WDT=y CONFIG_XILINX_TB_WATCHDOG=y diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 29af22e..5699a71 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -185,6 +185,7 @@ config SANDBOX_GPIO_COUNT config XILINX_GPIO bool "Xilinx GPIO driver" + depends on DM_GPIO help This config enable the Xilinx GPIO driver for Microblaze. diff --git a/include/configs/microblaze-generic.h b/include/configs/microblaze-generic.h index 6a049cf..5eab2e5 100644 --- a/include/configs/microblaze-generic.h +++ b/include/configs/microblaze-generic.h @@ -38,11 +38,6 @@ /* setting reset address */ /*#define CONFIG_SYS_RESET_ADDRESS CONFIG_SYS_TEXT_BASE*/ -/* gpio */ -#ifdef XILINX_GPIO_BASEADDR -# define CONFIG_SYS_GPIO_0_ADDR XILINX_GPIO_BASEADDR -#endif - #define CONFIG_SYS_MALLOC_LEN 0xC0000 /* Stack location before relocation */ From 28a961aa0b5c5446ae20913e26fa0db765a32f96 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Mon, 16 Jul 2018 13:37:28 +0200 Subject: [PATCH 38/55] microblaze: Do not force saving variables to flash There is no reason to save variables to flash only. Select option via Kconfig instead. Signed-off-by: Michal Simek --- arch/microblaze/Kconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig index dcc502b..c564593 100644 --- a/arch/microblaze/Kconfig +++ b/arch/microblaze/Kconfig @@ -15,7 +15,6 @@ config TARGET_MICROBLAZE_GENERIC select OF_CONTROL select DM select DM_SERIAL - select ENV_IS_IN_FLASH select SYSRESET endchoice From 6c253be7ce19bec6dba386fc55f4986de65281d0 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Mon, 16 Jul 2018 13:34:55 +0200 Subject: [PATCH 39/55] watchdog: cdns: Add comment for expire_now function IP itself has no reg/no bit which can be used for this functionality. Add this note to the driver to make sure that none will be asking for that. Current method is to setup 1s timeout and hang() which is done via wdt_expire_now(). Signed-off-by: Michal Simek --- drivers/watchdog/cdns_wdt.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/watchdog/cdns_wdt.c b/drivers/watchdog/cdns_wdt.c index f7618f8..71575cb 100644 --- a/drivers/watchdog/cdns_wdt.c +++ b/drivers/watchdog/cdns_wdt.c @@ -251,6 +251,7 @@ static const struct wdt_ops cdns_wdt_ops = { .start = cdns_wdt_start, .reset = cdns_wdt_reset, .stop = cdns_wdt_stop, + /* There is no bit/reg/support in IP for expire_now functionality */ }; static const struct udevice_id cdns_wdt_ids[] = { From f5ed3605851abe428e36ceb775bf9a704fc5fe01 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Mon, 16 Jul 2018 14:12:43 +0200 Subject: [PATCH 40/55] xilinx: Enable led support for some boards Enable led support for boards which have "gpio-leds" node. And also for microblaze which is converted to DM_GPIO now. Tested on zcu100. Signed-off-by: Michal Simek --- configs/microblaze-generic_defconfig | 2 ++ configs/xilinx_zynqmp_zcu100_revC_defconfig | 2 ++ configs/xilinx_zynqmp_zcu102_rev1_0_defconfig | 2 ++ configs/xilinx_zynqmp_zcu102_revA_defconfig | 2 ++ configs/xilinx_zynqmp_zcu102_revB_defconfig | 2 ++ configs/xilinx_zynqmp_zcu106_revA_defconfig | 2 ++ configs/xilinx_zynqmp_zcu111_revA_defconfig | 2 ++ configs/zynq_z_turn_defconfig | 2 ++ configs/zynq_zc702_defconfig | 2 ++ 9 files changed, 18 insertions(+) diff --git a/configs/microblaze-generic_defconfig b/configs/microblaze-generic_defconfig index b1d0193..4917d47 100644 --- a/configs/microblaze-generic_defconfig +++ b/configs/microblaze-generic_defconfig @@ -41,6 +41,8 @@ CONFIG_NETCONSOLE=y CONFIG_SPL_DM=y CONFIG_DM_GPIO=y CONFIG_XILINX_GPIO=y +CONFIG_LED=y +CONFIG_LED_GPIO=y CONFIG_MTD_NOR_FLASH=y CONFIG_PHY_ATHEROS=y CONFIG_PHY_BROADCOM=y diff --git a/configs/xilinx_zynqmp_zcu100_revC_defconfig b/configs/xilinx_zynqmp_zcu100_revC_defconfig index 802f4e7..2e9a110 100644 --- a/configs/xilinx_zynqmp_zcu100_revC_defconfig +++ b/configs/xilinx_zynqmp_zcu100_revC_defconfig @@ -51,6 +51,8 @@ CONFIG_FPGA_ZYNQMPPL=y CONFIG_DM_GPIO=y CONFIG_SYS_I2C_ZYNQ=y CONFIG_ZYNQ_I2C1=y +CONFIG_LED=y +CONFIG_LED_GPIO=y CONFIG_MISC=y CONFIG_DM_MMC=y CONFIG_MMC_SDHCI=y diff --git a/configs/xilinx_zynqmp_zcu102_rev1_0_defconfig b/configs/xilinx_zynqmp_zcu102_rev1_0_defconfig index 5dea5ce..1dfbf71 100644 --- a/configs/xilinx_zynqmp_zcu102_rev1_0_defconfig +++ b/configs/xilinx_zynqmp_zcu102_rev1_0_defconfig @@ -64,6 +64,8 @@ CONFIG_CMD_PCA953X=y CONFIG_SYS_I2C_ZYNQ=y CONFIG_ZYNQ_I2C0=y CONFIG_ZYNQ_I2C1=y +CONFIG_LED=y +CONFIG_LED_GPIO=y CONFIG_MISC=y CONFIG_ZYNQ_GEM_I2C_MAC_OFFSET=0x20 CONFIG_DM_MMC=y diff --git a/configs/xilinx_zynqmp_zcu102_revA_defconfig b/configs/xilinx_zynqmp_zcu102_revA_defconfig index 49a9a4f..09ae9e8 100644 --- a/configs/xilinx_zynqmp_zcu102_revA_defconfig +++ b/configs/xilinx_zynqmp_zcu102_revA_defconfig @@ -63,6 +63,8 @@ CONFIG_CMD_PCA953X=y CONFIG_SYS_I2C_ZYNQ=y CONFIG_ZYNQ_I2C0=y CONFIG_ZYNQ_I2C1=y +CONFIG_LED=y +CONFIG_LED_GPIO=y CONFIG_MISC=y CONFIG_ZYNQ_GEM_I2C_MAC_OFFSET=0x20 CONFIG_DM_MMC=y diff --git a/configs/xilinx_zynqmp_zcu102_revB_defconfig b/configs/xilinx_zynqmp_zcu102_revB_defconfig index 589c8e3..907cd10 100644 --- a/configs/xilinx_zynqmp_zcu102_revB_defconfig +++ b/configs/xilinx_zynqmp_zcu102_revB_defconfig @@ -63,6 +63,8 @@ CONFIG_CMD_PCA953X=y CONFIG_SYS_I2C_ZYNQ=y CONFIG_ZYNQ_I2C0=y CONFIG_ZYNQ_I2C1=y +CONFIG_LED=y +CONFIG_LED_GPIO=y CONFIG_MISC=y CONFIG_ZYNQ_GEM_I2C_MAC_OFFSET=0x20 CONFIG_DM_MMC=y diff --git a/configs/xilinx_zynqmp_zcu106_revA_defconfig b/configs/xilinx_zynqmp_zcu106_revA_defconfig index c8a50d3..45f9884 100644 --- a/configs/xilinx_zynqmp_zcu106_revA_defconfig +++ b/configs/xilinx_zynqmp_zcu106_revA_defconfig @@ -59,6 +59,8 @@ CONFIG_CMD_PCA953X=y CONFIG_SYS_I2C_ZYNQ=y CONFIG_ZYNQ_I2C0=y CONFIG_ZYNQ_I2C1=y +CONFIG_LED=y +CONFIG_LED_GPIO=y CONFIG_MISC=y CONFIG_ZYNQ_GEM_I2C_MAC_OFFSET=0x20 CONFIG_DM_MMC=y diff --git a/configs/xilinx_zynqmp_zcu111_revA_defconfig b/configs/xilinx_zynqmp_zcu111_revA_defconfig index a9adfbe..e035faa 100644 --- a/configs/xilinx_zynqmp_zcu111_revA_defconfig +++ b/configs/xilinx_zynqmp_zcu111_revA_defconfig @@ -53,6 +53,8 @@ CONFIG_CMD_PCA953X=y CONFIG_SYS_I2C_ZYNQ=y CONFIG_ZYNQ_I2C0=y CONFIG_ZYNQ_I2C1=y +CONFIG_LED=y +CONFIG_LED_GPIO=y CONFIG_MISC=y CONFIG_ZYNQ_GEM_I2C_MAC_OFFSET=0x20 CONFIG_DM_MMC=y diff --git a/configs/zynq_z_turn_defconfig b/configs/zynq_z_turn_defconfig index d8170ec..ce3ec00 100644 --- a/configs/zynq_z_turn_defconfig +++ b/configs/zynq_z_turn_defconfig @@ -35,6 +35,8 @@ CONFIG_DFU_RAM=y CONFIG_FPGA_XILINX=y CONFIG_FPGA_ZYNQPL=y CONFIG_DM_GPIO=y +CONFIG_LED=y +CONFIG_LED_GPIO=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_ZYNQ=y CONFIG_SPI_FLASH=y diff --git a/configs/zynq_zc702_defconfig b/configs/zynq_zc702_defconfig index ab719f9..dd5f834 100644 --- a/configs/zynq_zc702_defconfig +++ b/configs/zynq_zc702_defconfig @@ -46,6 +46,8 @@ CONFIG_FPGA_ZYNQPL=y CONFIG_DM_GPIO=y CONFIG_SYS_I2C_ZYNQ=y CONFIG_ZYNQ_I2C0=y +CONFIG_LED=y +CONFIG_LED_GPIO=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_ZYNQ=y CONFIG_SPI_FLASH=y From 0358cee5959fca0fea1074d038359d9d15a5a11e Mon Sep 17 00:00:00 2001 From: Vipul Kumar Date: Mon, 16 Jul 2018 18:04:22 +0530 Subject: [PATCH 41/55] arm64: zynqmp: Added support of mmio read and write commands This patch added support of mmio read and write commands. These commands can be used to read and write registers from the u-boot command line. It can be useful in debugging. Signed-off-by: Vipul Kumar Signed-off-by: Michal Simek --- board/xilinx/zynqmp/cmds.c | 48 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/board/xilinx/zynqmp/cmds.c b/board/xilinx/zynqmp/cmds.c index 1f6a5de..f8c8674 100644 --- a/board/xilinx/zynqmp/cmds.c +++ b/board/xilinx/zynqmp/cmds.c @@ -61,8 +61,51 @@ static int do_zynqmp_verify_secure(cmd_tbl_t *cmdtp, int flag, int argc, return ret; } +static int do_zynqmp_mmio_read(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]) +{ + u32 read_val, addr; + int ret; + + if (argc != cmdtp->maxargs) + return CMD_RET_USAGE; + + addr = simple_strtoul(argv[2], NULL, 16); + + ret = zynqmp_mmio_read(addr, &read_val); + if (!ret) + printf("mmio read value at 0x%x = 0x%x\n", + addr, read_val); + else + printf("Failed: mmio read\n"); + + return ret; +} + +static int do_zynqmp_mmio_write(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]) +{ + u32 addr, mask, val; + int ret; + + if (argc != cmdtp->maxargs) + return CMD_RET_USAGE; + + addr = simple_strtoul(argv[2], NULL, 16); + mask = simple_strtoul(argv[3], NULL, 16); + val = simple_strtoul(argv[4], NULL, 16); + + ret = zynqmp_mmio_write(addr, mask, val); + if (ret != 0) + printf("Failed: mmio write\n"); + + return ret; +} + static cmd_tbl_t cmd_zynqmp_sub[] = { U_BOOT_CMD_MKENT(secure, 5, 0, do_zynqmp_verify_secure, "", ""), + U_BOOT_CMD_MKENT(mmio_read, 3, 0, do_zynqmp_mmio_read, "", ""), + U_BOOT_CMD_MKENT(mmio_write, 5, 0, do_zynqmp_mmio_write, "", ""), }; /** @@ -99,7 +142,10 @@ static char zynqmp_help_text[] = "secure src len [key_addr] - verifies secure images of $len bytes\n" " long at address $src. Optional key_addr\n" " can be specified if user key needs to\n" - " be used for decryption\n"; + " be used for decryption\n" + "zynqmp mmio_read address - read from address\n" + "zynqmp mmio_write address mask value - write value after masking to\n" + " address\n"; #endif U_BOOT_CMD( From 0bd83060c2b01331f1b989433bc400b5bf002f9f Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Tue, 17 Jul 2018 13:17:39 +0200 Subject: [PATCH 42/55] watchdog: cadence: Do not stop wdt in probe Watchdog can be started before probe and u-boot should just take control over it. That's why do not stop watchdog in probe to cover cases where watchdog can expire before probe and start. Signed-off-by: Michal Simek --- drivers/watchdog/cdns_wdt.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/watchdog/cdns_wdt.c b/drivers/watchdog/cdns_wdt.c index 71575cb..fc85fbc 100644 --- a/drivers/watchdog/cdns_wdt.c +++ b/drivers/watchdog/cdns_wdt.c @@ -224,8 +224,6 @@ static int cdns_wdt_probe(struct udevice *dev) { debug("%s: Probing wdt%u\n", __func__, dev->seq); - cdns_wdt_stop(dev); - return 0; } From f4da871a7f09540557792ea5da688c54790add7d Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Tue, 17 Jul 2018 14:49:33 +0200 Subject: [PATCH 43/55] microblaze: Remove XILINX_SPI_FLASH_BASEADDR logic XILINX_SPI_FLASH_BASEADDR logic has been converted to DM that's why there is no reason to depend on this address anymore. Signed-off-by: Michal Simek --- include/configs/microblaze-generic.h | 7 ------- 1 file changed, 7 deletions(-) diff --git a/include/configs/microblaze-generic.h b/include/configs/microblaze-generic.h index 5eab2e5..d6a0f5a 100644 --- a/include/configs/microblaze-generic.h +++ b/include/configs/microblaze-generic.h @@ -19,16 +19,10 @@ #undef SPIFLASH #undef RAMENV /* hold environment in flash */ #else -#ifdef XILINX_SPI_FLASH_BASEADDR -#undef FLASH -#define SPIFLASH -#undef RAMENV /* hold environment in flash */ -#else #undef FLASH #undef SPIFLASH #define RAMENV /* hold environment in RAM */ #endif -#endif /* uart */ /* The following table includes the supported baudrates */ @@ -91,7 +85,6 @@ #else /* !FLASH */ #ifdef SPIFLASH -# define CONFIG_SYS_SPI_BASE XILINX_SPI_FLASH_BASEADDR # define CONFIG_SF_DEFAULT_MODE SPI_MODE_3 # define CONFIG_SF_DEFAULT_SPEED XILINX_SPI_FLASH_MAX_FREQ # define CONFIG_SF_DEFAULT_CS XILINX_SPI_FLASH_CS From 1473b12ad0b33771ded1b2fd6b73d2cd6d73b8f7 Mon Sep 17 00:00:00 2001 From: Siva Durga Prasad Paladugu Date: Mon, 16 Jul 2018 15:56:10 +0530 Subject: [PATCH 44/55] lib: fdtdec: Update ram_base to store ram start adddress This patch updates the ram_base to store the start address of the first bank DRAM and the use this ram_base to calculate ram_top properly. This patch fixes the erroneous calculation of ram_top incase of non zero ram start address. Signed-off-by: Siva Durga Prasad Paladugu Signed-off-by: Michal Simek Reviewed-by: Tom Rini --- common/board_f.c | 4 ++-- lib/fdtdec.c | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/common/board_f.c b/common/board_f.c index e943347..88d7700 100644 --- a/common/board_f.c +++ b/common/board_f.c @@ -281,9 +281,9 @@ static int setup_dest_addr(void) gd->ram_size -= CONFIG_SYS_MEM_TOP_HIDE; #endif #ifdef CONFIG_SYS_SDRAM_BASE - gd->ram_top = CONFIG_SYS_SDRAM_BASE; + gd->ram_base = CONFIG_SYS_SDRAM_BASE; #endif - gd->ram_top += get_effective_memsize(); + gd->ram_top = gd->ram_base + get_effective_memsize(); gd->ram_top = board_get_usable_ram_top(gd->mon_len); gd->relocaddr = gd->ram_top; debug("Ram top: %08lX\n", (ulong)gd->ram_top); diff --git a/lib/fdtdec.c b/lib/fdtdec.c index 1b0c430..66dff0f 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -1173,6 +1173,7 @@ int fdtdec_setup_memory_size(void) } gd->ram_size = (phys_size_t)(res.end - res.start + 1); + gd->ram_base = (unsigned long)res.start; debug("%s: Initial DRAM size %llx\n", __func__, (unsigned long long)gd->ram_size); From 12308b128fa28d50c1586f60f3117f5213356756 Mon Sep 17 00:00:00 2001 From: Siva Durga Prasad Paladugu Date: Mon, 16 Jul 2018 15:56:11 +0530 Subject: [PATCH 45/55] lib: fdtdec: Rename routine fdtdec_setup_memory_size() This patch renames the routine fdtdec_setup_memory_size() to fdtdec_setup_mem_size_base() as it now fills the mem base as well along with size. Signed-off-by: Siva Durga Prasad Paladugu Signed-off-by: Michal Simek Reviewed-by: Tom Rini --- arch/arm/mach-mvebu/arm64-common.c | 2 +- arch/arm/mach-socfpga/misc.c | 2 +- board/broadcom/bcmstb/bcmstb.c | 2 +- board/emulation/qemu-arm/qemu-arm.c | 2 +- board/renesas/alt/alt.c | 2 +- board/renesas/blanche/blanche.c | 2 +- board/renesas/draak/draak.c | 2 +- board/renesas/eagle/eagle.c | 2 +- board/renesas/ebisu/ebisu.c | 2 +- board/renesas/gose/gose.c | 2 +- board/renesas/koelsch/koelsch.c | 2 +- board/renesas/lager/lager.c | 2 +- board/renesas/porter/porter.c | 2 +- board/renesas/salvator-x/salvator-x.c | 2 +- board/renesas/silk/silk.c | 2 +- board/renesas/stout/stout.c | 2 +- board/renesas/ulcb/ulcb.c | 2 +- board/st/stm32f429-discovery/stm32f429-discovery.c | 2 +- board/st/stm32f429-evaluation/stm32f429-evaluation.c | 2 +- board/st/stm32f469-discovery/stm32f469-discovery.c | 2 +- board/st/stm32h743-disco/stm32h743-disco.c | 2 +- board/st/stm32h743-eval/stm32h743-eval.c | 2 +- board/xilinx/zynq/board.c | 2 +- board/xilinx/zynqmp/zynqmp.c | 2 +- board/xilinx/zynqmp_r5/board.c | 2 +- include/fdtdec.h | 16 +++++++++------- lib/fdtdec.c | 2 +- tools/patman/func_test.py | 2 +- tools/patman/test/0000-cover-letter.patch | 2 +- ...orrect-cast-for-sandbox-in-fdtdec_setup_memory_.patch | 4 ++-- tools/patman/test/test01.txt | 2 +- 31 files changed, 40 insertions(+), 38 deletions(-) diff --git a/arch/arm/mach-mvebu/arm64-common.c b/arch/arm/mach-mvebu/arm64-common.c index d3ea9e6..f47273f 100644 --- a/arch/arm/mach-mvebu/arm64-common.c +++ b/arch/arm/mach-mvebu/arm64-common.c @@ -54,7 +54,7 @@ int dram_init_banksize(void) int dram_init(void) { - if (fdtdec_setup_memory_size() != 0) + if (fdtdec_setup_mem_size_base() != 0) return -EINVAL; return 0; diff --git a/arch/arm/mach-socfpga/misc.c b/arch/arm/mach-socfpga/misc.c index 77628e1..a4f6d5c 100644 --- a/arch/arm/mach-socfpga/misc.c +++ b/arch/arm/mach-socfpga/misc.c @@ -40,7 +40,7 @@ struct bsel bsel_str[] = { int dram_init(void) { - if (fdtdec_setup_memory_size() != 0) + if (fdtdec_setup_mem_size_base() != 0) return -EINVAL; return 0; diff --git a/board/broadcom/bcmstb/bcmstb.c b/board/broadcom/bcmstb/bcmstb.c index 25cd354..5632846 100644 --- a/board/broadcom/bcmstb/bcmstb.c +++ b/board/broadcom/bcmstb/bcmstb.c @@ -48,7 +48,7 @@ int print_cpuinfo(void) int dram_init(void) { - if (fdtdec_setup_memory_size() != 0) + if (fdtdec_setup_mem_size_base() != 0) return -EINVAL; return 0; diff --git a/board/emulation/qemu-arm/qemu-arm.c b/board/emulation/qemu-arm/qemu-arm.c index 085cbbe..1f5a33d 100644 --- a/board/emulation/qemu-arm/qemu-arm.c +++ b/board/emulation/qemu-arm/qemu-arm.c @@ -47,7 +47,7 @@ int board_init(void) int dram_init(void) { - if (fdtdec_setup_memory_size() != 0) + if (fdtdec_setup_mem_size_base() != 0) return -EINVAL; return 0; diff --git a/board/renesas/alt/alt.c b/board/renesas/alt/alt.c index 86e9d24..b18ab7c 100644 --- a/board/renesas/alt/alt.c +++ b/board/renesas/alt/alt.c @@ -78,7 +78,7 @@ int board_init(void) int dram_init(void) { - if (fdtdec_setup_memory_size() != 0) + if (fdtdec_setup_mem_size_base() != 0) return -EINVAL; return 0; diff --git a/board/renesas/blanche/blanche.c b/board/renesas/blanche/blanche.c index 7d48d0f..f5ada6e 100644 --- a/board/renesas/blanche/blanche.c +++ b/board/renesas/blanche/blanche.c @@ -339,7 +339,7 @@ int board_eth_init(bd_t *bis) int dram_init(void) { - if (fdtdec_setup_memory_size() != 0) + if (fdtdec_setup_mem_size_base() != 0) return -EINVAL; return 0; diff --git a/board/renesas/draak/draak.c b/board/renesas/draak/draak.c index f804fae..852fdda 100644 --- a/board/renesas/draak/draak.c +++ b/board/renesas/draak/draak.c @@ -96,7 +96,7 @@ int board_init(void) int dram_init(void) { - if (fdtdec_setup_memory_size() != 0) + if (fdtdec_setup_mem_size_base() != 0) return -EINVAL; return 0; diff --git a/board/renesas/eagle/eagle.c b/board/renesas/eagle/eagle.c index 7b89c10..9317410 100644 --- a/board/renesas/eagle/eagle.c +++ b/board/renesas/eagle/eagle.c @@ -74,7 +74,7 @@ int board_init(void) int dram_init(void) { - if (fdtdec_setup_memory_size() != 0) + if (fdtdec_setup_mem_size_base() != 0) return -EINVAL; return 0; diff --git a/board/renesas/ebisu/ebisu.c b/board/renesas/ebisu/ebisu.c index fdff2a8..248223b 100644 --- a/board/renesas/ebisu/ebisu.c +++ b/board/renesas/ebisu/ebisu.c @@ -50,7 +50,7 @@ int board_init(void) int dram_init(void) { - if (fdtdec_setup_memory_size() != 0) + if (fdtdec_setup_mem_size_base() != 0) return -EINVAL; return 0; diff --git a/board/renesas/gose/gose.c b/board/renesas/gose/gose.c index 96ac29d..282381e 100644 --- a/board/renesas/gose/gose.c +++ b/board/renesas/gose/gose.c @@ -83,7 +83,7 @@ int board_init(void) int dram_init(void) { - if (fdtdec_setup_memory_size() != 0) + if (fdtdec_setup_mem_size_base() != 0) return -EINVAL; return 0; diff --git a/board/renesas/koelsch/koelsch.c b/board/renesas/koelsch/koelsch.c index b6688a2..52f37c9 100644 --- a/board/renesas/koelsch/koelsch.c +++ b/board/renesas/koelsch/koelsch.c @@ -85,7 +85,7 @@ int board_init(void) int dram_init(void) { - if (fdtdec_setup_memory_size() != 0) + if (fdtdec_setup_mem_size_base() != 0) return -EINVAL; return 0; diff --git a/board/renesas/lager/lager.c b/board/renesas/lager/lager.c index 6bfb0d1..062e88c 100644 --- a/board/renesas/lager/lager.c +++ b/board/renesas/lager/lager.c @@ -94,7 +94,7 @@ int board_init(void) int dram_init(void) { - if (fdtdec_setup_memory_size() != 0) + if (fdtdec_setup_mem_size_base() != 0) return -EINVAL; return 0; diff --git a/board/renesas/porter/porter.c b/board/renesas/porter/porter.c index cadff2c..663b800 100644 --- a/board/renesas/porter/porter.c +++ b/board/renesas/porter/porter.c @@ -83,7 +83,7 @@ int board_init(void) int dram_init(void) { - if (fdtdec_setup_memory_size() != 0) + if (fdtdec_setup_mem_size_base() != 0) return -EINVAL; return 0; diff --git a/board/renesas/salvator-x/salvator-x.c b/board/renesas/salvator-x/salvator-x.c index 651877c..00256bc 100644 --- a/board/renesas/salvator-x/salvator-x.c +++ b/board/renesas/salvator-x/salvator-x.c @@ -108,7 +108,7 @@ int board_init(void) int dram_init(void) { - if (fdtdec_setup_memory_size() != 0) + if (fdtdec_setup_mem_size_base() != 0) return -EINVAL; return 0; diff --git a/board/renesas/silk/silk.c b/board/renesas/silk/silk.c index 5fa472c..966c071 100644 --- a/board/renesas/silk/silk.c +++ b/board/renesas/silk/silk.c @@ -78,7 +78,7 @@ int board_init(void) int dram_init(void) { - if (fdtdec_setup_memory_size() != 0) + if (fdtdec_setup_mem_size_base() != 0) return -EINVAL; return 0; diff --git a/board/renesas/stout/stout.c b/board/renesas/stout/stout.c index 778593b..85e30db 100644 --- a/board/renesas/stout/stout.c +++ b/board/renesas/stout/stout.c @@ -97,7 +97,7 @@ int board_init(void) int dram_init(void) { - if (fdtdec_setup_memory_size() != 0) + if (fdtdec_setup_mem_size_base() != 0) return -EINVAL; return 0; diff --git a/board/renesas/ulcb/ulcb.c b/board/renesas/ulcb/ulcb.c index 9e15e45..213e869 100644 --- a/board/renesas/ulcb/ulcb.c +++ b/board/renesas/ulcb/ulcb.c @@ -96,7 +96,7 @@ int board_init(void) int dram_init(void) { - if (fdtdec_setup_memory_size() != 0) + if (fdtdec_setup_mem_size_base() != 0) return -EINVAL; return 0; diff --git a/board/st/stm32f429-discovery/stm32f429-discovery.c b/board/st/stm32f429-discovery/stm32f429-discovery.c index b7638c0..e800d70 100644 --- a/board/st/stm32f429-discovery/stm32f429-discovery.c +++ b/board/st/stm32f429-discovery/stm32f429-discovery.c @@ -29,7 +29,7 @@ int dram_init(void) return rv; } - if (fdtdec_setup_memory_size() != 0) + if (fdtdec_setup_mem_size_base() != 0) rv = -EINVAL; return rv; diff --git a/board/st/stm32f429-evaluation/stm32f429-evaluation.c b/board/st/stm32f429-evaluation/stm32f429-evaluation.c index 2e638c6..fd2109b 100644 --- a/board/st/stm32f429-evaluation/stm32f429-evaluation.c +++ b/board/st/stm32f429-evaluation/stm32f429-evaluation.c @@ -23,7 +23,7 @@ int dram_init(void) return rv; } - if (fdtdec_setup_memory_size() != 0) + if (fdtdec_setup_mem_size_base() != 0) rv = -EINVAL; return rv; diff --git a/board/st/stm32f469-discovery/stm32f469-discovery.c b/board/st/stm32f469-discovery/stm32f469-discovery.c index 90d7045..a457f90 100644 --- a/board/st/stm32f469-discovery/stm32f469-discovery.c +++ b/board/st/stm32f469-discovery/stm32f469-discovery.c @@ -23,7 +23,7 @@ int dram_init(void) return rv; } - if (fdtdec_setup_memory_size() != 0) + if (fdtdec_setup_mem_size_base() != 0) rv = -EINVAL; return rv; diff --git a/board/st/stm32h743-disco/stm32h743-disco.c b/board/st/stm32h743-disco/stm32h743-disco.c index fa007c7..3ab9518 100644 --- a/board/st/stm32h743-disco/stm32h743-disco.c +++ b/board/st/stm32h743-disco/stm32h743-disco.c @@ -20,7 +20,7 @@ int dram_init(void) return ret; } - if (fdtdec_setup_memory_size() != 0) + if (fdtdec_setup_mem_size_base() != 0) ret = -EINVAL; return ret; diff --git a/board/st/stm32h743-eval/stm32h743-eval.c b/board/st/stm32h743-eval/stm32h743-eval.c index fa007c7..3ab9518 100644 --- a/board/st/stm32h743-eval/stm32h743-eval.c +++ b/board/st/stm32h743-eval/stm32h743-eval.c @@ -20,7 +20,7 @@ int dram_init(void) return ret; } - if (fdtdec_setup_memory_size() != 0) + if (fdtdec_setup_mem_size_base() != 0) ret = -EINVAL; return ret; diff --git a/board/xilinx/zynq/board.c b/board/xilinx/zynq/board.c index 9c005e4..614d93c 100644 --- a/board/xilinx/zynq/board.c +++ b/board/xilinx/zynq/board.c @@ -98,7 +98,7 @@ int dram_init_banksize(void) int dram_init(void) { - if (fdtdec_setup_memory_size() != 0) + if (fdtdec_setup_mem_size_base() != 0) return -EINVAL; zynq_ddrc_init(); diff --git a/board/xilinx/zynqmp/zynqmp.c b/board/xilinx/zynqmp/zynqmp.c index 06cdcbd..89fac6b 100644 --- a/board/xilinx/zynqmp/zynqmp.c +++ b/board/xilinx/zynqmp/zynqmp.c @@ -423,7 +423,7 @@ int dram_init_banksize(void) int dram_init(void) { - if (fdtdec_setup_memory_size() != 0) + if (fdtdec_setup_mem_size_base() != 0) return -EINVAL; return 0; diff --git a/board/xilinx/zynqmp_r5/board.c b/board/xilinx/zynqmp_r5/board.c index 70fb202..1c45ee7 100644 --- a/board/xilinx/zynqmp_r5/board.c +++ b/board/xilinx/zynqmp_r5/board.c @@ -18,7 +18,7 @@ int dram_init_banksize(void) int dram_init(void) { - if (fdtdec_setup_memory_size() != 0) + if (fdtdec_setup_mem_size_base() != 0) return -EINVAL; return 0; diff --git a/include/fdtdec.h b/include/fdtdec.h index 58d5b72..83be064 100644 --- a/include/fdtdec.h +++ b/include/fdtdec.h @@ -957,20 +957,22 @@ int fdtdec_decode_display_timing(const void *blob, int node, int index, struct display_timing *config); /** - * fdtdec_setup_memory_size() - decode and setup gd->ram_size + * fdtdec_setup_mem_size_base() - decode and setup gd->ram_size and + * gd->ram_start * - * Decode the /memory 'reg' property to determine the size of the first memory - * bank, populate the global data with the size of the first bank of memory. + * Decode the /memory 'reg' property to determine the size and start of the + * first memory bank, populate the global data with the size and start of the + * first bank of memory. * * This function should be called from a boards dram_init(). This helper - * function allows for boards to query the device tree for DRAM size instead of - * hard coding the value in the case where the memory size cannot be detected - * automatically. + * function allows for boards to query the device tree for DRAM size and start + * address instead of hard coding the value in the case where the memory size + * and start address cannot be detected automatically. * * @return 0 if OK, -EINVAL if the /memory node or reg property is missing or * invalid */ -int fdtdec_setup_memory_size(void); +int fdtdec_setup_mem_size_base(void); /** * fdtdec_setup_memory_banksize() - decode and populate gd->bd->bi_dram diff --git a/lib/fdtdec.c b/lib/fdtdec.c index 66dff0f..c373dde 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -1155,7 +1155,7 @@ int fdtdec_decode_display_timing(const void *blob, int parent, int index, return ret; } -int fdtdec_setup_memory_size(void) +int fdtdec_setup_mem_size_base(void) { int ret, mem; struct fdt_resource res; diff --git a/tools/patman/func_test.py b/tools/patman/func_test.py index 3f7e032..d79e716 100644 --- a/tools/patman/func_test.py +++ b/tools/patman/func_test.py @@ -210,7 +210,7 @@ Changes in v4: Simon Glass (2): pci: Correct cast for sandbox - fdt: Correct cast for sandbox in fdtdec_setup_memory_size() + fdt: Correct cast for sandbox in fdtdec_setup_mem_size_base() cmd/pci.c | 3 ++- fs/fat/fat.c | 1 + diff --git a/tools/patman/test/0000-cover-letter.patch b/tools/patman/test/0000-cover-letter.patch index 2906201..c99e635 100644 --- a/tools/patman/test/0000-cover-letter.patch +++ b/tools/patman/test/0000-cover-letter.patch @@ -10,7 +10,7 @@ Content-Transfer-Encoding: 8bit Simon Glass (2): pci: Correct cast for sandbox - fdt: Correct cast for sandbox in fdtdec_setup_memory_size() + fdt: Correct cast for sandbox in fdtdec_setup_mem_size_base() cmd/pci.c | 3 ++- fs/fat/fat.c | 1 + diff --git a/tools/patman/test/0002-fdt-Correct-cast-for-sandbox-in-fdtdec_setup_memory_.patch b/tools/patman/test/0002-fdt-Correct-cast-for-sandbox-in-fdtdec_setup_memory_.patch index e328497..702c030 100644 --- a/tools/patman/test/0002-fdt-Correct-cast-for-sandbox-in-fdtdec_setup_memory_.patch +++ b/tools/patman/test/0002-fdt-Correct-cast-for-sandbox-in-fdtdec_setup_memory_.patch @@ -1,7 +1,7 @@ From 5ab48490f03051875ab13d288a4bf32b507d76fd Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sat, 15 Apr 2017 15:39:08 -0600 -Subject: [RFC 2/2] fdt: Correct cast for sandbox in fdtdec_setup_memory_size() +Subject: [RFC 2/2] fdt: Correct cast for sandbox in fdtdec_setup_mem_size_base() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @@ -58,7 +58,7 @@ diff --git a/lib/fdtdec.c b/lib/fdtdec.c index c072e54..942244f 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c -@@ -1200,7 +1200,8 @@ int fdtdec_setup_memory_size(void) +@@ -1200,7 +1200,8 @@ int fdtdec_setup_mem_size_base(void) } gd->ram_size = (phys_size_t)(res.end - res.start + 1); diff --git a/tools/patman/test/test01.txt b/tools/patman/test/test01.txt index 8ad9587..478ea93 100644 --- a/tools/patman/test/test01.txt +++ b/tools/patman/test/test01.txt @@ -28,7 +28,7 @@ commit 5ab48490f03051875ab13d288a4bf32b507d76fd Author: Simon Glass Date: Sat Apr 15 15:39:08 2017 -0600 - fdt: Correct cast for sandbox in fdtdec_setup_memory_size() + fdt: Correct cast for sandbox in fdtdec_setup_mem_size_base() This gives a warning with some native compilers: From e4655aa2409eeeb3ce7d7ddbbe30b2c5caf8d068 Mon Sep 17 00:00:00 2001 From: Siva Durga Prasad Paladugu Date: Mon, 16 Jul 2018 15:57:00 +0530 Subject: [PATCH 46/55] arm: zynq: Dont define SDRAM_BASE and SDRAM_SIZE in .h Remove the SDRAM_BASE and SDRAM_SIZE as it can now get these details from DT. Signed-off-by: Siva Durga Prasad Paladugu Signed-off-by: Michal Simek Reviewed-by: Simon Glass --- include/configs/zynq_cse.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/include/configs/zynq_cse.h b/include/configs/zynq_cse.h index 2f5843f..adc02f0 100644 --- a/include/configs/zynq_cse.h +++ b/include/configs/zynq_cse.h @@ -41,7 +41,4 @@ #undef CONFIG_SYS_MALLOC_LEN #define CONFIG_SYS_MALLOC_LEN 0x1000 -#define CONFIG_SYS_SDRAM_BASE 0xfffc0000 -#define CONFIG_SYS_SDRAM_SIZE 0x40000 - #endif /* __CONFIG_ZYNQ_CSE_H */ From 6754fabe6537cee05cf43d20b0e21a28ecf5c69d Mon Sep 17 00:00:00 2001 From: Siva Durga Prasad Paladugu Date: Mon, 16 Jul 2018 15:57:01 +0530 Subject: [PATCH 47/55] arm: zynq: Add Nand flash mini u-boot configuration for zynq Add configuration files/dtses for mini u-boot configuration which runs on smaller footprint of memory. This configuration has only required nand flash support. Signed-off-by: Siva Durga Prasad Paladugu Signed-off-by: Michal Simek --- arch/arm/dts/Makefile | 1 + arch/arm/dts/zynq-cse-nand.dts | 80 +++++++++++++++++++++++++++++++++++++++++ configs/zynq_cse_nand_defconfig | 47 ++++++++++++++++++++++++ 3 files changed, 128 insertions(+) create mode 100644 arch/arm/dts/zynq-cse-nand.dts create mode 100644 configs/zynq_cse_nand_defconfig diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 9607239..4247104 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -129,6 +129,7 @@ dtb-$(CONFIG_ARCH_UNIPHIER_SLD8) += \ dtb-$(CONFIG_ARCH_ZYNQ) += \ zynq-cc108.dtb \ + zynq-cse-nand.dtb \ zynq-cse-qspi-single.dtb \ zynq-microzed.dtb \ zynq-minized.dtb \ diff --git a/arch/arm/dts/zynq-cse-nand.dts b/arch/arm/dts/zynq-cse-nand.dts new file mode 100644 index 0000000..9b1dd19 --- /dev/null +++ b/arch/arm/dts/zynq-cse-nand.dts @@ -0,0 +1,80 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Xilinx CSE NAND board DTS + * + * Copyright (C) 2018 Xilinx, Inc. + */ +/dts-v1/; + +/ { + #address-cells = <1>; + #size-cells = <1>; + model = "Zynq CSE NAND Board"; + compatible = "xlnx,zynq-cse-nand", "xlnx,zynq-7000"; + + aliases { + serial0 = &dcc; + }; + + memory@0 { + device_type = "memory"; + reg = <0x0 0x400000>; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + dcc: dcc { + compatible = "arm,dcc"; + status = "disabled"; + u-boot,dm-pre-reloc; + }; + + amba: amba { + u-boot,dm-pre-reloc; + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + slcr: slcr@f8000000 { + u-boot,dm-pre-reloc; + #address-cells = <1>; + #size-cells = <1>; + compatible = "xlnx,zynq-slcr", "syscon", "simple-bus"; + reg = <0xF8000000 0x1000>; + ranges; + clkc: clkc@100 { + u-boot,dm-pre-reloc; + #clock-cells = <1>; + compatible = "xlnx,ps7-clkc"; + clock-output-names = "armpll", "ddrpll", + "iopll", "cpu_6or4x", + "cpu_3or2x", "cpu_2x", "cpu_1x", + "ddr2x", "ddr3x", "dci", + "lqspi", "smc", "pcap", "gem0", + "gem1", "fclk0", "fclk1", + "fclk2", "fclk3", "can0", + "can1", "sdio0", "sdio1", + "uart0", "uart1", "spi0", + "spi1", "dma", "usb0_aper", + "usb1_aper", "gem0_aper", + "gem1_aper", "sdio0_aper", + "sdio1_aper", "spi0_aper", + "spi1_aper", "can0_aper", + "can1_aper", "i2c0_aper", + "i2c1_aper", "uart0_aper", + "uart1_aper", "gpio_aper", + "lqspi_aper", "smc_aper", + "swdt", "dbg_trc", "dbg_apb"; + reg = <0x100 0x100>; + }; + }; + }; + +}; + +&dcc { + status = "okay"; +}; diff --git a/configs/zynq_cse_nand_defconfig b/configs/zynq_cse_nand_defconfig new file mode 100644 index 0000000..dcd4eda --- /dev/null +++ b/configs/zynq_cse_nand_defconfig @@ -0,0 +1,47 @@ +CONFIG_ARM=y +CONFIG_SYS_CONFIG_NAME="zynq_cse" +CONFIG_ARCH_ZYNQ=y +CONFIG_SYS_TEXT_BASE=0x100000 +CONFIG_SPL=y +CONFIG_SPL_STACK_R_ADDR=0x200000 +CONFIG_DEFAULT_DEVICE_TREE="zynq-cse-nand" +# CONFIG_DISPLAY_CPUINFO is not set +CONFIG_SPL_STACK_R=y +CONFIG_SYS_PROMPT="Zynq> " +# CONFIG_CMD_BDI is not set +# CONFIG_CMD_CONSOLE is not set +# CONFIG_CMD_BOOTD is not set +# CONFIG_CMD_BOOTM is not set +# CONFIG_CMD_ELF is not set +# CONFIG_CMD_FDT is not set +# CONFIG_CMD_GO is not set +# CONFIG_CMD_RUN is not set +# CONFIG_CMD_IMI is not set +# CONFIG_CMD_XIMG is not set +# CONFIG_CMD_SPL is not set +# CONFIG_CMD_EXPORTENV is not set +# CONFIG_CMD_IMPORTENV is not set +# CONFIG_CMD_EDITENV is not set +# CONFIG_CMD_SAVEENV is not set +# CONFIG_CMD_ENV_EXISTS is not set +# CONFIG_CMD_CRC32 is not set +# CONFIG_CMD_CLK is not set +# CONFIG_CMD_DM is not set +# CONFIG_CMD_FLASH is not set +# CONFIG_CMD_LOADB is not set +# CONFIG_CMD_LOADS is not set +# CONFIG_CMD_ECHO is not set +# CONFIG_CMD_ITEST is not set +# CONFIG_CMD_SOURCE is not set +# CONFIG_CMD_SETEXPR is not set +# CONFIG_CMD_NET is not set +# CONFIG_CMD_MISC is not set +# CONFIG_PARTITIONS is not set +CONFIG_OF_EMBED=y +# CONFIG_DM_WARN is not set +# CONFIG_DM_DEVICE_REMOVE is not set +CONFIG_SPL_DM_SEQ_ALIAS=y +# CONFIG_MMC is not set +CONFIG_NAND=y +CONFIG_NAND_ZYNQ=y +# CONFIG_EFI_LOADER is not set From 1c310aec671e7cde9cd255b2ffbc6089ee7ac53b Mon Sep 17 00:00:00 2001 From: Siva Durga Prasad Paladugu Date: Mon, 16 Jul 2018 15:57:02 +0530 Subject: [PATCH 48/55] arm: zynq: Add parallel NOR flash mini u-boot configuration for zynq Add configuration files/dtses for mini u-boot configuration which runs on smaller footprint OCM memory. This configuration only has required parallel nor flash support. Signed-off-by: Siva Durga Prasad Paladugu Signed-off-by: Michal Simek --- arch/arm/dts/Makefile | 1 + arch/arm/dts/zynq-cse-nor.dts | 88 ++++++++++++++++++++++++++++++++++++++++++ configs/zynq_cse_nor_defconfig | 46 ++++++++++++++++++++++ 3 files changed, 135 insertions(+) create mode 100644 arch/arm/dts/zynq-cse-nor.dts create mode 100644 configs/zynq_cse_nor_defconfig diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 4247104..1bdcb1b 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -130,6 +130,7 @@ dtb-$(CONFIG_ARCH_UNIPHIER_SLD8) += \ dtb-$(CONFIG_ARCH_ZYNQ) += \ zynq-cc108.dtb \ zynq-cse-nand.dtb \ + zynq-cse-nor.dtb \ zynq-cse-qspi-single.dtb \ zynq-microzed.dtb \ zynq-minized.dtb \ diff --git a/arch/arm/dts/zynq-cse-nor.dts b/arch/arm/dts/zynq-cse-nor.dts new file mode 100644 index 0000000..ba6f9a1 --- /dev/null +++ b/arch/arm/dts/zynq-cse-nor.dts @@ -0,0 +1,88 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Xilinx CSE NOR board DTS + * + * Copyright (C) 2018 Xilinx, Inc. + */ +/dts-v1/; +#include "zynq-7000.dtsi" + +/ { + #address-cells = <1>; + #size-cells = <1>; + model = "Zynq CSE NOR Board"; + compatible = "xlnx,zynq-cse-nor", "xlnx,zynq-7000"; + + aliases { + serial0 = &dcc; + }; + + memory@fffc0000 { + device_type = "memory"; + reg = <0xFFFC0000 0x40000>; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + dcc: dcc { + compatible = "arm,dcc"; + status = "disabled"; + u-boot,dm-pre-reloc; + }; + + amba: amba { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + interrupt-parent = <&intc>; + ranges; + + intc: interrupt-controller@f8f01000 { + compatible = "arm,cortex-a9-gic"; + #interrupt-cells = <3>; + interrupt-controller; + reg = <0xF8F01000 0x1000>, + <0xF8F00100 0x100>; + }; + + slcr: slcr@f8000000 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "xlnx,zynq-slcr", "syscon", "simple-bus"; + reg = <0xF8000000 0x1000>; + ranges; + clkc: clkc@100 { + #clock-cells = <1>; + compatible = "xlnx,ps7-clkc"; + fclk-enable = <0xf>; + clock-output-names = "armpll", "ddrpll", + "iopll", "cpu_6or4x", + "cpu_3or2x", "cpu_2x", "cpu_1x", + "ddr2x", "ddr3x", "dci", + "lqspi", "smc", "pcap", "gem0", + "gem1", "fclk0", "fclk1", + "fclk2", "fclk3", "can0", + "can1", "sdio0", "sdio1", + "uart0", "uart1", "spi0", + "spi1", "dma", "usb0_aper", + "usb1_aper", "gem0_aper", + "gem1_aper", "sdio0_aper", + "sdio1_aper", "spi0_aper", + "spi1_aper", "can0_aper", + "can1_aper", "i2c0_aper", + "i2c1_aper", "uart0_aper", + "uart1_aper", "gpio_aper", + "lqspi_aper", "smc_aper", + "swdt", "dbg_trc", "dbg_apb"; + reg = <0x100 0x100>; + }; + }; + }; + +}; + +&dcc { + status = "okay"; +}; diff --git a/configs/zynq_cse_nor_defconfig b/configs/zynq_cse_nor_defconfig new file mode 100644 index 0000000..9e2546b --- /dev/null +++ b/configs/zynq_cse_nor_defconfig @@ -0,0 +1,46 @@ +CONFIG_ARM=y +CONFIG_SYS_CONFIG_NAME="zynq_cse" +CONFIG_ARCH_ZYNQ=y +CONFIG_SYS_TEXT_BASE=0xFFFC0000 +CONFIG_SPL=y +CONFIG_SPL_STACK_R_ADDR=0x200000 +CONFIG_DEFAULT_DEVICE_TREE="zynq-cse-nor" +CONFIG_BOOTDELAY=-1 +# CONFIG_DISPLAY_CPUINFO is not set +CONFIG_SPL_STACK_R=y +CONFIG_SYS_PROMPT="Zynq> " +# CONFIG_CMD_BDI is not set +# CONFIG_CMD_CONSOLE is not set +# CONFIG_CMD_BOOTD is not set +# CONFIG_CMD_BOOTM is not set +# CONFIG_CMD_ELF is not set +# CONFIG_CMD_FDT is not set +# CONFIG_CMD_GO is not set +# CONFIG_CMD_RUN is not set +# CONFIG_CMD_IMI is not set +# CONFIG_CMD_XIMG is not set +# CONFIG_CMD_SPL is not set +# CONFIG_CMD_EXPORTENV is not set +# CONFIG_CMD_IMPORTENV is not set +# CONFIG_CMD_EDITENV is not set +# CONFIG_CMD_SAVEENV is not set +# CONFIG_CMD_ENV_EXISTS is not set +# CONFIG_CMD_CRC32 is not set +# CONFIG_CMD_CLK is not set +# CONFIG_CMD_DM is not set +# CONFIG_CMD_LOADB is not set +# CONFIG_CMD_LOADS is not set +# CONFIG_CMD_ECHO is not set +# CONFIG_CMD_ITEST is not set +# CONFIG_CMD_SOURCE is not set +# CONFIG_CMD_SETEXPR is not set +# CONFIG_CMD_NET is not set +# CONFIG_CMD_MISC is not set +# CONFIG_PARTITIONS is not set +CONFIG_OF_EMBED=y +# CONFIG_DM_WARN is not set +# CONFIG_DM_DEVICE_REMOVE is not set +CONFIG_SPL_DM_SEQ_ALIAS=y +# CONFIG_MMC is not set +CONFIG_MTD_NOR_FLASH=y +# CONFIG_EFI_LOADER is not set From 2a30809cae098d8d2d4af7c5fba059993ef5f10e Mon Sep 17 00:00:00 2001 From: Vipul Kumar Date: Tue, 17 Jul 2018 19:00:34 +0530 Subject: [PATCH 49/55] env: Added support to save env to spi through Kconfig This patch added support to enable CONFIG_ENV_SIZE, CONFIG_ENV_OFFSET and CONFIG_ENV_SECT_SIZE through Kconfig for Zynq and Zynqmp. Signed-off-by: Vipul Kumar Signed-off-by: Michal Simek --- configs/bitmain_antminer_s9_defconfig | 1 + env/Kconfig | 28 ++++++++++++++++++++++++++++ include/configs/bitmain_antminer_s9.h | 3 --- include/configs/xilinx_zynqmp.h | 3 --- include/configs/zynq-common.h | 13 ------------- 5 files changed, 29 insertions(+), 19 deletions(-) diff --git a/configs/bitmain_antminer_s9_defconfig b/configs/bitmain_antminer_s9_defconfig index 40bce4e..f59c767 100644 --- a/configs/bitmain_antminer_s9_defconfig +++ b/configs/bitmain_antminer_s9_defconfig @@ -4,6 +4,7 @@ CONFIG_SYS_BOARD="antminer_s9" CONFIG_SYS_CONFIG_NAME="bitmain_antminer_s9" CONFIG_ARCH_ZYNQ=y CONFIG_SYS_TEXT_BASE=0x4000000 +CONFIG_ENV_OFFSET=0x300000 CONFIG_SPL=y CONFIG_DEBUG_UART_BASE=0xe0001000 CONFIG_DEBUG_UART_CLOCK=50000000 diff --git a/env/Kconfig b/env/Kconfig index 8618376..b37dcd7 100644 --- a/env/Kconfig +++ b/env/Kconfig @@ -480,6 +480,34 @@ config ENV_SIZE endif +if ARCH_ZYNQMP || ARCH_ZYNQ + +config ENV_OFFSET + hex "Environment Offset" + depends on !ENV_IS_NOWHERE + default 0x1E00000 if ARCH_ZYNQMP + default 0xE0000 if ARCH_ZYNQ + help + Offset from the start of the device (or partition) + +config ENV_SIZE + hex "Environment Size" + default 0x40000 if ENV_IS_IN_SPI_FLASH && ARCH_ZYNQMP + default 0x8000 if ARCH_ZYNQMP + default 0x20000 if ARCH_ZYNQ + help + Size of the environment storage area. + +config ENV_SECT_SIZE + hex "Environment Sector-Size" + depends on !ENV_IS_NOWHERE + default 0x40000 if ARCH_ZYNQMP + default 0x20000 if ARCH_ZYNQ + help + Size of the sector containing the environment. + +endif + config USE_DEFAULT_ENV_FILE bool "Create default environment from file" help diff --git a/include/configs/bitmain_antminer_s9.h b/include/configs/bitmain_antminer_s9.h index 2267502..a9f45f1 100644 --- a/include/configs/bitmain_antminer_s9.h +++ b/include/configs/bitmain_antminer_s9.h @@ -9,9 +9,6 @@ #define CONFIG_SYS_SDRAM_BASE 0x00000000 #define CONFIG_SYS_SDRAM_SIZE 0x40000000 -#define CONFIG_ENV_SIZE 0x20000 -#define CONFIG_ENV_OFFSET 0x300000 - #define CONFIG_BOOTP_SERVERIP #define CONFIG_EXTRA_ENV_SETTINGS \ diff --git a/include/configs/xilinx_zynqmp.h b/include/configs/xilinx_zynqmp.h index ebc6c6f..ef242c7 100644 --- a/include/configs/xilinx_zynqmp.h +++ b/include/configs/xilinx_zynqmp.h @@ -99,9 +99,6 @@ # define PARTS_DEFAULT #endif -/* Do not preserve environment */ -#define CONFIG_ENV_SIZE 0x8000 - /* Monitor Command Prompt */ /* Console I/O Buffer Size */ #define CONFIG_SYS_CBSIZE 2048 diff --git a/include/configs/zynq-common.h b/include/configs/zynq-common.h index a6f2ace..c41dc2c 100644 --- a/include/configs/zynq-common.h +++ b/include/configs/zynq-common.h @@ -121,22 +121,9 @@ # define CONFIG_SYS_EEPROM_SIZE 1024 /* Bytes */ #endif -/* Total Size of Environment Sector */ -#ifndef CONFIG_ENV_SIZE -# define CONFIG_ENV_SIZE (128 << 10) -#endif - /* Allow to overwrite serial and ethaddr */ #define CONFIG_ENV_OVERWRITE -/* Environment */ -#ifndef CONFIG_ENV_IS_NOWHERE -# define CONFIG_ENV_SECT_SIZE CONFIG_ENV_SIZE -# ifndef CONFIG_ENV_OFFSET -# define CONFIG_ENV_OFFSET 0xE0000 -# endif -#endif - /* enable preboot to be loaded before CONFIG_BOOTDELAY */ #define CONFIG_PREBOOT From bb8920ed77ecc19fcbe55fbd7504775d7f7b51eb Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Wed, 18 Jul 2018 12:59:14 +0200 Subject: [PATCH 50/55] arm: zynq: Setup ENV_SIZE via Kconfig Simplify zynq_cse config by setting up ENV_SIZE via Kconfig. Signed-off-by: Michal Simek --- configs/zynq_cse_nand_defconfig | 1 + configs/zynq_cse_nor_defconfig | 1 + configs/zynq_cse_qspi_defconfig | 1 + include/configs/zynq_cse.h | 2 -- 4 files changed, 3 insertions(+), 2 deletions(-) diff --git a/configs/zynq_cse_nand_defconfig b/configs/zynq_cse_nand_defconfig index dcd4eda..eb7e574 100644 --- a/configs/zynq_cse_nand_defconfig +++ b/configs/zynq_cse_nand_defconfig @@ -2,6 +2,7 @@ CONFIG_ARM=y CONFIG_SYS_CONFIG_NAME="zynq_cse" CONFIG_ARCH_ZYNQ=y CONFIG_SYS_TEXT_BASE=0x100000 +CONFIG_ENV_SIZE=0x190 CONFIG_SPL=y CONFIG_SPL_STACK_R_ADDR=0x200000 CONFIG_DEFAULT_DEVICE_TREE="zynq-cse-nand" diff --git a/configs/zynq_cse_nor_defconfig b/configs/zynq_cse_nor_defconfig index 9e2546b..95b31a0 100644 --- a/configs/zynq_cse_nor_defconfig +++ b/configs/zynq_cse_nor_defconfig @@ -2,6 +2,7 @@ CONFIG_ARM=y CONFIG_SYS_CONFIG_NAME="zynq_cse" CONFIG_ARCH_ZYNQ=y CONFIG_SYS_TEXT_BASE=0xFFFC0000 +CONFIG_ENV_SIZE=0x190 CONFIG_SPL=y CONFIG_SPL_STACK_R_ADDR=0x200000 CONFIG_DEFAULT_DEVICE_TREE="zynq-cse-nor" diff --git a/configs/zynq_cse_qspi_defconfig b/configs/zynq_cse_qspi_defconfig index df6ebdc..c094a5e 100644 --- a/configs/zynq_cse_qspi_defconfig +++ b/configs/zynq_cse_qspi_defconfig @@ -2,6 +2,7 @@ CONFIG_ARM=y CONFIG_SYS_CONFIG_NAME="zynq_cse" CONFIG_ARCH_ZYNQ=y CONFIG_SYS_TEXT_BASE=0xFFFC0000 +CONFIG_ENV_SIZE=0x190 CONFIG_SPL=y CONFIG_DEBUG_UART_BASE=0x0 CONFIG_DEBUG_UART_CLOCK=0 diff --git a/include/configs/zynq_cse.h b/include/configs/zynq_cse.h index adc02f0..36fbe0e 100644 --- a/include/configs/zynq_cse.h +++ b/include/configs/zynq_cse.h @@ -18,7 +18,6 @@ /* Undef unneeded configs */ #undef CONFIG_EXTRA_ENV_SETTINGS #undef CONFIG_BOARD_LATE_INIT -#undef CONFIG_ENV_SIZE #undef CONFIG_ZLIB #undef CONFIG_GZIP @@ -28,7 +27,6 @@ #define CONFIG_SYS_CBSIZE 1024 -#define CONFIG_ENV_SIZE 400 #undef CONFIG_SYS_INIT_RAM_ADDR #undef CONFIG_SYS_INIT_RAM_SIZE #define CONFIG_SYS_INIT_RAM_ADDR 0xFFFDE000 From 14ed50a4bfadf7bc3437b325ec655c79bddd8833 Mon Sep 17 00:00:00 2001 From: Siva Durga Prasad Paladugu Date: Wed, 18 Jul 2018 16:31:38 +0530 Subject: [PATCH 51/55] arm64: zynqmp: Add QSPI flash mini u-boot configuration Add configuration files/dtses for mini u-boot configuration which runs on smaller footprint of internal memory. This configuration has only required qspi flash support and it uses DCC as serial. Signed-off-by: Siva Durga Prasad Paladugu Signed-off-by: Michal Simek --- arch/arm/dts/Makefile | 1 + arch/arm/dts/zynqmp-mini-qspi.dts | 79 +++++++++++++++++++++++++++++++ configs/xilinx_zynqmp_mini_qspi_defconfig | 61 ++++++++++++++++++++++++ include/configs/xilinx_zynqmp_mini_qspi.h | 21 ++++++++ 4 files changed, 162 insertions(+) create mode 100644 arch/arm/dts/zynqmp-mini-qspi.dts create mode 100644 configs/xilinx_zynqmp_mini_qspi_defconfig create mode 100644 include/configs/xilinx_zynqmp_mini_qspi.h diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 1bdcb1b..094c41b 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -152,6 +152,7 @@ dtb-$(CONFIG_ARCH_ZYNQMP) += \ zynqmp-mini-emmc0.dtb \ zynqmp-mini-emmc1.dtb \ zynqmp-mini-nand.dtb \ + zynqmp-mini-qspi.dtb \ zynqmp-zcu100-revC.dtb \ zynqmp-zcu102-revA.dtb \ zynqmp-zcu102-revB.dtb \ diff --git a/arch/arm/dts/zynqmp-mini-qspi.dts b/arch/arm/dts/zynqmp-mini-qspi.dts new file mode 100644 index 0000000..c235a5f --- /dev/null +++ b/arch/arm/dts/zynqmp-mini-qspi.dts @@ -0,0 +1,79 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * dts file for Xilinx ZynqMP Mini Configuration + * + * (C) Copyright 2015 - 2018, Xilinx, Inc. + * + * Siva Durga Prasad + * Michal Simek + */ + +/dts-v1/; + +/ { + model = "ZynqMP MINI QSPI"; + compatible = "xlnx,zynqmp"; + #address-cells = <2>; + #size-cells = <1>; + + aliases { + serial0 = &dcc; + spi0 = &qspi; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + memory@fffc0000 { + device_type = "memory"; + reg = <0x0 0xfffc0000 0x40000>; + }; + + dcc: dcc { + compatible = "arm,dcc"; + status = "disabled"; + u-boot,dm-pre-reloc; + }; + + amba: amba { + compatible = "simple-bus"; + #address-cells = <2>; + #size-cells = <1>; + ranges; + + qspi: spi@ff0f0000 { + compatible = "xlnx,zynqmp-qspi-1.0"; + status = "disabled"; + clock-names = "ref_clk", "pclk"; + clocks = <&misc_clk &misc_clk>; + num-cs = <1>; + reg = <0x0 0xff0f0000 0x1000 0x0 0xc0000000 0x8000000>; + #address-cells = <1>; + #size-cells = <0>; + }; + + misc_clk: misc_clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <125000000>; + }; + }; +}; + +&qspi { + status = "okay"; + flash@0 { + compatible = "n25q512a11"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0x0>; + spi-tx-bus-width = <1>; + spi-rx-bus-width = <4>; + spi-max-frequency = <10000000>; + }; +}; + +&dcc { + status = "okay"; +}; diff --git a/configs/xilinx_zynqmp_mini_qspi_defconfig b/configs/xilinx_zynqmp_mini_qspi_defconfig new file mode 100644 index 0000000..8b32829 --- /dev/null +++ b/configs/xilinx_zynqmp_mini_qspi_defconfig @@ -0,0 +1,61 @@ +CONFIG_ARM=y +CONFIG_SYS_CONFIG_NAME="xilinx_zynqmp_mini_qspi" +CONFIG_ARCH_ZYNQMP=y +CONFIG_SYS_TEXT_BASE=0xFFFC0000 +CONFIG_SYS_MEM_RSVD_FOR_MMU=y +CONFIG_ZYNQMP_NO_DDR=y +# CONFIG_CMD_ZYNQMP is not set +CONFIG_DEFAULT_DEVICE_TREE="zynqmp-mini-qspi" +# CONFIG_IMAGE_FORMAT_LEGACY is not set +CONFIG_BOOTDELAY=-1 +# CONFIG_DISPLAY_CPUINFO is not set +# CONFIG_CMDLINE_EDITING is not set +# CONFIG_AUTO_COMPLETE is not set +# CONFIG_SYS_LONGHELP is not set +CONFIG_SYS_PROMPT="ZynqMP> " +# CONFIG_CMD_BDI is not set +# CONFIG_CMD_CONSOLE is not set +# CONFIG_CMD_BOOTD is not set +# CONFIG_CMD_BOOTM is not set +# CONFIG_CMD_BOOTI is not set +# CONFIG_CMD_ELF is not set +# CONFIG_CMD_FDT is not set +# CONFIG_CMD_GO is not set +# CONFIG_CMD_RUN is not set +# CONFIG_CMD_IMI is not set +# CONFIG_CMD_XIMG is not set +# CONFIG_CMD_EXPORTENV is not set +# CONFIG_CMD_IMPORTENV is not set +# CONFIG_CMD_EDITENV is not set +# CONFIG_CMD_SAVEENV is not set +# CONFIG_CMD_ENV_EXISTS is not set +# CONFIG_CMD_CRC32 is not set +# CONFIG_CMD_DM is not set +# CONFIG_CMD_FLASH is not set +# CONFIG_CMD_LOADB is not set +# CONFIG_CMD_LOADS is not set +CONFIG_CMD_SF=y +# CONFIG_CMD_ECHO is not set +# CONFIG_CMD_ITEST is not set +# CONFIG_CMD_SOURCE is not set +# CONFIG_CMD_SETEXPR is not set +# CONFIG_CMD_MISC is not set +CONFIG_MP=y +# CONFIG_PARTITIONS is not set +CONFIG_OF_EMBED=y +# CONFIG_NET is not set +# CONFIG_DM_WARN is not set +# CONFIG_DM_DEVICE_REMOVE is not set +# CONFIG_MMC is not set +CONFIG_DM_SPI_FLASH=y +CONFIG_SPI_FLASH=y +CONFIG_SPI_FLASH_BAR=y +CONFIG_SF_DUAL_FLASH=y +CONFIG_SPI_FLASH_MACRONIX=y +CONFIG_SPI_FLASH_SPANSION=y +CONFIG_SPI_FLASH_STMICRO=y +CONFIG_SPI_FLASH_WINBOND=y +CONFIG_SPI=y +CONFIG_DM_SPI=y +CONFIG_ZYNQMP_GQSPI=y +# CONFIG_EFI_LOADER is not set diff --git a/include/configs/xilinx_zynqmp_mini_qspi.h b/include/configs/xilinx_zynqmp_mini_qspi.h new file mode 100644 index 0000000..6fb0520 --- /dev/null +++ b/include/configs/xilinx_zynqmp_mini_qspi.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Configuration for Xilinx ZynqMP QSPI Flash utility + * + * (C) Copyright 2018 Xilinx, Inc. + * Michal Simek + * Siva Durga Prasad Paladugu + */ + +#ifndef __CONFIG_ZYNQMP_MINI_QSPI_H +#define __CONFIG_ZYNQMP_MINI_QSPI_H + +#include + +#define CONFIG_SYS_ICACHE_OFF +#define CONFIG_NR_DRAM_BANKS 1 +#define CONFIG_ENV_SIZE 1400 +#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_TEXT_BASE + 0x20000) +#define CONFIG_SYS_MALLOC_LEN 0x2000 + +#endif /* __CONFIG_ZYNQMP_MINI_QSPI_H */ From a133b3ac3257e471f521991e472c8f8c15d2c5a9 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Wed, 18 Jul 2018 13:07:59 +0200 Subject: [PATCH 52/55] arm64: zynqmp: Setup ENV_SIZE via Kconfig for mini targets Mini targets are using different ENV_SIZE then standard one that's why defconfigs should be updated to simplify config files. Signed-off-by: Michal Simek --- configs/xilinx_zynqmp_mini_emmc0_defconfig | 1 + configs/xilinx_zynqmp_mini_emmc1_defconfig | 1 + configs/xilinx_zynqmp_mini_nand_defconfig | 1 + configs/xilinx_zynqmp_mini_qspi_defconfig | 1 + include/configs/xilinx_zynqmp_mini.h | 1 - include/configs/xilinx_zynqmp_mini_emmc.h | 1 - include/configs/xilinx_zynqmp_mini_nand.h | 1 - include/configs/xilinx_zynqmp_mini_qspi.h | 1 - 8 files changed, 4 insertions(+), 4 deletions(-) diff --git a/configs/xilinx_zynqmp_mini_emmc0_defconfig b/configs/xilinx_zynqmp_mini_emmc0_defconfig index ffb9693..65a72b7 100644 --- a/configs/xilinx_zynqmp_mini_emmc0_defconfig +++ b/configs/xilinx_zynqmp_mini_emmc0_defconfig @@ -2,6 +2,7 @@ CONFIG_ARM=y CONFIG_SYS_CONFIG_NAME="xilinx_zynqmp_mini_emmc" CONFIG_ARCH_ZYNQMP=y CONFIG_SYS_TEXT_BASE=0x10000 +CONFIG_ENV_SIZE=0x10000 # CONFIG_CMD_ZYNQMP is not set CONFIG_DEFAULT_DEVICE_TREE="zynqmp-mini-emmc0" CONFIG_ENV_VARS_UBOOT_CONFIG=y diff --git a/configs/xilinx_zynqmp_mini_emmc1_defconfig b/configs/xilinx_zynqmp_mini_emmc1_defconfig index edca32d..c32ba73 100644 --- a/configs/xilinx_zynqmp_mini_emmc1_defconfig +++ b/configs/xilinx_zynqmp_mini_emmc1_defconfig @@ -2,6 +2,7 @@ CONFIG_ARM=y CONFIG_SYS_CONFIG_NAME="xilinx_zynqmp_mini_emmc" CONFIG_ARCH_ZYNQMP=y CONFIG_SYS_TEXT_BASE=0x10000 +CONFIG_ENV_SIZE=0x10000 # CONFIG_CMD_ZYNQMP is not set CONFIG_DEFAULT_DEVICE_TREE="zynqmp-mini-emmc1" CONFIG_ENV_VARS_UBOOT_CONFIG=y diff --git a/configs/xilinx_zynqmp_mini_nand_defconfig b/configs/xilinx_zynqmp_mini_nand_defconfig index 4c8c2fc..3117770 100644 --- a/configs/xilinx_zynqmp_mini_nand_defconfig +++ b/configs/xilinx_zynqmp_mini_nand_defconfig @@ -2,6 +2,7 @@ CONFIG_ARM=y CONFIG_SYS_CONFIG_NAME="xilinx_zynqmp_mini_nand" CONFIG_ARCH_ZYNQMP=y CONFIG_SYS_TEXT_BASE=0x10000 +CONFIG_ENV_SIZE=0x10000 # CONFIG_CMD_ZYNQMP is not set CONFIG_DEFAULT_DEVICE_TREE="zynqmp-mini-nand" CONFIG_ENV_VARS_UBOOT_CONFIG=y diff --git a/configs/xilinx_zynqmp_mini_qspi_defconfig b/configs/xilinx_zynqmp_mini_qspi_defconfig index 8b32829..a4bc895 100644 --- a/configs/xilinx_zynqmp_mini_qspi_defconfig +++ b/configs/xilinx_zynqmp_mini_qspi_defconfig @@ -2,6 +2,7 @@ CONFIG_ARM=y CONFIG_SYS_CONFIG_NAME="xilinx_zynqmp_mini_qspi" CONFIG_ARCH_ZYNQMP=y CONFIG_SYS_TEXT_BASE=0xFFFC0000 +CONFIG_ENV_SIZE=0x578 CONFIG_SYS_MEM_RSVD_FOR_MMU=y CONFIG_ZYNQMP_NO_DDR=y # CONFIG_CMD_ZYNQMP is not set diff --git a/include/configs/xilinx_zynqmp_mini.h b/include/configs/xilinx_zynqmp_mini.h index 118779a..8ba91d0 100644 --- a/include/configs/xilinx_zynqmp_mini.h +++ b/include/configs/xilinx_zynqmp_mini.h @@ -17,7 +17,6 @@ /* Undef unneeded configs */ #undef CONFIG_EXTRA_ENV_SETTINGS #undef CONFIG_SYS_MALLOC_LEN -#undef CONFIG_ENV_SIZE #undef CONFIG_ZLIB #undef CONFIG_GZIP #undef CONFIG_CMD_ENV diff --git a/include/configs/xilinx_zynqmp_mini_emmc.h b/include/configs/xilinx_zynqmp_mini_emmc.h index dc81c66..6531599 100644 --- a/include/configs/xilinx_zynqmp_mini_emmc.h +++ b/include/configs/xilinx_zynqmp_mini_emmc.h @@ -14,7 +14,6 @@ #define CONFIG_SYS_ICACHE_OFF #define CONFIG_NR_DRAM_BANKS 1 -#define CONFIG_ENV_SIZE 0x10000 #define CONFIG_SYS_INIT_SP_ADDR CONFIG_SYS_TEXT_BASE #define CONFIG_SYS_MALLOC_LEN 0x800000 diff --git a/include/configs/xilinx_zynqmp_mini_nand.h b/include/configs/xilinx_zynqmp_mini_nand.h index 4434e6a..00db449 100644 --- a/include/configs/xilinx_zynqmp_mini_nand.h +++ b/include/configs/xilinx_zynqmp_mini_nand.h @@ -16,7 +16,6 @@ #define CONFIG_NR_DRAM_BANKS 1 #define CONFIG_SYS_SDRAM_SIZE 0x1000000 #define CONFIG_SYS_SDRAM_BASE 0x0 -#define CONFIG_ENV_SIZE 0x10000 #define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_SDRAM_BASE + 0x40000) #define CONFIG_SYS_MALLOC_LEN 0x800000 diff --git a/include/configs/xilinx_zynqmp_mini_qspi.h b/include/configs/xilinx_zynqmp_mini_qspi.h index 6fb0520..2291326 100644 --- a/include/configs/xilinx_zynqmp_mini_qspi.h +++ b/include/configs/xilinx_zynqmp_mini_qspi.h @@ -14,7 +14,6 @@ #define CONFIG_SYS_ICACHE_OFF #define CONFIG_NR_DRAM_BANKS 1 -#define CONFIG_ENV_SIZE 1400 #define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_TEXT_BASE + 0x20000) #define CONFIG_SYS_MALLOC_LEN 0x2000 From 3907eef1a385e52d99d9888de078cd652548a668 Mon Sep 17 00:00:00 2001 From: Luis Araneda Date: Thu, 19 Jul 2018 03:10:16 -0400 Subject: [PATCH 53/55] spl: fit: display a message when an FPGA image is loaded A message should be displayed if an image is loaded to an FPGA, because the hardware might have changed, and the user should be informed Signed-off-by: Luis Araneda Signed-off-by: Michal Simek --- common/spl/spl_fit.c | 1 + 1 file changed, 1 insertion(+) diff --git a/common/spl/spl_fit.c b/common/spl/spl_fit.c index 5b51a28..9eabb1c 100644 --- a/common/spl/spl_fit.c +++ b/common/spl/spl_fit.c @@ -412,6 +412,7 @@ int spl_load_simple_fit(struct spl_image_info *spl_image, printf("%s: Cannot load the FPGA: %i\n", __func__, ret); return ret; } + puts("FPGA image loaded from FIT\n"); node = -1; } #endif From d600c4f6b09f75c3bb0ef588cde69cc236ec3feb Mon Sep 17 00:00:00 2001 From: Luis Araneda Date: Thu, 19 Jul 2018 03:10:17 -0400 Subject: [PATCH 54/55] drivers: fpga: zynqpl: fix compilation with SPL Disable the use of function zynq_loadfs when compiling the driver for the SPL, as the following filesystem functions are not found by the linker: - fs_set_blk_dev - fs_read - fs_set_blk_dev - fs_read - fs_read Signed-off-by: Luis Araneda Signed-off-by: Michal Simek --- drivers/fpga/zynqpl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/fpga/zynqpl.c b/drivers/fpga/zynqpl.c index 6409d30..499310d 100644 --- a/drivers/fpga/zynqpl.c +++ b/drivers/fpga/zynqpl.c @@ -411,7 +411,7 @@ static int zynq_load(xilinx_desc *desc, const void *buf, size_t bsize, return FPGA_SUCCESS; } -#if defined(CONFIG_CMD_FPGA_LOADFS) +#if defined(CONFIG_CMD_FPGA_LOADFS) && !defined(CONFIG_SPL_BUILD) static int zynq_loadfs(xilinx_desc *desc, const void *buf, size_t bsize, fpga_fs_info *fsinfo) { @@ -494,7 +494,7 @@ static int zynq_loadfs(xilinx_desc *desc, const void *buf, size_t bsize, struct xilinx_fpga_op zynq_op = { .load = zynq_load, -#if defined(CONFIG_CMD_FPGA_LOADFS) +#if defined(CONFIG_CMD_FPGA_LOADFS) && !defined(CONFIG_SPL_BUILD) .loadfs = zynq_loadfs, #endif }; From 577012da71ea9dcf07272c7f458218aa8ab29984 Mon Sep 17 00:00:00 2001 From: Luis Araneda Date: Thu, 19 Jul 2018 03:10:18 -0400 Subject: [PATCH 55/55] arm: zynq: spl: fix FPGA initialization commit 4aba5fb857c1 ("arm: zynq: Rework FPGA initialization") moved FPGA initialization from board_init() to arch_early_init_r(), which is not called as part of the SPL Fix this by calling arch_early_init_r() in the spl_board_init() function, so the FPGA is correctly initialized Signed-off-by: Luis Araneda Signed-off-by: Michal Simek --- arch/arm/mach-zynq/spl.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm/mach-zynq/spl.c b/arch/arm/mach-zynq/spl.c index 83297d6..9b7c0be 100644 --- a/arch/arm/mach-zynq/spl.c +++ b/arch/arm/mach-zynq/spl.c @@ -29,6 +29,9 @@ void board_init_f(ulong dummy) void spl_board_init(void) { preloader_console_init(); +#if defined(CONFIG_ARCH_EARLY_INIT_R) && defined(CONFIG_SPL_FPGA_SUPPORT) + arch_early_init_r(); +#endif board_init(); } #endif