aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--MAINTAINERS52
-rw-r--r--arch/arc/Kconfig18
-rw-r--r--arch/arc/config.mk3
-rw-r--r--arch/arc/include/asm/arc-bcr.h77
-rw-r--r--arch/arc/include/asm/arcregs.h11
-rw-r--r--arch/arc/include/asm/cache.h7
-rw-r--r--arch/arc/include/asm/global_data.h6
-rw-r--r--arch/arc/include/asm/io.h8
-rw-r--r--arch/arc/include/asm/string.h26
-rw-r--r--arch/arc/lib/Makefile7
-rw-r--r--arch/arc/lib/bootm.c55
-rw-r--r--arch/arc/lib/cache.c677
-rw-r--r--arch/arc/lib/init_helpers.c6
-rw-r--r--arch/arc/lib/memcmp.S123
-rw-r--r--arch/arc/lib/memcpy-700.S63
-rw-r--r--arch/arc/lib/memset.S62
-rw-r--r--arch/arc/lib/relocate.c6
-rw-r--r--arch/arc/lib/start.S28
-rw-r--r--arch/arc/lib/strchr-700.S141
-rw-r--r--arch/arc/lib/strcmp.S97
-rw-r--r--arch/arc/lib/strcpy-700.S67
-rw-r--r--arch/arc/lib/strlen.S80
-rw-r--r--arch/arm/Kconfig2
-rw-r--r--arch/arm/cpu/armv8/zynqmp/cpu.c2
-rw-r--r--arch/arm/dts/Makefile1
-rw-r--r--arch/arm/dts/zynq-zc706.dts4
-rw-r--r--arch/arm/dts/zynqmp-clk-ccf.dtsi290
-rw-r--r--arch/arm/dts/zynqmp-ep108-clk.dtsi172
-rw-r--r--arch/arm/dts/zynqmp-ep108.dts235
-rw-r--r--arch/arm/dts/zynqmp-zc1751-xm015-dc1.dts2
-rw-r--r--arch/arm/dts/zynqmp-zc1751-xm016-dc2.dts2
-rw-r--r--arch/arm/dts/zynqmp-zc1751-xm018-dc4.dts2
-rw-r--r--arch/arm/dts/zynqmp-zc1751-xm019-dc5.dts2
-rw-r--r--arch/arm/dts/zynqmp-zcu102-revA.dts2
-rw-r--r--arch/arm/include/asm/arch-zynqmp/sys_proto.h2
-rw-r--r--board/synopsys/axs10x/axs10x.c12
-rw-r--r--board/synopsys/hsdk/hsdk.c11
-rw-r--r--board/xilinx/zynq/MAINTAINERS1
-rw-r--r--board/xilinx/zynq/board.c49
-rw-r--r--board/xilinx/zynqmp/Kconfig18
-rw-r--r--board/xilinx/zynqmp/MAINTAINERS1
-rw-r--r--board/xilinx/zynqmp/Makefile4
-rw-r--r--board/xilinx/zynqmp/cmds.c105
-rw-r--r--board/xilinx/zynqmp/zynqmp.c67
-rw-r--r--common/board_f.c3
-rw-r--r--configs/microblaze-generic_defconfig2
-rw-r--r--configs/syzygy_hub_defconfig2
-rw-r--r--configs/topic_miami_defconfig2
-rw-r--r--configs/topic_miamilite_defconfig2
-rw-r--r--configs/topic_miamiplus_defconfig2
-rw-r--r--configs/xilinx_zynqmp_ep_defconfig102
-rw-r--r--configs/xilinx_zynqmp_mini_emmc_defconfig1
-rw-r--r--configs/xilinx_zynqmp_mini_nand_defconfig1
-rw-r--r--configs/xilinx_zynqmp_zc1751_xm015_dc1_defconfig3
-rw-r--r--configs/xilinx_zynqmp_zc1751_xm016_dc2_defconfig3
-rw-r--r--configs/xilinx_zynqmp_zc1751_xm018_dc4_defconfig3
-rw-r--r--configs/xilinx_zynqmp_zc1751_xm019_dc5_defconfig5
-rw-r--r--configs/xilinx_zynqmp_zcu102_rev1_0_defconfig3
-rw-r--r--configs/xilinx_zynqmp_zcu102_revA_defconfig3
-rw-r--r--configs/xilinx_zynqmp_zcu102_revB_defconfig3
-rw-r--r--configs/zynq_cc108_defconfig2
-rw-r--r--configs/zynq_cse_qspi_defconfig2
-rw-r--r--configs/zynq_microzed_defconfig2
-rw-r--r--configs/zynq_picozed_defconfig2
-rw-r--r--configs/zynq_z_turn_defconfig2
-rw-r--r--configs/zynq_zc702_defconfig2
-rw-r--r--configs/zynq_zc706_defconfig4
-rw-r--r--configs/zynq_zc770_xm010_defconfig2
-rw-r--r--configs/zynq_zc770_xm011_defconfig2
-rw-r--r--configs/zynq_zc770_xm011_x16_defconfig5
-rw-r--r--configs/zynq_zc770_xm012_defconfig2
-rw-r--r--configs/zynq_zc770_xm013_defconfig2
-rw-r--r--configs/zynq_zed_defconfig6
-rw-r--r--configs/zynq_zybo_defconfig2
-rw-r--r--drivers/clk/clk_zynq.c2
-rw-r--r--drivers/clk/clk_zynqmp.c75
-rw-r--r--drivers/fpga/fpga.c21
-rw-r--r--drivers/mtd/nand/arasan_nfc.c7
-rw-r--r--drivers/net/zynq_gem.c3
-rw-r--r--drivers/watchdog/Kconfig16
-rw-r--r--drivers/watchdog/Makefile1
-rw-r--r--drivers/watchdog/cdns_wdt.c276
-rw-r--r--include/command.h2
-rw-r--r--include/configs/xilinx_zynqmp.h4
-rw-r--r--include/configs/xilinx_zynqmp_ep.h24
-rw-r--r--include/configs/xilinx_zynqmp_mini.h2
-rw-r--r--tools/zynqimage.c6
-rw-r--r--tools/zynqmpimage.c2
88 files changed, 1665 insertions, 1559 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 6c7f3ae2a5..7cc3b06c44 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -245,14 +245,50 @@ N: uniphier
ARM ZYNQ
M: Michal Simek <monstr@monstr.eu>
S: Maintained
-F: arch/arm/cpu/armv7/zynq/
-F: arch/arm/include/asm/arch-zynq/
+T: git git://git.denx.de/u-boot-microblaze.git
+F: arch/arm/mach-zynq/
+F: drivers/clk/clk_zynq.c
+F: drivers/fpga/zynqpl.c
+F: drivers/gpio/zynq_gpio.c
+F: drivers/i2c/i2c-cdns.c
+F: drivers/i2c/muxes/pca954x.c
+F: drivers/i2c/zynq_i2c.c
+F: drivers/mmc/zynq_sdhci.c
+F: drivers/mtd/nand/zynq_nand.c
+F: drivers/net/phy/xilinx_phy.c
+F: drivers/net/zynq_gem.c
+F: drivers/serial/serial_zynq.c
+F: drivers/spi/zynq_qspi.c
+F: drivers/spi/zynq_spi.c
+F: drivers/usb/host/ehci-zynq.c
+F: drivers/watchdog/cdns_wdt.c
+F: include/zynqmp.h
+F: tools/zynqimage.c
+N: zynq
ARM ZYNQMP
M: Michal Simek <michal.simek@xilinx.com>
S: Maintained
-F: arch/arm/cpu/armv8/zynqmp/
-F: arch/arm/include/asm/arch-zynqmp/
+T: git git://git.denx.de/u-boot-microblaze.git
+F: arch/arm/mach-zynq/
+F: drivers/clk/clk_zynq.c
+F: drivers/fpga/zynqpl.c
+F: drivers/gpio/zynq_gpio.c
+F: drivers/i2c/i2c-cdns.c
+F: drivers/i2c/muxes/pca954x.c
+F: drivers/i2c/zynq_i2c.c
+F: drivers/mmc/zynq_sdhci.c
+F: drivers/mtd/nand/zynq_nand.c
+F: drivers/net/phy/xilinx_phy.c
+F: drivers/net/zynq_gem.c
+F: drivers/serial/serial_zynq.c
+F: drivers/spi/zynq_qspi.c
+F: drivers/spi/zynq_spi.c
+F: drivers/usb/host/ehci-zynq.c
+F: drivers/watchdog/cdns_wdt.c
+F: include/zynqmp.h
+F: tools/zynqimage.c
+N: zynqmp
BUILDMAN
M: Simon Glass <sjg@chromium.org>
@@ -343,6 +379,14 @@ M: Michal Simek <monstr@monstr.eu>
S: Maintained
T: git git://git.denx.de/u-boot-microblaze.git
F: arch/microblaze/
+F: cmd/mfsl.c
+F: drivers/gpio/xilinx_gpio.c
+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/watchdog/xilinx_tb_wdt.c
+N: xilinx
MIPS
M: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig
index e3f9db7b29..aee15d5353 100644
--- a/arch/arc/Kconfig
+++ b/arch/arc/Kconfig
@@ -116,6 +116,24 @@ config SYS_DCACHE_OFF
bool "Do not use Data Cache"
default n
+menuconfig ARC_DBG
+ bool "ARC debugging"
+ default n
+
+if ARC_DBG
+
+config ARC_DBG_IOC_ENABLE
+ bool "Enable IO coherency unit"
+ depends on CPU_ARCHS38
+ default n
+ help
+ Enable IO coherency unit to debug problems with caches and
+ DMA peripherals.
+ NOTE: as of today linux will not work properly if this option
+ is enabled in u-boot!
+
+endif
+
choice
prompt "Target select"
default TARGET_AXS103
diff --git a/arch/arc/config.mk b/arch/arc/config.mk
index 3ed0c282ba..d040454d1a 100644
--- a/arch/arc/config.mk
+++ b/arch/arc/config.mk
@@ -51,9 +51,10 @@ PLATFORM_CPPFLAGS += -mcpu=archs
endif
PLATFORM_CPPFLAGS += -ffixed-r25 -D__ARC__ -gdwarf-2 -mno-sdata
+PLATFORM_RELFLAGS += -ffunction-sections -fdata-sections
# Needed for relocation
-LDFLAGS_FINAL += -pie
+LDFLAGS_FINAL += -pie --gc-sections
# Load address for standalone apps
CONFIG_STANDALONE_LOAD_ADDR ?= 0x82000000
diff --git a/arch/arc/include/asm/arc-bcr.h b/arch/arc/include/asm/arc-bcr.h
new file mode 100644
index 0000000000..823906d946
--- /dev/null
+++ b/arch/arc/include/asm/arc-bcr.h
@@ -0,0 +1,77 @@
+/*
+ * ARC Build Configuration Registers, with encoded hardware config
+ *
+ * Copyright (C) 2018 Synopsys
+ * Author: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __ARC_BCR_H
+#define __ARC_BCR_H
+#ifndef __ASSEMBLY__
+
+#include <config.h>
+
+union bcr_di_cache {
+ struct {
+#ifdef CONFIG_CPU_BIG_ENDIAN
+ unsigned int pad:12, line_len:4, sz:4, config:4, ver:8;
+#else
+ unsigned int ver:8, config:4, sz:4, line_len:4, pad:12;
+#endif
+ } fields;
+ unsigned int word;
+};
+
+union bcr_slc_cfg {
+ struct {
+#ifdef CONFIG_CPU_BIG_ENDIAN
+ unsigned int pad:24, way:2, lsz:2, sz:4;
+#else
+ unsigned int sz:4, lsz:2, way:2, pad:24;
+#endif
+ } fields;
+ unsigned int word;
+};
+
+union bcr_generic {
+ struct {
+#ifdef CONFIG_CPU_BIG_ENDIAN
+ unsigned int pad:24, ver:8;
+#else
+ unsigned int ver:8, pad:24;
+#endif
+ } fields;
+ unsigned int word;
+};
+
+union bcr_clust_cfg {
+ struct {
+#ifdef CONFIG_CPU_BIG_ENDIAN
+ unsigned int pad:7, c:1, num_entries:8, num_cores:8, ver:8;
+#else
+ unsigned int ver:8, num_cores:8, num_entries:8, c:1, pad:7;
+#endif
+ } fields;
+ unsigned int word;
+};
+
+union bcr_mmu_4 {
+ struct {
+#ifdef CONFIG_CPU_BIG_ENDIAN
+ unsigned int ver:8, sasid:1, sz1:4, sz0:4, res:2, pae:1,
+ n_ways:2, n_entry:2, n_super:2, u_itlb:3, u_dtlb:3;
+#else
+ /* DTLB ITLB JES JE JA */
+ unsigned int u_dtlb:3, u_itlb:3, n_super:2, n_entry:2, n_ways:2,
+ pae:1, res:2, sz0:4, sz1:4, sasid:1, ver:8;
+#endif
+ } fields;
+ unsigned int word;
+};
+
+#endif /* __ASSEMBLY__ */
+#endif /* __ARC_BCR_H */
diff --git a/arch/arc/include/asm/arcregs.h b/arch/arc/include/asm/arcregs.h
index 67f416305d..3a513149f5 100644
--- a/arch/arc/include/asm/arcregs.h
+++ b/arch/arc/include/asm/arcregs.h
@@ -8,6 +8,7 @@
#define _ASM_ARC_ARCREGS_H
#include <asm/cache.h>
+#include <config.h>
/*
* ARC architecture has additional address space - auxiliary registers.
@@ -88,6 +89,16 @@
/* ARCNUM [15:8] - field to identify each core in a multi-core system */
#define CPU_ID_GET() ((read_aux_reg(ARC_AUX_IDENTITY) & 0xFF00) >> 8)
+
+static const inline int is_isa_arcv2(void)
+{
+ return IS_ENABLED(CONFIG_ISA_ARCV2);
+}
+
+static const inline int is_isa_arcompact(void)
+{
+ return IS_ENABLED(CONFIG_ISA_ARCOMPACT);
+}
#endif /* __ASSEMBLY__ */
#endif /* _ASM_ARC_ARCREGS_H */
diff --git a/arch/arc/include/asm/cache.h b/arch/arc/include/asm/cache.h
index d26d9fb18d..2269183615 100644
--- a/arch/arc/include/asm/cache.h
+++ b/arch/arc/include/asm/cache.h
@@ -30,6 +30,13 @@
#ifndef __ASSEMBLY__
void cache_init(void);
+void flush_n_invalidate_dcache_all(void);
+void sync_n_cleanup_cache_all(void);
+
+static const inline int is_ioc_enabled(void)
+{
+ return IS_ENABLED(CONFIG_ARC_DBG_IOC_ENABLE);
+}
#endif /* __ASSEMBLY__ */
diff --git a/arch/arc/include/asm/global_data.h b/arch/arc/include/asm/global_data.h
index f0242f1ad6..43e1343095 100644
--- a/arch/arc/include/asm/global_data.h
+++ b/arch/arc/include/asm/global_data.h
@@ -7,9 +7,15 @@
#ifndef __ASM_ARC_GLOBAL_DATA_H
#define __ASM_ARC_GLOBAL_DATA_H
+#include <config.h>
+
#ifndef __ASSEMBLY__
/* Architecture-specific global data */
struct arch_global_data {
+ int l1_line_sz;
+#if defined(CONFIG_ISA_ARCV2)
+ int slc_line_sz;
+#endif
};
#endif /* __ASSEMBLY__ */
diff --git a/arch/arc/include/asm/io.h b/arch/arc/include/asm/io.h
index a12303bc73..060cdf637b 100644
--- a/arch/arc/include/asm/io.h
+++ b/arch/arc/include/asm/io.h
@@ -10,7 +10,7 @@
#include <linux/types.h>
#include <asm/byteorder.h>
-#ifdef CONFIG_ISA_ARCV2
+#ifdef __ARCHS__
/*
* ARCv2 based HS38 cores are in-order issue, but still weakly ordered
@@ -42,12 +42,12 @@
#define mb() asm volatile("sync\n" : : : "memory")
#endif
-#ifdef CONFIG_ISA_ARCV2
+#ifdef __ARCHS__
#define __iormb() rmb()
#define __iowmb() wmb()
#else
-#define __iormb() do { } while (0)
-#define __iowmb() do { } while (0)
+#define __iormb() asm volatile("" : : : "memory")
+#define __iowmb() asm volatile("" : : : "memory")
#endif
static inline void sync(void)
diff --git a/arch/arc/include/asm/string.h b/arch/arc/include/asm/string.h
index 909129c333..8b13789179 100644
--- a/arch/arc/include/asm/string.h
+++ b/arch/arc/include/asm/string.h
@@ -1,27 +1 @@
-/*
- * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. All rights reserved.
- *
- * SPDX-License-Identifier: GPL-2.0+
- */
-#ifndef __ASM_ARC_STRING_H
-#define __ASM_ARC_STRING_H
-
-#define __HAVE_ARCH_MEMSET
-#define __HAVE_ARCH_MEMCPY
-#define __HAVE_ARCH_MEMCMP
-#define __HAVE_ARCH_STRCHR
-#define __HAVE_ARCH_STRCPY
-#define __HAVE_ARCH_STRCMP
-#define __HAVE_ARCH_STRLEN
-
-extern void *memset(void *ptr, int, __kernel_size_t);
-extern void *memcpy(void *, const void *, __kernel_size_t);
-extern void memzero(void *ptr, __kernel_size_t n);
-extern int memcmp(const void *, const void *, __kernel_size_t);
-extern char *strchr(const char *s, int c);
-extern char *strcpy(char *dest, const char *src);
-extern int strcmp(const char *cs, const char *ct);
-extern __kernel_size_t strlen(const char *);
-
-#endif /* __ASM_ARC_STRING_H */
diff --git a/arch/arc/lib/Makefile b/arch/arc/lib/Makefile
index 12097bf3be..6b7fb0fdff 100644
--- a/arch/arc/lib/Makefile
+++ b/arch/arc/lib/Makefile
@@ -10,13 +10,6 @@ obj-y += cache.o
obj-y += cpu.o
obj-y += interrupts.o
obj-y += relocate.o
-obj-y += strchr-700.o
-obj-y += strcmp.o
-obj-y += strcpy-700.o
-obj-y += strlen.o
-obj-y += memcmp.o
-obj-y += memcpy-700.o
-obj-y += memset.o
obj-y += reset.o
obj-y += ints_low.o
obj-y += init_helpers.o
diff --git a/arch/arc/lib/bootm.c b/arch/arc/lib/bootm.c
index 4d4acff239..4f04aad34a 100644
--- a/arch/arc/lib/bootm.c
+++ b/arch/arc/lib/bootm.c
@@ -4,6 +4,7 @@
* SPDX-License-Identifier: GPL-2.0+
*/
+#include <asm/cache.h>
#include <common.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -40,41 +41,52 @@ void arch_lmb_reserve(struct lmb *lmb)
static int cleanup_before_linux(void)
{
disable_interrupts();
- flush_dcache_all();
- invalidate_icache_all();
+ sync_n_cleanup_cache_all();
return 0;
}
+__weak int board_prep_linux(bootm_headers_t *images) { return 0; }
+
/* Subcommand: PREP */
-static void boot_prep_linux(bootm_headers_t *images)
+static int boot_prep_linux(bootm_headers_t *images)
{
- if (image_setup_linux(images))
- hang();
+ int ret;
+
+ ret = image_setup_linux(images);
+ if (ret)
+ return ret;
+
+ return board_prep_linux(images);
}
-__weak void smp_set_core_boot_addr(unsigned long addr, int corenr) {}
-__weak void smp_kick_all_cpus(void) {}
+/* Generic implementation for single core CPU */
+__weak void board_jump_and_run(ulong entry, int zero, int arch, uint params)
+{
+ void (*kernel_entry)(int zero, int arch, uint params);
+
+ kernel_entry = (void (*)(int, int, uint))entry;
+
+ kernel_entry(zero, arch, params);
+}
/* Subcommand: GO */
static void boot_jump_linux(bootm_headers_t *images, int flag)
{
- void (*kernel_entry)(int zero, int arch, uint params);
+ ulong kernel_entry;
unsigned int r0, r2;
int fake = (flag & BOOTM_STATE_OS_FAKE_GO);
- kernel_entry = (void (*)(int, int, uint))images->ep;
+ kernel_entry = images->ep;
debug("## Transferring control to Linux (at address %08lx)...\n",
- (ulong) kernel_entry);
+ kernel_entry);
bootstage_mark(BOOTSTAGE_ID_RUN_OS);
printf("\nStarting kernel ...%s\n\n", fake ?
"(fake run for tracing)" : "");
bootstage_mark_name(BOOTSTAGE_ID_BOOTM_HANDOFF, "start_kernel");
- cleanup_before_linux();
-
if (IMAGE_ENABLE_OF_LIBFDT && images->ft_len) {
r0 = 2;
r2 = (unsigned int)images->ft_addr;
@@ -83,11 +95,10 @@ static void boot_jump_linux(bootm_headers_t *images, int flag)
r2 = (unsigned int)env_get("bootargs");
}
- if (!fake) {
- smp_set_core_boot_addr((unsigned long)kernel_entry, -1);
- smp_kick_all_cpus();
- kernel_entry(r0, 0, r2);
- }
+ cleanup_before_linux();
+
+ if (!fake)
+ board_jump_and_run(kernel_entry, r0, 0, r2);
}
int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images)
@@ -96,17 +107,13 @@ int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images)
if ((flag & BOOTM_STATE_OS_BD_T) || (flag & BOOTM_STATE_OS_CMDLINE))
return -1;
- if (flag & BOOTM_STATE_OS_PREP) {
- boot_prep_linux(images);
- return 0;
- }
+ if (flag & BOOTM_STATE_OS_PREP)
+ return boot_prep_linux(images);
if (flag & (BOOTM_STATE_OS_GO | BOOTM_STATE_OS_FAKE_GO)) {
boot_jump_linux(images, flag);
return 0;
}
- boot_prep_linux(images);
- boot_jump_linux(images, flag);
- return 0;
+ return -1;
}
diff --git a/arch/arc/lib/cache.c b/arch/arc/lib/cache.c
index 04f1d9d59b..8203fae145 100644
--- a/arch/arc/lib/cache.c
+++ b/arch/arc/lib/cache.c
@@ -10,8 +10,145 @@
#include <linux/kernel.h>
#include <linux/log2.h>
#include <asm/arcregs.h>
+#include <asm/arc-bcr.h>
#include <asm/cache.h>
+/*
+ * [ NOTE 1 ]:
+ * Data cache (L1 D$ or SL$) entire invalidate operation or data cache disable
+ * operation may result in unexpected behavior and data loss even if we flush
+ * data cache right before invalidation. That may happens if we store any context
+ * on stack (like we store BLINK register on stack before function call).
+ * BLINK register is the register where return address is automatically saved
+ * when we do function call with instructions like 'bl'.
+ *
+ * There is the real example:
+ * We may hang in the next code as we store any BLINK register on stack in
+ * invalidate_dcache_all() function.
+ *
+ * void flush_dcache_all() {
+ * __dc_entire_op(OP_FLUSH);
+ * // Other code //
+ * }
+ *
+ * void invalidate_dcache_all() {
+ * __dc_entire_op(OP_INV);
+ * // Other code //
+ * }
+ *
+ * void foo(void) {
+ * flush_dcache_all();
+ * invalidate_dcache_all();
+ * }
+ *
+ * Now let's see what really happens during that code execution:
+ *
+ * foo()
+ * |->> call flush_dcache_all
+ * [return address is saved to BLINK register]
+ * [push BLINK] (save to stack) ![point 1]
+ * |->> call __dc_entire_op(OP_FLUSH)
+ * [return address is saved to BLINK register]
+ * [flush L1 D$]
+ * return [jump to BLINK]
+ * <<------
+ * [other flush_dcache_all code]
+ * [pop BLINK] (get from stack)
+ * return [jump to BLINK]
+ * <<------
+ * |->> call invalidate_dcache_all
+ * [return address is saved to BLINK register]
+ * [push BLINK] (save to stack) ![point 2]
+ * |->> call __dc_entire_op(OP_FLUSH)
+ * [return address is saved to BLINK register]
+ * [invalidate L1 D$] ![point 3]
+ * // Oops!!!
+ * // We lose return address from invalidate_dcache_all function:
+ * // we save it to stack and invalidate L1 D$ after that!
+ * return [jump to BLINK]
+ * <<------
+ * [other invalidate_dcache_all code]
+ * [pop BLINK] (get from stack)
+ * // we don't have this data in L1 dcache as we invalidated it in [point 3]
+ * // so we get it from next memory level (for example DDR memory)
+ * // but in the memory we have value which we save in [point 1], which
+ * // is return address from flush_dcache_all function (instead of
+ * // address from current invalidate_dcache_all function which we
+ * // saved in [point 2] !)
+ * return [jump to BLINK]
+ * <<------
+ * // As BLINK points to invalidate_dcache_all, we call it again and
+ * // loop forever.
+ *
+ * Fortunately we may fix that by using flush & invalidation of D$ with a single
+ * one instruction (instead of flush and invalidation instructions pair) and
+ * enabling force function inline with '__attribute__((always_inline))' gcc
+ * attribute to avoid any function call (and BLINK store) between cache flush
+ * and disable.
+ *
+ *
+ * [ NOTE 2 ]:
+ * As of today we only support the following cache configurations on ARC.
+ * Other configurations may exist in HW (for example, since version 3.0 HS
+ * supports SL$ (L2 system level cache) disable) but we don't support it in SW.
+ * Configuration 1:
+ * ______________________
+ * | |
+ * | ARC CPU |
+ * |______________________|
+ * ___|___ ___|___
+ * | | | |
+ * | L1 I$ | | L1 D$ |
+ * |_______| |_______|
+ * on/off on/off
+ * ___|______________|____
+ * | |
+ * | main memory |
+ * |______________________|
+ *
+ * Configuration 2:
+ * ______________________
+ * | |
+ * | ARC CPU |
+ * |______________________|
+ * ___|___ ___|___
+ * | | | |
+ * | L1 I$ | | L1 D$ |
+ * |_______| |_______|
+ * on/off on/off
+ * ___|______________|____
+ * | |
+ * | L2 (SL$) |
+ * |______________________|
+ * always must be on
+ * ___|______________|____
+ * | |
+ * | main memory |
+ * |______________________|
+ *
+ * Configuration 3:
+ * ______________________
+ * | |
+ * | ARC CPU |
+ * |______________________|
+ * ___|___ ___|___
+ * | | | |
+ * | L1 I$ | | L1 D$ |
+ * |_______| |_______|
+ * on/off must be on
+ * ___|______________|____ _______
+ * | | | |
+ * | L2 (SL$) |-----| IOC |
+ * |______________________| |_______|
+ * always must be on on/off
+ * ___|______________|____
+ * | |
+ * | main memory |
+ * |______________________|
+ */
+
+DECLARE_GLOBAL_DATA_PTR;
+
/* Bit values in IC_CTRL */
#define IC_CTRL_CACHE_DISABLE BIT(0)
@@ -19,11 +156,10 @@
#define DC_CTRL_CACHE_DISABLE BIT(0)
#define DC_CTRL_INV_MODE_FLUSH BIT(6)
#define DC_CTRL_FLUSH_STATUS BIT(8)
-#define CACHE_VER_NUM_MASK 0xF
-#define OP_INV 0x1
-#define OP_FLUSH 0x2
-#define OP_INV_IC 0x3
+#define OP_INV BIT(0)
+#define OP_FLUSH BIT(1)
+#define OP_FLUSH_N_INV (OP_FLUSH | OP_INV)
/* Bit val in SLC_CONTROL */
#define SLC_CTRL_DIS 0x001
@@ -31,55 +167,117 @@
#define SLC_CTRL_BUSY 0x100
#define SLC_CTRL_RGN_OP_INV 0x200
+#define CACHE_LINE_MASK (~(gd->arch.l1_line_sz - 1))
+
/*
- * By default that variable will fall into .bss section.
- * But .bss section is not relocated and so it will be initilized before
- * relocation but will be used after being zeroed.
+ * We don't want to use '__always_inline' macro here as it can be redefined
+ * to simple 'inline' in some cases which breaks stuff. See [ NOTE 1 ] for more
+ * details about the reasons we need to use always_inline functions.
*/
-int l1_line_sz __section(".data");
-bool dcache_exists __section(".data") = false;
-bool icache_exists __section(".data") = false;
-
-#define CACHE_LINE_MASK (~(l1_line_sz - 1))
-
-#ifdef CONFIG_ISA_ARCV2
-int slc_line_sz __section(".data");
-bool slc_exists __section(".data") = false;
-bool ioc_exists __section(".data") = false;
-bool pae_exists __section(".data") = false;
+#define inlined_cachefunc inline __attribute__((always_inline))
-/* To force enable IOC set ioc_enable to 'true' */
-bool ioc_enable __section(".data") = false;
+static inlined_cachefunc void __ic_entire_invalidate(void);
+static inlined_cachefunc void __dc_entire_op(const int cacheop);
-void read_decode_mmu_bcr(void)
+static inline bool pae_exists(void)
{
/* TODO: should we compare mmu version from BCR and from CONFIG? */
#if (CONFIG_ARC_MMU_VER >= 4)
- u32 tmp;
+ union bcr_mmu_4 mmu4;
- tmp = read_aux_reg(ARC_AUX_MMU_BCR);
+ mmu4.word = read_aux_reg(ARC_AUX_MMU_BCR);
- struct bcr_mmu_4 {
-#ifdef CONFIG_CPU_BIG_ENDIAN
- unsigned int ver:8, sasid:1, sz1:4, sz0:4, res:2, pae:1,
- n_ways:2, n_entry:2, n_super:2, u_itlb:3, u_dtlb:3;
-#else
- /* DTLB ITLB JES JE JA */
- unsigned int u_dtlb:3, u_itlb:3, n_super:2, n_entry:2, n_ways:2,
- pae:1, res:2, sz0:4, sz1:4, sasid:1, ver:8;
-#endif /* CONFIG_CPU_BIG_ENDIAN */
- } *mmu4;
+ if (mmu4.fields.pae)
+ return true;
+#endif /* (CONFIG_ARC_MMU_VER >= 4) */
- mmu4 = (struct bcr_mmu_4 *)&tmp;
+ return false;
+}
- pae_exists = !!mmu4->pae;
-#endif /* (CONFIG_ARC_MMU_VER >= 4) */
+static inlined_cachefunc bool icache_exists(void)
+{
+ union bcr_di_cache ibcr;
+
+ ibcr.word = read_aux_reg(ARC_BCR_IC_BUILD);
+ return !!ibcr.fields.ver;
}
-static void __slc_entire_op(const int op)
+static inlined_cachefunc bool icache_enabled(void)
+{
+ if (!icache_exists())
+ return false;
+
+ return !(read_aux_reg(ARC_AUX_IC_CTRL) & IC_CTRL_CACHE_DISABLE);
+}
+
+static inlined_cachefunc bool dcache_exists(void)
+{
+ union bcr_di_cache dbcr;
+
+ dbcr.word = read_aux_reg(ARC_BCR_DC_BUILD);
+ return !!dbcr.fields.ver;
+}
+
+static inlined_cachefunc bool dcache_enabled(void)
+{
+ if (!dcache_exists())
+ return false;
+
+ return !(read_aux_reg(ARC_AUX_DC_CTRL) & DC_CTRL_CACHE_DISABLE);
+}
+
+static inlined_cachefunc bool slc_exists(void)
+{
+ if (is_isa_arcv2()) {
+ union bcr_generic sbcr;
+
+ sbcr.word = read_aux_reg(ARC_BCR_SLC);
+ return !!sbcr.fields.ver;
+ }
+
+ return false;
+}
+
+static inlined_cachefunc bool slc_data_bypass(void)
+{
+ /*
+ * If L1 data cache is disabled SL$ is bypassed and all load/store
+ * requests are sent directly to main memory.
+ */
+ return !dcache_enabled();
+}
+
+static inline bool ioc_exists(void)
+{
+ if (is_isa_arcv2()) {
+ union bcr_clust_cfg cbcr;
+
+ cbcr.word = read_aux_reg(ARC_BCR_CLUSTER);
+ return cbcr.fields.c;
+ }
+
+ return false;
+}
+
+static inline bool ioc_enabled(void)
+{
+ /*
+ * We check only CONFIG option instead of IOC HW state check as IOC
+ * must be disabled by default.
+ */
+ if (is_ioc_enabled())
+ return ioc_exists();
+
+ return false;
+}
+
+static inlined_cachefunc void __slc_entire_op(const int op)
{
unsigned int ctrl;
+ if (!slc_exists())
+ return;
+
ctrl = read_aux_reg(ARC_AUX_SLC_CTRL);
if (!(op & OP_FLUSH)) /* i.e. OP_INV */
@@ -104,6 +302,14 @@ static void __slc_entire_op(const int op)
static void slc_upper_region_init(void)
{
/*
+ * ARC_AUX_SLC_RGN_START1 and ARC_AUX_SLC_RGN_END1 register exist
+ * only if PAE exists in current HW. So we had to check pae_exist
+ * before using them.
+ */
+ if (!pae_exists())
+ return;
+
+ /*
* ARC_AUX_SLC_RGN_END1 and ARC_AUX_SLC_RGN_START1 are always == 0
* as we don't use PAE40.
*/
@@ -113,9 +319,14 @@ static void slc_upper_region_init(void)
static void __slc_rgn_op(unsigned long paddr, unsigned long sz, const int op)
{
+#ifdef CONFIG_ISA_ARCV2
+
unsigned int ctrl;
unsigned long end;
+ if (!slc_exists())
+ return;
+
/*
* The Region Flush operation is specified by CTRL.RGN_OP[11..9]
* - b'000 (default) is Flush,
@@ -142,7 +353,7 @@ static void __slc_rgn_op(unsigned long paddr, unsigned long sz, const int op)
* END needs to be setup before START (latter triggers the operation)
* END can't be same as START, so add (l2_line_sz - 1) to sz
*/
- end = paddr + sz + slc_line_sz - 1;
+ end = paddr + sz + gd->arch.slc_line_sz - 1;
/*
* Upper addresses (ARC_AUX_SLC_RGN_END1 and ARC_AUX_SLC_RGN_START1)
@@ -156,85 +367,82 @@ static void __slc_rgn_op(unsigned long paddr, unsigned long sz, const int op)
read_aux_reg(ARC_AUX_SLC_CTRL);
while (read_aux_reg(ARC_AUX_SLC_CTRL) & SLC_CTRL_BUSY);
-}
+
#endif /* CONFIG_ISA_ARCV2 */
+}
+
+static void arc_ioc_setup(void)
+{
+ /* IOC Aperture start is equal to DDR start */
+ unsigned int ap_base = CONFIG_SYS_SDRAM_BASE;
+ /* IOC Aperture size is equal to DDR size */
+ long ap_size = CONFIG_SYS_SDRAM_SIZE;
+
+ /* Unsupported configuration. See [ NOTE 2 ] for more details. */
+ if (!slc_exists())
+ panic("Try to enable IOC but SLC is not present");
+
+ /* Unsupported configuration. See [ NOTE 2 ] for more details. */
+ if (!dcache_enabled())
+ panic("Try to enable IOC but L1 D$ is disabled");
+
+ if (!is_power_of_2(ap_size) || ap_size < 4096)
+ panic("IOC Aperture size must be power of 2 and bigger 4Kib");
+
+ /* IOC Aperture start must be aligned to the size of the aperture */
+ if (ap_base % ap_size != 0)
+ panic("IOC Aperture start must be aligned to the size of the aperture");
+
+ flush_n_invalidate_dcache_all();
+
+ /*
+ * IOC Aperture size decoded as 2 ^ (SIZE + 2) KB,
+ * so setting 0x11 implies 512M, 0x12 implies 1G...
+ */
+ write_aux_reg(ARC_AUX_IO_COH_AP0_SIZE,
+ order_base_2(ap_size / 1024) - 2);
+
+ write_aux_reg(ARC_AUX_IO_COH_AP0_BASE, ap_base >> 12);
+ write_aux_reg(ARC_AUX_IO_COH_PARTIAL, 1);
+ write_aux_reg(ARC_AUX_IO_COH_ENABLE, 1);
+}
-#ifdef CONFIG_ISA_ARCV2
static void read_decode_cache_bcr_arcv2(void)
{
- union {
- struct {
-#ifdef CONFIG_CPU_BIG_ENDIAN
- unsigned int pad:24, way:2, lsz:2, sz:4;
-#else
- unsigned int sz:4, lsz:2, way:2, pad:24;
-#endif
- } fields;
- unsigned int word;
- } slc_cfg;
-
- union {
- struct {
-#ifdef CONFIG_CPU_BIG_ENDIAN
- unsigned int pad:24, ver:8;
-#else
- unsigned int ver:8, pad:24;
-#endif
- } fields;
- unsigned int word;
- } sbcr;
+#ifdef CONFIG_ISA_ARCV2
- sbcr.word = read_aux_reg(ARC_BCR_SLC);
- if (sbcr.fields.ver) {
+ union bcr_slc_cfg slc_cfg;
+
+ if (slc_exists()) {
slc_cfg.word = read_aux_reg(ARC_AUX_SLC_CONFIG);
- slc_exists = true;
- slc_line_sz = (slc_cfg.fields.lsz == 0) ? 128 : 64;
- }
+ gd->arch.slc_line_sz = (slc_cfg.fields.lsz == 0) ? 128 : 64;
- union {
- struct bcr_clust_cfg {
-#ifdef CONFIG_CPU_BIG_ENDIAN
- unsigned int pad:7, c:1, num_entries:8, num_cores:8, ver:8;
-#else
- unsigned int ver:8, num_cores:8, num_entries:8, c:1, pad:7;
-#endif
- } fields;
- unsigned int word;
- } cbcr;
+ /*
+ * We don't support configuration where L1 I$ or L1 D$ is
+ * absent but SL$ exists. See [ NOTE 2 ] for more details.
+ */
+ if (!icache_exists() || !dcache_exists())
+ panic("Unsupported cache configuration: SLC exists but one of L1 caches is absent");
+ }
- cbcr.word = read_aux_reg(ARC_BCR_CLUSTER);
- if (cbcr.fields.c && ioc_enable)
- ioc_exists = true;
+#endif /* CONFIG_ISA_ARCV2 */
}
-#endif
void read_decode_cache_bcr(void)
{
int dc_line_sz = 0, ic_line_sz = 0;
-
- union {
- struct {
-#ifdef CONFIG_CPU_BIG_ENDIAN
- unsigned int pad:12, line_len:4, sz:4, config:4, ver:8;
-#else
- unsigned int ver:8, config:4, sz:4, line_len:4, pad:12;
-#endif
- } fields;
- unsigned int word;
- } ibcr, dbcr;
+ union bcr_di_cache ibcr, dbcr;
ibcr.word = read_aux_reg(ARC_BCR_IC_BUILD);
if (ibcr.fields.ver) {
- icache_exists = true;
- l1_line_sz = ic_line_sz = 8 << ibcr.fields.line_len;
+ gd->arch.l1_line_sz = ic_line_sz = 8 << ibcr.fields.line_len;
if (!ic_line_sz)
panic("Instruction exists but line length is 0\n");
}
dbcr.word = read_aux_reg(ARC_BCR_DC_BUILD);
if (dbcr.fields.ver) {
- dcache_exists = true;
- l1_line_sz = dc_line_sz = 16 << dbcr.fields.line_len;
+ gd->arch.l1_line_sz = dc_line_sz = 16 << dbcr.fields.line_len;
if (!dc_line_sz)
panic("Data cache exists but line length is 0\n");
}
@@ -247,109 +455,79 @@ void cache_init(void)
{
read_decode_cache_bcr();
-#ifdef CONFIG_ISA_ARCV2
- read_decode_cache_bcr_arcv2();
-
- if (ioc_exists) {
- /* IOC Aperture start is equal to DDR start */
- unsigned int ap_base = CONFIG_SYS_SDRAM_BASE;
- /* IOC Aperture size is equal to DDR size */
- long ap_size = CONFIG_SYS_SDRAM_SIZE;
-
- flush_dcache_all();
- invalidate_dcache_all();
+ if (is_isa_arcv2())
+ read_decode_cache_bcr_arcv2();
- if (!is_power_of_2(ap_size) || ap_size < 4096)
- panic("IOC Aperture size must be power of 2 and bigger 4Kib");
-
- /*
- * IOC Aperture size decoded as 2 ^ (SIZE + 2) KB,
- * so setting 0x11 implies 512M, 0x12 implies 1G...
- */
- write_aux_reg(ARC_AUX_IO_COH_AP0_SIZE,
- order_base_2(ap_size / 1024) - 2);
-
- /* IOC Aperture start must be aligned to the size of the aperture */
- if (ap_base % ap_size != 0)
- panic("IOC Aperture start must be aligned to the size of the aperture");
-
- write_aux_reg(ARC_AUX_IO_COH_AP0_BASE, ap_base >> 12);
- write_aux_reg(ARC_AUX_IO_COH_PARTIAL, 1);
- write_aux_reg(ARC_AUX_IO_COH_ENABLE, 1);
- }
+ if (is_isa_arcv2() && ioc_enabled())
+ arc_ioc_setup();
- read_decode_mmu_bcr();
-
- /*
- * ARC_AUX_SLC_RGN_START1 and ARC_AUX_SLC_RGN_END1 register exist
- * only if PAE exists in current HW. So we had to check pae_exist
- * before using them.
- */
- if (slc_exists && pae_exists)
+ if (is_isa_arcv2() && slc_exists())
slc_upper_region_init();
-#endif /* CONFIG_ISA_ARCV2 */
}
int icache_status(void)
{
- if (!icache_exists)
- return 0;
-
- if (read_aux_reg(ARC_AUX_IC_CTRL) & IC_CTRL_CACHE_DISABLE)
- return 0;
- else
- return 1;
+ return icache_enabled();
}
void icache_enable(void)
{
- if (icache_exists)
+ if (icache_exists())
write_aux_reg(ARC_AUX_IC_CTRL, read_aux_reg(ARC_AUX_IC_CTRL) &
~IC_CTRL_CACHE_DISABLE);
}
void icache_disable(void)
{
- if (icache_exists)
- write_aux_reg(ARC_AUX_IC_CTRL, read_aux_reg(ARC_AUX_IC_CTRL) |
- IC_CTRL_CACHE_DISABLE);
+ if (!icache_exists())
+ return;
+
+ __ic_entire_invalidate();
+
+ write_aux_reg(ARC_AUX_IC_CTRL, read_aux_reg(ARC_AUX_IC_CTRL) |
+ IC_CTRL_CACHE_DISABLE);
}
-void invalidate_icache_all(void)
+/* IC supports only invalidation */
+static inlined_cachefunc void __ic_entire_invalidate(void)
{
+ if (!icache_enabled())
+ return;
+
/* Any write to IC_IVIC register triggers invalidation of entire I$ */
- if (icache_status()) {
- write_aux_reg(ARC_AUX_IC_IVIC, 1);
- /*
- * As per ARC HS databook (see chapter 5.3.3.2)
- * it is required to add 3 NOPs after each write to IC_IVIC.
- */
- __builtin_arc_nop();
- __builtin_arc_nop();
- __builtin_arc_nop();
- read_aux_reg(ARC_AUX_IC_CTRL); /* blocks */
- }
+ write_aux_reg(ARC_AUX_IC_IVIC, 1);
+ /*
+ * As per ARC HS databook (see chapter 5.3.3.2)
+ * it is required to add 3 NOPs after each write to IC_IVIC.
+ */
+ __builtin_arc_nop();
+ __builtin_arc_nop();
+ __builtin_arc_nop();
+ read_aux_reg(ARC_AUX_IC_CTRL); /* blocks */
+}
-#ifdef CONFIG_ISA_ARCV2
- if (slc_exists)
+void invalidate_icache_all(void)
+{
+ __ic_entire_invalidate();
+
+ /*
+ * If SL$ is bypassed for data it is used only for instructions,
+ * so we need to invalidate it too.
+ * TODO: HS 3.0 supports SLC disable so we need to check slc
+ * enable/disable status here.
+ */
+ if (is_isa_arcv2() && slc_data_bypass())
__slc_entire_op(OP_INV);
-#endif
}
int dcache_status(void)
{
- if (!dcache_exists)
- return 0;
-
- if (read_aux_reg(ARC_AUX_DC_CTRL) & DC_CTRL_CACHE_DISABLE)
- return 0;
- else
- return 1;
+ return dcache_enabled();
}
void dcache_enable(void)
{
- if (!dcache_exists)
+ if (!dcache_exists())
return;
write_aux_reg(ARC_AUX_DC_CTRL, read_aux_reg(ARC_AUX_DC_CTRL) &
@@ -358,83 +536,77 @@ void dcache_enable(void)
void dcache_disable(void)
{
- if (!dcache_exists)
+ if (!dcache_exists())
return;
+ __dc_entire_op(OP_FLUSH_N_INV);
+
+ /*
+ * As SLC will be bypassed for data after L1 D$ disable we need to
+ * flush it first before L1 D$ disable. Also we invalidate SLC to
+ * avoid any inconsistent data problems after enabling L1 D$ again with
+ * dcache_enable function.
+ */
+ if (is_isa_arcv2())
+ __slc_entire_op(OP_FLUSH_N_INV);
+
write_aux_reg(ARC_AUX_DC_CTRL, read_aux_reg(ARC_AUX_DC_CTRL) |
DC_CTRL_CACHE_DISABLE);
}
-#ifndef CONFIG_SYS_DCACHE_OFF
-/*
- * Common Helper for Line Operations on {I,D}-Cache
- */
-static inline void __cache_line_loop(unsigned long paddr, unsigned long sz,
- const int cacheop)
+/* Common Helper for Line Operations on D-cache */
+static inline void __dcache_line_loop(unsigned long paddr, unsigned long sz,
+ const int cacheop)
{
unsigned int aux_cmd;
-#if (CONFIG_ARC_MMU_VER == 3)
- unsigned int aux_tag;
-#endif
int num_lines;
- if (cacheop == OP_INV_IC) {
- aux_cmd = ARC_AUX_IC_IVIL;
-#if (CONFIG_ARC_MMU_VER == 3)
- aux_tag = ARC_AUX_IC_PTAG;
-#endif
- } else {
- /* d$ cmd: INV (discard or wback-n-discard) OR FLUSH (wback) */
- aux_cmd = cacheop & OP_INV ? ARC_AUX_DC_IVDL : ARC_AUX_DC_FLDL;
-#if (CONFIG_ARC_MMU_VER == 3)
- aux_tag = ARC_AUX_DC_PTAG;
-#endif
- }
+ /* d$ cmd: INV (discard or wback-n-discard) OR FLUSH (wback) */
+ aux_cmd = cacheop & OP_INV ? ARC_AUX_DC_IVDL : ARC_AUX_DC_FLDL;
sz += paddr & ~CACHE_LINE_MASK;
paddr &= CACHE_LINE_MASK;
- num_lines = DIV_ROUND_UP(sz, l1_line_sz);
+ num_lines = DIV_ROUND_UP(sz, gd->arch.l1_line_sz);
while (num_lines-- > 0) {
#if (CONFIG_ARC_MMU_VER == 3)
- write_aux_reg(aux_tag, paddr);
+ write_aux_reg(ARC_AUX_DC_PTAG, paddr);
#endif
write_aux_reg(aux_cmd, paddr);
- paddr += l1_line_sz;
+ paddr += gd->arch.l1_line_sz;
}
}
-static unsigned int __before_dc_op(const int op)
+static inlined_cachefunc void __before_dc_op(const int op)
{
- unsigned int reg;
+ unsigned int ctrl;
- if (op == OP_INV) {
- /*
- * IM is set by default and implies Flush-n-inv
- * Clear it here for vanilla inv
- */
- reg = read_aux_reg(ARC_AUX_DC_CTRL);
- write_aux_reg(ARC_AUX_DC_CTRL, reg & ~DC_CTRL_INV_MODE_FLUSH);
- }
+ ctrl = read_aux_reg(ARC_AUX_DC_CTRL);
- return reg;
+ /* IM bit implies flush-n-inv, instead of vanilla inv */
+ if (op == OP_INV)
+ ctrl &= ~DC_CTRL_INV_MODE_FLUSH;
+ else
+ ctrl |= DC_CTRL_INV_MODE_FLUSH;
+
+ write_aux_reg(ARC_AUX_DC_CTRL, ctrl);
}
-static void __after_dc_op(const int op, unsigned int reg)
+static inlined_cachefunc void __after_dc_op(const int op)
{
if (op & OP_FLUSH) /* flush / flush-n-inv both wait */
while (read_aux_reg(ARC_AUX_DC_CTRL) & DC_CTRL_FLUSH_STATUS);
-
- /* Switch back to default Invalidate mode */
- if (op == OP_INV)
- write_aux_reg(ARC_AUX_DC_CTRL, reg | DC_CTRL_INV_MODE_FLUSH);
}
-static inline void __dc_entire_op(const int cacheop)
+static inlined_cachefunc void __dc_entire_op(const int cacheop)
{
int aux;
- unsigned int ctrl_reg = __before_dc_op(cacheop);
+
+ if (!dcache_enabled())
+ return;
+
+ __before_dc_op(cacheop);
if (cacheop & OP_INV) /* Inv or flush-n-inv use same cmd reg */
aux = ARC_AUX_DC_IVDC;
@@ -443,36 +615,36 @@ static inline void __dc_entire_op(const int cacheop)
write_aux_reg(aux, 0x1);
- __after_dc_op(cacheop, ctrl_reg);
+ __after_dc_op(cacheop);
}
static inline void __dc_line_op(unsigned long paddr, unsigned long sz,
const int cacheop)
{
- unsigned int ctrl_reg = __before_dc_op(cacheop);
+ if (!dcache_enabled())
+ return;
- __cache_line_loop(paddr, sz, cacheop);
- __after_dc_op(cacheop, ctrl_reg);
+ __before_dc_op(cacheop);
+ __dcache_line_loop(paddr, sz, cacheop);
+ __after_dc_op(cacheop);
}
-#else
-#define __dc_entire_op(cacheop)
-#define __dc_line_op(paddr, sz, cacheop)
-#endif /* !CONFIG_SYS_DCACHE_OFF */
void invalidate_dcache_range(unsigned long start, unsigned long end)
{
if (start >= end)
return;
-#ifdef CONFIG_ISA_ARCV2
- if (!ioc_exists)
-#endif
+ /*
+ * ARCv1 -> call __dc_line_op
+ * ARCv2 && L1 D$ disabled -> nothing
+ * ARCv2 && L1 D$ enabled && IOC enabled -> nothing
+ * ARCv2 && L1 D$ enabled && no IOC -> call __dc_line_op; call __slc_rgn_op
+ */
+ if (!is_isa_arcv2() || !ioc_enabled())
__dc_line_op(start, end - start, OP_INV);
-#ifdef CONFIG_ISA_ARCV2
- if (slc_exists && !ioc_exists)
+ if (is_isa_arcv2() && !ioc_enabled() && !slc_data_bypass())
__slc_rgn_op(start, end - start, OP_INV);
-#endif
}
void flush_dcache_range(unsigned long start, unsigned long end)
@@ -480,15 +652,17 @@ void flush_dcache_range(unsigned long start, unsigned long end)
if (start >= end)
return;
-#ifdef CONFIG_ISA_ARCV2
- if (!ioc_exists)
-#endif
+ /*
+ * ARCv1 -> call __dc_line_op
+ * ARCv2 && L1 D$ disabled -> nothing
+ * ARCv2 && L1 D$ enabled && IOC enabled -> nothing
+ * ARCv2 && L1 D$ enabled && no IOC -> call __dc_line_op; call __slc_rgn_op
+ */
+ if (!is_isa_arcv2() || !ioc_enabled())
__dc_line_op(start, end - start, OP_FLUSH);
-#ifdef CONFIG_ISA_ARCV2
- if (slc_exists && !ioc_exists)
+ if (is_isa_arcv2() && !ioc_enabled() && !slc_data_bypass())
__slc_rgn_op(start, end - start, OP_FLUSH);
-#endif
}
void flush_cache(unsigned long start, unsigned long size)
@@ -496,22 +670,47 @@ void flush_cache(unsigned long start, unsigned long size)
flush_dcache_range(start, start + size);
}
-void invalidate_dcache_all(void)
+/*
+ * As invalidate_dcache_all() is not used in generic U-Boot code and as we
+ * don't need it in arch/arc code alone (invalidate without flush) we implement
+ * flush_n_invalidate_dcache_all (flush and invalidate in 1 operation) because
+ * it's much safer. See [ NOTE 1 ] for more details.
+ */
+void flush_n_invalidate_dcache_all(void)
{
- __dc_entire_op(OP_INV);
+ __dc_entire_op(OP_FLUSH_N_INV);
-#ifdef CONFIG_ISA_ARCV2
- if (slc_exists)
- __slc_entire_op(OP_INV);
-#endif
+ if (is_isa_arcv2() && !slc_data_bypass())
+ __slc_entire_op(OP_FLUSH_N_INV);
}
void flush_dcache_all(void)
{
__dc_entire_op(OP_FLUSH);
-#ifdef CONFIG_ISA_ARCV2
- if (slc_exists)
+ if (is_isa_arcv2() && !slc_data_bypass())
__slc_entire_op(OP_FLUSH);
-#endif
+}
+
+/*
+ * This is function to cleanup all caches (and therefore sync I/D caches) which
+ * can be used for cleanup before linux launch or to sync caches during
+ * relocation.
+ */
+void sync_n_cleanup_cache_all(void)
+{
+ __dc_entire_op(OP_FLUSH_N_INV);
+
+ /*
+ * If SL$ is bypassed for data it is used only for instructions,
+ * and we shouldn't flush it. So invalidate it instead of flush_n_inv.
+ */
+ if (is_isa_arcv2()) {
+ if (slc_data_bypass())
+ __slc_entire_op(OP_INV);
+ else
+ __slc_entire_op(OP_FLUSH_N_INV);
+ }
+
+ __ic_entire_invalidate();
}
diff --git a/arch/arc/lib/init_helpers.c b/arch/arc/lib/init_helpers.c
index dbc8d68ffb..435fe96ef4 100644
--- a/arch/arc/lib/init_helpers.c
+++ b/arch/arc/lib/init_helpers.c
@@ -4,14 +4,14 @@
* SPDX-License-Identifier: GPL-2.0+
*/
+#include <asm/cache.h>
#include <common.h>
DECLARE_GLOBAL_DATA_PTR;
int init_cache_f_r(void)
{
-#ifndef CONFIG_SYS_DCACHE_OFF
- flush_dcache_all();
-#endif
+ sync_n_cleanup_cache_all();
+
return 0;
}
diff --git a/arch/arc/lib/memcmp.S b/arch/arc/lib/memcmp.S
deleted file mode 100644
index 87bccab51d..0000000000
--- a/arch/arc/lib/memcmp.S
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright (C) 2004, 2007-2010, 2011-2014 Synopsys, Inc. All rights reserved.
- *
- * SPDX-License-Identifier: GPL-2.0+
- */
-
-#ifdef __LITTLE_ENDIAN__
-#define WORD2 r2
-#define SHIFT r3
-#else /* __BIG_ENDIAN__ */
-#define WORD2 r3
-#define SHIFT r2
-#endif /* _ENDIAN__ */
-
-.global memcmp
-.align 4
-memcmp:
- or %r12, %r0, %r1
- asl_s %r12, %r12, 30
- sub %r3, %r2, 1
- brls %r2, %r12, .Lbytewise
- ld %r4, [%r0, 0]
- ld %r5, [%r1, 0]
- lsr.f %lp_count, %r3, 3
- lpne .Loop_end
- ld_s WORD2, [%r0, 4]
- ld_s %r12, [%r1, 4]
- brne %r4, %r5, .Leven
- ld.a %r4, [%r0, 8]
- ld.a %r5, [%r1, 8]
- brne WORD2, %r12, .Lodd
- nop
-.Loop_end:
- asl_s SHIFT, SHIFT, 3
- bhs_s .Last_cmp
- brne %r4, %r5, .Leven
- ld %r4, [%r0, 4]
- ld %r5, [%r1, 4]
-#ifdef __LITTLE_ENDIAN__
- nop_s
- /* one more load latency cycle */
-.Last_cmp:
- xor %r0, %r4, %r5
- bset %r0, %r0, SHIFT
- sub_s %r1, %r0, 1
- bic_s %r1, %r1, %r0
- norm %r1, %r1
- b.d .Leven_cmp
- and %r1, %r1, 24
-.Leven:
- xor %r0, %r4, %r5
- sub_s %r1, %r0, 1
- bic_s %r1, %r1, %r0
- norm %r1, %r1
- /* slow track insn */
- and %r1, %r1, 24
-.Leven_cmp:
- asl %r2, %r4, %r1
- asl %r12, %r5, %r1
- lsr_s %r2, %r2, 1
- lsr_s %r12, %r12, 1
- j_s.d [%blink]
- sub %r0, %r2, %r12
- .balign 4
-.Lodd:
- xor %r0, WORD2, %r12
- sub_s %r1, %r0, 1
- bic_s %r1, %r1, %r0
- norm %r1, %r1
- /* slow track insn */
- and %r1, %r1, 24
- asl_s %r2, %r2, %r1
- asl_s %r12, %r12, %r1
- lsr_s %r2, %r2, 1
- lsr_s %r12, %r12, 1
- j_s.d [%blink]
- sub %r0, %r2, %r12
-#else /* __BIG_ENDIAN__ */
-.Last_cmp:
- neg_s SHIFT, SHIFT
- lsr %r4, %r4, SHIFT
- lsr %r5, %r5, SHIFT
- /* slow track insn */
-.Leven:
- sub.f %r0, %r4, %r5
- mov.ne %r0, 1
- j_s.d [%blink]
- bset.cs %r0, %r0, 31
-.Lodd:
- cmp_s WORD2, %r12
-
- mov_s %r0, 1
- j_s.d [%blink]
- bset.cs %r0, %r0, 31
-#endif /* _ENDIAN__ */
- .balign 4
-.Lbytewise:
- breq %r2, 0, .Lnil
- ldb %r4, [%r0, 0]
- ldb %r5, [%r1, 0]
- lsr.f %lp_count, %r3
- lpne .Lbyte_end
- ldb_s %r3, [%r0, 1]
- ldb %r12, [%r1, 1]
- brne %r4, %r5, .Lbyte_even
- ldb.a %r4, [%r0, 2]
- ldb.a %r5, [%r1, 2]
- brne %r3, %r12, .Lbyte_odd
- nop
-.Lbyte_end:
- bcc .Lbyte_even
- brne %r4, %r5, .Lbyte_even
- ldb_s %r3, [%r0, 1]
- ldb_s %r12, [%r1, 1]
-.Lbyte_odd:
- j_s.d [%blink]
- sub %r0, %r3, %r12
-.Lbyte_even:
- j_s.d [%blink]
- sub %r0, %r4, %r5
-.Lnil:
- j_s.d [%blink]
- mov %r0, 0
diff --git a/arch/arc/lib/memcpy-700.S b/arch/arc/lib/memcpy-700.S
deleted file mode 100644
index 51dd73ab8f..0000000000
--- a/arch/arc/lib/memcpy-700.S
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2004, 2007-2010, 2011-2014 Synopsys, Inc. All rights reserved.
- *
- * SPDX-License-Identifier: GPL-2.0+
- */
-
-.global memcpy
-.align 4
-memcpy:
- or %r3, %r0, %r1
- asl_s %r3, %r3, 30
- mov_s %r5, %r0
- brls.d %r2, %r3, .Lcopy_bytewise
- sub.f %r3, %r2, 1
- ld_s %r12, [%r1, 0]
- asr.f %lp_count, %r3, 3
- bbit0.d %r3, 2, .Lnox4
- bmsk_s %r2, %r2, 1
- st.ab %r12, [%r5, 4]
- ld.a %r12, [%r1, 4]
-.Lnox4:
- lppnz .Lendloop
- ld_s %r3, [%r1, 4]
- st.ab %r12, [%r5, 4]
- ld.a %r12, [%r1, 8]
- st.ab %r3, [%r5, 4]
-.Lendloop:
- breq %r2, 0, .Last_store
- ld %r3, [%r5, 0]
-#ifdef __LITTLE_ENDIAN__
- add3 %r2, -1, %r2
- /* uses long immediate */
- xor_s %r12, %r12, %r3
- bmsk %r12, %r12, %r2
- xor_s %r12, %r12, %r3
-#else /* __BIG_ENDIAN__ */
- sub3 %r2, 31, %r2
- /* uses long immediate */
- xor_s %r3, %r3, %r12
- bmsk %r3, %r3, %r2
- xor_s %r12, %r12, %r3
-#endif /* _ENDIAN__ */
-.Last_store:
- j_s.d [%blink]
- st %r12, [%r5, 0]
-
- .balign 4
-.Lcopy_bytewise:
- jcs [%blink]
- ldb_s %r12, [%r1, 0]
- lsr.f %lp_count, %r3
- bhs_s .Lnox1
- stb.ab %r12, [%r5, 1]
- ldb.a %r12, [%r1, 1]
-.Lnox1:
- lppnz .Lendbloop
- ldb_s %r3, [%r1, 1]
- stb.ab %r12, [%r5, 1]
- ldb.a %r12, [%r1, 2]
- stb.ab %r3, [%r5, 1]
-.Lendbloop:
- j_s.d [%blink]
- stb %r12, [%r5, 0]
diff --git a/arch/arc/lib/memset.S b/arch/arc/lib/memset.S
deleted file mode 100644
index 017e8af0e8..0000000000
--- a/arch/arc/lib/memset.S
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2004, 2007-2010, 2011-2014 Synopsys, Inc. All rights reserved.
- *
- * SPDX-License-Identifier: GPL-2.0+
- */
-
-#define SMALL 7 /* Must be at least 6 to deal with alignment/loop issues. */
-
-.global memset
-.align 4
-memset:
- mov_s %r4, %r0
- or %r12, %r0, %r2
- bmsk.f %r12, %r12, 1
- extb_s %r1, %r1
- asl %r3, %r1, 8
- beq.d .Laligned
- or_s %r1, %r1, %r3
- brls %r2, SMALL, .Ltiny
- add %r3, %r2, %r0
- stb %r1, [%r3, -1]
- bclr_s %r3, %r3, 0
- stw %r1, [%r3, -2]
- bmsk.f %r12, %r0, 1
- add_s %r2, %r2, %r12
- sub.ne %r2, %r2, 4
- stb.ab %r1, [%r4, 1]
- and %r4, %r4, -2
- stw.ab %r1, [%r4, 2]
- and %r4, %r4, -4
-
- .balign 4
-.Laligned:
- asl %r3, %r1, 16
- lsr.f %lp_count, %r2, 2
- or_s %r1, %r1, %r3
- lpne .Loop_end
- st.ab %r1, [%r4, 4]
-.Loop_end:
- j_s [%blink]
-
- .balign 4
-.Ltiny:
- mov.f %lp_count, %r2
- lpne .Ltiny_end
- stb.ab %r1, [%r4, 1]
-.Ltiny_end:
- j_s [%blink]
-
-/*
- * memzero: @r0 = mem, @r1 = size_t
- * memset: @r0 = mem, @r1 = char, @r2 = size_t
- */
-
-.global memzero
-.align 4
-memzero:
- /* adjust bzero args to memset args */
- mov %r2, %r1
- mov %r1, 0
- /* tail call so need to tinker with blink */
- b memset
diff --git a/arch/arc/lib/relocate.c b/arch/arc/lib/relocate.c
index 7802f40545..96b4bd3d8f 100644
--- a/arch/arc/lib/relocate.c
+++ b/arch/arc/lib/relocate.c
@@ -17,6 +17,9 @@ int copy_uboot_to_ram(void)
{
size_t len = (size_t)&__image_copy_end - (size_t)&__image_copy_start;
+ if (gd->flags & GD_FLG_SKIP_RELOC)
+ return 0;
+
memcpy((void *)gd->relocaddr, (void *)&__image_copy_start, len);
return 0;
@@ -40,6 +43,9 @@ int do_elf_reloc_fixups(void)
Elf32_Rela *re_src = (Elf32_Rela *)(&__rel_dyn_start);
Elf32_Rela *re_end = (Elf32_Rela *)(&__rel_dyn_end);
+ if (gd->flags & GD_FLG_SKIP_RELOC)
+ return 0;
+
debug("Section .rela.dyn is located at %08x-%08x\n",
(unsigned int)re_src, (unsigned int)re_end);
diff --git a/arch/arc/lib/start.S b/arch/arc/lib/start.S
index 0d72fe71d4..c78dd001d8 100644
--- a/arch/arc/lib/start.S
+++ b/arch/arc/lib/start.S
@@ -10,26 +10,6 @@
#include <asm/arcregs.h>
ENTRY(_start)
-; ARCompact devices are not supposed to be SMP so master/slave check
-; makes no sense.
-#ifdef CONFIG_ISA_ARCV2
- ; Non-masters will be halted immediately, they might be kicked later
- ; by platform code right before passing control to the Linux kernel
- ; in bootm.c:boot_jump_linux().
- lr r5, [identity]
- lsr r5, r5, 8
- bmsk r5, r5, 7
- cmp r5, 0
- mov.nz r0, r5
- bz .Lmaster_proceed
- flag 1
- nop
- nop
- nop
-
-.Lmaster_proceed:
-#endif
-
/* Setup interrupt vector base that matches "__text_start" */
sr __ivt_start, [ARC_AUX_INTR_VEC_BASE]
@@ -98,7 +78,13 @@ ENTRY(_start)
/* Zero the one and only argument of "board_init_f" */
mov_s %r0, 0
- j board_init_f
+ bl board_init_f
+
+ /* We only get here if relocation is disabled by GD_FLG_SKIP_RELOC */
+ /* Make sure we don't lose GD overwritten by zero new GD */
+ mov %r0, %r25
+ mov %r1, 0
+ bl board_init_r
ENDPROC(_start)
/*
diff --git a/arch/arc/lib/strchr-700.S b/arch/arc/lib/strchr-700.S
deleted file mode 100644
index 55fcc9fb00..0000000000
--- a/arch/arc/lib/strchr-700.S
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Copyright (C) 2004, 2007-2010, 2011-2014 Synopsys, Inc. All rights reserved.
- *
- * SPDX-License-Identifier: GPL-2.0+
- */
-
-/*
- * ARC700 has a relatively long pipeline and branch prediction, so we want
- * to avoid branches that are hard to predict. On the other hand, the
- * presence of the norm instruction makes it easier to operate on whole
- * words branch-free.
- */
-
-.global strchr
-.align 4
-strchr:
- extb_s %r1, %r1
- asl %r5, %r1, 8
- bmsk %r2, %r0, 1
- or %r5, %r5, %r1
- mov_s %r3, 0x01010101
- breq.d %r2, %r0, .Laligned
- asl %r4, %r5, 16
- sub_s %r0, %r0, %r2
- asl %r7, %r2, 3
- ld_s %r2, [%r0]
-#ifdef __LITTLE_ENDIAN__
- asl %r7, %r3, %r7
-#else /* __BIG_ENDIAN__ */
- lsr %r7, %r3, %r7
-#endif /* _ENDIAN__ */
- or %r5, %r5, %r4
- ror %r4, %r3
- sub %r12, %r2, %r7
- bic_s %r12, %r12, %r2
- and %r12, %r12, %r4
- brne.d %r12, 0, .Lfound0_ua
- xor %r6, %r2, %r5
- ld.a %r2, [%r0, 4]
- sub %r12, %r6, %r7
- bic %r12, %r12, %r6
-#ifdef __LITTLE_ENDIAN__
- and %r7, %r12, %r4
- /* For speed, we want this branch to be unaligned. */
- breq %r7, 0, .Loop
- /* Likewise this one */
- b .Lfound_char
-#else /* __BIG_ENDIAN__ */
- and %r12, %r12, %r4
- /* For speed, we want this branch to be unaligned. */
- breq %r12, 0, .Loop
- lsr_s %r12, %r12, 7
- bic %r2, %r7, %r6
- b.d .Lfound_char_b
- and_s %r2, %r2, %r12
-#endif /* _ENDIAN__ */
- /* We require this code address to be unaligned for speed... */
-.Laligned:
- ld_s %r2, [%r0]
- or %r5, %r5, %r4
- ror %r4, %r3
- /* ... so that this code address is aligned, for itself and ... */
-.Loop:
- sub %r12, %r2, %r3
- bic_s %r12, %r12, %r2
- and %r12, %r12, %r4
- brne.d %r12, 0, .Lfound0
- xor %r6, %r2, %r5
- ld.a %r2, [%r0, 4]
- sub %r12, %r6, %r3
- bic %r12, %r12, %r6
- and %r7, %r12, %r4
- breq %r7, 0, .Loop
- /*
- *... so that this branch is unaligned.
- * Found searched-for character.
- * r0 has already advanced to next word.
- */
-#ifdef __LITTLE_ENDIAN__
- /*
- * We only need the information about the first matching byte
- * (i.e. the least significant matching byte) to be exact,
- * hence there is no problem with carry effects.
- */
-.Lfound_char:
- sub %r3, %r7, 1
- bic %r3, %r3, %r7
- norm %r2, %r3
- sub_s %r0, %r0, 1
- asr_s %r2, %r2, 3
- j.d [%blink]
- sub_s %r0, %r0, %r2
-
- .balign 4
-.Lfound0_ua:
- mov %r3, %r7
-.Lfound0:
- sub %r3, %r6, %r3
- bic %r3, %r3, %r6
- and %r2, %r3, %r4
- or_s %r12, %r12, %r2
- sub_s %r3, %r12, 1
- bic_s %r3, %r3, %r12
- norm %r3, %r3
- add_s %r0, %r0, 3
- asr_s %r12, %r3, 3
- asl.f 0, %r2, %r3
- sub_s %r0, %r0, %r12
- j_s.d [%blink]
- mov.pl %r0, 0
-#else /* __BIG_ENDIAN__ */
-.Lfound_char:
- lsr %r7, %r7, 7
-
- bic %r2, %r7, %r6
-.Lfound_char_b:
- norm %r2, %r2
- sub_s %r0, %r0, 4
- asr_s %r2, %r2, 3
- j.d [%blink]
- add_s %r0, %r0, %r2
-
-.Lfound0_ua:
- mov_s %r3, %r7
-.Lfound0:
- asl_s %r2, %r2, 7
- or %r7, %r6, %r4
- bic_s %r12, %r12, %r2
- sub %r2, %r7, %r3
- or %r2, %r2, %r6
- bic %r12, %r2, %r12
- bic.f %r3, %r4, %r12
- norm %r3, %r3
-
- add.pl %r3, %r3, 1
- asr_s %r12, %r3, 3
- asl.f 0, %r2, %r3
- add_s %r0, %r0, %r12
- j_s.d [%blink]
- mov.mi %r0, 0
-#endif /* _ENDIAN__ */
diff --git a/arch/arc/lib/strcmp.S b/arch/arc/lib/strcmp.S
deleted file mode 100644
index 8cb7d2f18c..0000000000
--- a/arch/arc/lib/strcmp.S
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (C) 2004, 2007-2010, 2011-2014 Synopsys, Inc. All rights reserved.
- *
- * SPDX-License-Identifier: GPL-2.0+
- */
-
-/*
- * This is optimized primarily for the ARC700.
- * It would be possible to speed up the loops by one cycle / word
- * respective one cycle / byte by forcing double source 1 alignment, unrolling
- * by a factor of two, and speculatively loading the second word / byte of
- * source 1; however, that would increase the overhead for loop setup / finish,
- * and strcmp might often terminate early.
- */
-
-.global strcmp
-.align 4
-strcmp:
- or %r2, %r0, %r1
- bmsk_s %r2, %r2, 1
- brne %r2, 0, .Lcharloop
- mov_s %r12, 0x01010101
- ror %r5, %r12
-.Lwordloop:
- ld.ab %r2, [%r0, 4]
- ld.ab %r3, [%r1, 4]
- nop_s
- sub %r4, %r2, %r12
- bic %r4, %r4, %r2
- and %r4, %r4, %r5
- brne %r4, 0, .Lfound0
- breq %r2 ,%r3, .Lwordloop
-#ifdef __LITTLE_ENDIAN__
- xor %r0, %r2, %r3 /* mask for difference */
- sub_s %r1, %r0, 1
- bic_s %r0, %r0, %r1 /* mask for least significant difference bit */
- sub %r1, %r5, %r0
- xor %r0, %r5, %r1 /* mask for least significant difference byte */
- and_s %r2, %r2, %r0
- and_s %r3, %r3, %r0
-#endif /* _ENDIAN__ */
- cmp_s %r2, %r3
- mov_s %r0, 1
- j_s.d [%blink]
- bset.lo %r0, %r0, 31
-
- .balign 4
-#ifdef __LITTLE_ENDIAN__
-.Lfound0:
- xor %r0, %r2, %r3 /* mask for difference */
- or %r0, %r0, %r4 /* or in zero indicator */
- sub_s %r1, %r0, 1
- bic_s %r0, %r0, %r1 /* mask for least significant difference bit */
- sub %r1, %r5, %r0
- xor %r0, %r5, %r1 /* mask for least significant difference byte */
- and_s %r2, %r2, %r0
- and_s %r3, %r3, %r0
- sub.f %r0, %r2, %r3
- mov.hi %r0, 1
- j_s.d [%blink]
- bset.lo %r0, %r0, 31
-#else /* __BIG_ENDIAN__ */
- /*
- * The zero-detection above can mis-detect 0x01 bytes as zeroes
- * because of carry-propagateion from a lower significant zero byte.
- * We can compensate for this by checking that bit0 is zero.
- * This compensation is not necessary in the step where we
- * get a low estimate for r2, because in any affected bytes
- * we already have 0x00 or 0x01, which will remain unchanged
- * when bit 7 is cleared.
- */
- .balign 4
-.Lfound0:
- lsr %r0, %r4, 8
- lsr_s %r1, %r2
- bic_s %r2, %r2, %r0 /* get low estimate for r2 and get ... */
- bic_s %r0, %r0, %r1 /* <this is the adjusted mask for zeros> */
- or_s %r3, %r3, %r0 /* ... high estimate r3 so that r2 > r3 will */
- cmp_s %r3, %r2 /* ... be independent of trailing garbage */
- or_s %r2, %r2, %r0 /* likewise for r3 > r2 */
- bic_s %r3, %r3, %r0
- rlc %r0, 0 /* r0 := r2 > r3 ? 1 : 0 */
- cmp_s %r2, %r3
- j_s.d [%blink]
- bset.lo %r0, %r0, 31
-#endif /* _ENDIAN__ */
-
- .balign 4
-.Lcharloop:
- ldb.ab %r2,[%r0,1]
- ldb.ab %r3,[%r1,1]
- nop_s
- breq %r2, 0, .Lcmpend
- breq %r2, %r3, .Lcharloop
-.Lcmpend:
- j_s.d [%blink]
- sub %r0, %r2, %r3
diff --git a/arch/arc/lib/strcpy-700.S b/arch/arc/lib/strcpy-700.S
deleted file mode 100644
index 41bb53e501..0000000000
--- a/arch/arc/lib/strcpy-700.S
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2004, 2007-2010, 2011-2014 Synopsys, Inc. All rights reserved.
- *
- * SPDX-License-Identifier: GPL-2.0+
- */
-
-/*
- * If dst and src are 4 byte aligned, copy 8 bytes at a time.
- * If the src is 4, but not 8 byte aligned, we first read 4 bytes to get
- * it 8 byte aligned. Thus, we can do a little read-ahead, without
- * dereferencing a cache line that we should not touch.
- * Note that short and long instructions have been scheduled to avoid
- * branch stalls.
- * The beq_s to r3z could be made unaligned & long to avoid a stall
- * there, but it is not likely to be taken often, and it would also be likely
- * to cost an unaligned mispredict at the next call.
- */
-
-.global strcpy
-.align 4
-strcpy:
- or %r2, %r0, %r1
- bmsk_s %r2, %r2, 1
- brne.d %r2, 0, charloop
- mov_s %r10, %r0
- ld_s %r3, [%r1, 0]
- mov %r8, 0x01010101
- bbit0.d %r1, 2, loop_start
- ror %r12, %r8
- sub %r2, %r3, %r8
- bic_s %r2, %r2, %r3
- tst_s %r2,%r12
- bne r3z
- mov_s %r4,%r3
- .balign 4
-loop:
- ld.a %r3, [%r1, 4]
- st.ab %r4, [%r10, 4]
-loop_start:
- ld.a %r4, [%r1, 4]
- sub %r2, %r3, %r8
- bic_s %r2, %r2, %r3
- tst_s %r2, %r12
- bne_s r3z
- st.ab %r3, [%r10, 4]
- sub %r2, %r4, %r8
- bic %r2, %r2, %r4
- tst %r2, %r12
- beq loop
- mov_s %r3, %r4
-#ifdef __LITTLE_ENDIAN__
-r3z: bmsk.f %r1, %r3, 7
- lsr_s %r3, %r3, 8
-#else /* __BIG_ENDIAN__ */
-r3z: lsr.f %r1, %r3, 24
- asl_s %r3, %r3, 8
-#endif /* _ENDIAN__ */
- bne.d r3z
- stb.ab %r1, [%r10, 1]
- j_s [%blink]
-
- .balign 4
-charloop:
- ldb.ab %r3, [%r1, 1]
- brne.d %r3, 0, charloop
- stb.ab %r3, [%r10, 1]
- j [%blink]
diff --git a/arch/arc/lib/strlen.S b/arch/arc/lib/strlen.S
deleted file mode 100644
index 666e22c0d5..0000000000
--- a/arch/arc/lib/strlen.S
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2004, 2007-2010, 2011-2014 Synopsys, Inc. All rights reserved.
- *
- * SPDX-License-Identifier: GPL-2.0+
- */
-
-.global strlen
-.align 4
-strlen:
- or %r3, %r0, 7
- ld %r2, [%r3, -7]
- ld.a %r6, [%r3, -3]
- mov %r4, 0x01010101
- /* uses long immediate */
-#ifdef __LITTLE_ENDIAN__
- asl_s %r1, %r0, 3
- btst_s %r0, 2
- asl %r7, %r4, %r1
- ror %r5, %r4
- sub %r1, %r2, %r7
- bic_s %r1, %r1, %r2
- mov.eq %r7, %r4
- sub %r12, %r6, %r7
- bic %r12, %r12, %r6
- or.eq %r12, %r12, %r1
- and %r12, %r12, %r5
- brne %r12, 0, .Learly_end
-#else /* __BIG_ENDIAN__ */
- ror %r5, %r4
- btst_s %r0, 2
- mov_s %r1, 31
- sub3 %r7, %r1, %r0
- sub %r1, %r2, %r4
- bic_s %r1, %r1, %r2
- bmsk %r1, %r1, %r7
- sub %r12, %r6, %r4
- bic %r12, %r12, %r6
- bmsk.ne %r12, %r12, %r7
- or.eq %r12, %r12, %r1
- and %r12, %r12, %r5
- brne %r12, 0, .Learly_end
-#endif /* _ENDIAN__ */
-
-.Loop:
- ld_s %r2, [%r3, 4]
- ld.a %r6, [%r3, 8]
- /* stall for load result */
- sub %r1, %r2, %r4
- bic_s %r1, %r1, %r2
- sub %r12, %r6, %r4
- bic %r12, %r12, %r6
- or %r12, %r12, %r1
- and %r12, %r12, %r5
- breq %r12, 0, .Loop
-.Lend:
- and.f %r1, %r1, %r5
- sub.ne %r3, %r3, 4
- mov.eq %r1, %r12
-#ifdef __LITTLE_ENDIAN__
- sub_s %r2, %r1, 1
- bic_s %r2, %r2, %r1
- norm %r1, %r2
- sub_s %r0, %r0, 3
- lsr_s %r1, %r1, 3
- sub %r0, %r3, %r0
- j_s.d [%blink]
- sub %r0, %r0, %r1
-#else /* __BIG_ENDIAN__ */
- lsr_s %r1, %r1, 7
- mov.eq %r2, %r6
- bic_s %r1, %r1, %r2
- norm %r1, %r1
- sub %r0, %r3, %r0
- lsr_s %r1, %r1, 3
- j_s.d [%blink]
- add %r0, %r0, %r1
-#endif /* _ENDIAN */
-.Learly_end:
- b.d .Lend
- sub_s.ne %r1, %r1, %r1
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index b8f7a982d9..068ea1e877 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -762,6 +762,7 @@ config ARCH_ZYNQ
select SUPPORT_SPL
select OF_CONTROL
select SPL_BOARD_INIT if SPL
+ select BOARD_EARLY_INIT_F if WDT
select SPL_OF_CONTROL if SPL
select DM
select DM_ETH if NET
@@ -1359,6 +1360,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/zynqmp/Kconfig"
source "board/zipitz2/Kconfig"
source "arch/arm/Kconfig.debug"
diff --git a/arch/arm/cpu/armv8/zynqmp/cpu.c b/arch/arm/cpu/armv8/zynqmp/cpu.c
index bc77dd03c3..14e7d40064 100644
--- a/arch/arm/cpu/armv8/zynqmp/cpu.c
+++ b/arch/arm/cpu/armv8/zynqmp/cpu.c
@@ -185,7 +185,7 @@ void zynqmp_pmufw_version(void)
pm_api_version >> ZYNQMP_PM_VERSION_MAJOR_SHIFT,
pm_api_version & ZYNQMP_PM_VERSION_MINOR_MASK);
- if (pm_api_version != ZYNQMP_PM_VERSION)
+ if (pm_api_version < ZYNQMP_PM_VERSION)
panic("PMUFW version error. Expected: v%d.%d\n",
ZYNQMP_PM_VERSION_MAJOR, ZYNQMP_PM_VERSION_MINOR);
}
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 7dd1dffae5..e983622fea 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -146,7 +146,6 @@ dtb-$(CONFIG_ARCH_ZYNQ) += \
zynq-zturn-myir.dtb \
zynq-zybo.dtb
dtb-$(CONFIG_ARCH_ZYNQMP) += \
- zynqmp-ep108.dtb \
zynqmp-mini-emmc.dtb \
zynqmp-mini-nand.dtb \
zynqmp-zcu102-revA.dtb \
diff --git a/arch/arm/dts/zynq-zc706.dts b/arch/arm/dts/zynq-zc706.dts
index d342306293..a88a83c166 100644
--- a/arch/arm/dts/zynq-zc706.dts
+++ b/arch/arm/dts/zynq-zc706.dts
@@ -333,3 +333,7 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_usb0_default>;
};
+
+&watchdog0 {
+ reset-on-timeout;
+};
diff --git a/arch/arm/dts/zynqmp-clk-ccf.dtsi b/arch/arm/dts/zynqmp-clk-ccf.dtsi
new file mode 100644
index 0000000000..4449d5b93d
--- /dev/null
+++ b/arch/arm/dts/zynqmp-clk-ccf.dtsi
@@ -0,0 +1,290 @@
+/*
+ * Clock specification for Xilinx ZynqMP
+ *
+ * (C) Copyright 2017, Xilinx, Inc.
+ *
+ * Michal Simek <michal.simek@xilinx.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+/ {
+ fclk0: fclk0 {
+ status = "disabled";
+ compatible = "xlnx,fclk";
+ clocks = <&clkc 71>;
+ };
+
+ fclk1: fclk1 {
+ status = "disabled";
+ compatible = "xlnx,fclk";
+ clocks = <&clkc 72>;
+ };
+
+ fclk2: fclk2 {
+ status = "disabled";
+ compatible = "xlnx,fclk";
+ clocks = <&clkc 73>;
+ };
+
+ fclk3: fclk3 {
+ status = "disabled";
+ compatible = "xlnx,fclk";
+ clocks = <&clkc 74>;
+ };
+
+ pss_ref_clk: pss_ref_clk {
+ u-boot,dm-pre-reloc;
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <33333333>;
+ };
+
+ video_clk: video_clk {
+ u-boot,dm-pre-reloc;
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <27000000>;
+ };
+
+ pss_alt_ref_clk: pss_alt_ref_clk {
+ u-boot,dm-pre-reloc;
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <0>;
+ };
+
+ gt_crx_ref_clk: gt_crx_ref_clk {
+ u-boot,dm-pre-reloc;
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <108000000>;
+ };
+
+ aux_ref_clk: aux_ref_clk {
+ u-boot,dm-pre-reloc;
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <27000000>;
+ };
+
+ clkc: clkc {
+ u-boot,dm-pre-reloc;
+ #clock-cells = <1>;
+ compatible = "xlnx,zynqmp-clkc";
+ clocks = <&pss_ref_clk>, <&video_clk>, <&pss_alt_ref_clk>, <&aux_ref_clk>, <&gt_crx_ref_clk>;
+ clock-names = "pss_ref_clk", "video_clk", "pss_alt_ref_clk", "aux_ref_clk", "gt_crx_ref_clk";
+ clock-output-names = "iopll", "rpll", "apll", "dpll",
+ "vpll", "iopll_to_fpd", "rpll_to_fpd",
+ "apll_to_lpd", "dpll_to_lpd", "vpll_to_lpd",
+ "acpu", "acpu_half", "dbf_fpd", "dbf_lpd",
+ "dbg_trace", "dbg_tstmp", "dp_video_ref",
+ "dp_audio_ref", "dp_stc_ref", "gdma_ref",
+ "dpdma_ref", "ddr_ref", "sata_ref", "pcie_ref",
+ "gpu_ref", "gpu_pp0_ref", "gpu_pp1_ref",
+ "topsw_main", "topsw_lsbus", "gtgref0_ref",
+ "lpd_switch", "lpd_lsbus", "usb0_bus_ref",
+ "usb1_bus_ref", "usb3_dual_ref", "usb0",
+ "usb1", "cpu_r5", "cpu_r5_core", "csu_spb",
+ "csu_pll", "pcap", "iou_switch", "gem_tsu_ref",
+ "gem_tsu", "gem0_ref", "gem1_ref", "gem2_ref",
+ "gem3_ref", "gem0_tx", "gem1_tx", "gem2_tx",
+ "gem3_tx", "qspi_ref", "sdio0_ref", "sdio1_ref",
+ "uart0_ref", "uart1_ref", "spi0_ref",
+ "spi1_ref", "nand_ref", "i2c0_ref", "i2c1_ref",
+ "can0_ref", "can1_ref", "can0", "can1",
+ "dll_ref", "adma_ref", "timestamp_ref",
+ "ams_ref", "pl0", "pl1", "pl2", "pl3", "wdt";
+ };
+
+ dp_aclk: dp_aclk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <100000000>;
+ clock-accuracy = <100>;
+ };
+};
+
+&can0 {
+ clocks = <&clkc 63>, <&clkc 31>;
+};
+
+&can1 {
+ clocks = <&clkc 64>, <&clkc 31>;
+};
+
+&cpu0 {
+ clocks = <&clkc 10>;
+};
+
+&fpd_dma_chan1 {
+ clocks = <&clkc 19>, <&clkc 31>;
+};
+
+&fpd_dma_chan2 {
+ clocks = <&clkc 19>, <&clkc 31>;
+};
+
+&fpd_dma_chan3 {
+ clocks = <&clkc 19>, <&clkc 31>;
+};
+
+&fpd_dma_chan4 {
+ clocks = <&clkc 19>, <&clkc 31>;
+};
+
+&fpd_dma_chan5 {
+ clocks = <&clkc 19>, <&clkc 31>;
+};
+
+&fpd_dma_chan6 {
+ clocks = <&clkc 19>, <&clkc 31>;
+};
+
+&fpd_dma_chan7 {
+ clocks = <&clkc 19>, <&clkc 31>;
+};
+
+&fpd_dma_chan8 {
+ clocks = <&clkc 19>, <&clkc 31>;
+};
+
+&gpu {
+ clocks = <&clkc 24>, <&clkc 25>, <&clkc 26>;
+};
+
+&lpd_dma_chan1 {
+ clocks = <&clkc 68>, <&clkc 31>;
+};
+
+&lpd_dma_chan2 {
+ clocks = <&clkc 68>, <&clkc 31>;
+};
+
+&lpd_dma_chan3 {
+ clocks = <&clkc 68>, <&clkc 31>;
+};
+
+&lpd_dma_chan4 {
+ clocks = <&clkc 68>, <&clkc 31>;
+};
+
+&lpd_dma_chan5 {
+ clocks = <&clkc 68>, <&clkc 31>;
+};
+
+&lpd_dma_chan6 {
+ clocks = <&clkc 68>, <&clkc 31>;
+};
+
+&lpd_dma_chan7 {
+ clocks = <&clkc 68>, <&clkc 31>;
+};
+
+&lpd_dma_chan8 {
+ clocks = <&clkc 68>, <&clkc 31>;
+};
+
+&nand0 {
+ clocks = <&clkc 60>, <&clkc 31>;
+};
+
+&gem0 {
+ clocks = <&clkc 31>, <&clkc 49>, <&clkc 45>, <&clkc 49>, <&clkc 44>;
+ clock-names = "pclk", "hclk", "tx_clk", "rx_clk", "tsu_clk";
+};
+
+&gem1 {
+ clocks = <&clkc 31>, <&clkc 50>, <&clkc 46>, <&clkc 50>, <&clkc 44>;
+ clock-names = "pclk", "hclk", "tx_clk", "rx_clk", "tsu_clk";
+};
+
+&gem2 {
+ clocks = <&clkc 31>, <&clkc 51>, <&clkc 47>, <&clkc 51>, <&clkc 44>;
+ clock-names = "pclk", "hclk", "tx_clk", "rx_clk", "tsu_clk";
+};
+
+&gem3 {
+ clocks = <&clkc 31>, <&clkc 52>, <&clkc 48>, <&clkc 52>, <&clkc 44>;
+ clock-names = "pclk", "hclk", "tx_clk", "rx_clk", "tsu_clk";
+};
+
+&gpio {
+ clocks = <&clkc 31>;
+};
+
+&i2c0 {
+ clocks = <&clkc 61>;
+};
+
+&i2c1 {
+ clocks = <&clkc 62>;
+};
+
+&pcie {
+ clocks = <&clkc 23>;
+};
+
+&qspi {
+ clocks = <&clkc 53>, <&clkc 31>;
+};
+
+&sata {
+ clocks = <&clkc 22>;
+};
+
+&sdhci0 {
+ clocks = <&clkc 54>, <&clkc 31>;
+};
+
+&sdhci1 {
+ clocks = <&clkc 55>, <&clkc 31>;
+};
+
+&spi0 {
+ clocks = <&clkc 58>, <&clkc 31>;
+};
+
+&spi1 {
+ clocks = <&clkc 59>, <&clkc 31>;
+};
+
+&uart0 {
+ clocks = <&clkc 56>, <&clkc 31>;
+};
+
+&uart1 {
+ clocks = <&clkc 57>, <&clkc 31>;
+};
+
+&usb0 {
+ clocks = <&clkc 32>, <&clkc 34>;
+};
+
+&usb1 {
+ clocks = <&clkc 33>, <&clkc 34>;
+};
+
+&watchdog0 {
+ clocks = <&clkc 75>;
+};
+
+&xilinx_ams {
+ clocks = <&clkc 70>;
+};
+
+&xilinx_drm {
+ clocks = <&clkc 16>;
+};
+
+&xlnx_dp {
+ clocks = <&dp_aclk>, <&clkc 17>;
+};
+
+&xlnx_dpdma {
+ clocks = <&clkc 20>;
+};
+
+&xlnx_dp_snd_codec0 {
+ clocks = <&clkc 17>;
+};
diff --git a/arch/arm/dts/zynqmp-ep108-clk.dtsi b/arch/arm/dts/zynqmp-ep108-clk.dtsi
deleted file mode 100644
index 12d9fe1498..0000000000
--- a/arch/arm/dts/zynqmp-ep108-clk.dtsi
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * clock specification for Xilinx ZynqMP ep108 development board
- *
- * (C) Copyright 2015, Xilinx, Inc.
- *
- * Michal Simek <michal.simek@xilinx.com>
- *
- * SPDX-License-Identifier: GPL-2.0+
- */
-
-/ {
- misc_clk: misc_clk {
- compatible = "fixed-clock";
- #clock-cells = <0>;
- clock-frequency = <25000000>;
- u-boot,dm-pre-reloc;
- };
-
- i2c_clk: i2c_clk {
- compatible = "fixed-clock";
- #clock-cells = <0x0>;
- clock-frequency = <111111111>;
- };
-
- sata_clk: sata_clk {
- compatible = "fixed-clock";
- #clock-cells = <0>;
- clock-frequency = <75000000>;
- };
-
- dp_aclk: clock0 {
- compatible = "fixed-clock";
- #clock-cells = <0>;
- clock-frequency = <50000000>;
- clock-accuracy = <100>;
- };
-
- clk100: clk100 {
- compatible = "fixed-clock";
- #clock-cells = <0>;
- clock-frequency = <100000000>;
- };
-
- clk600: clk600 {
- compatible = "fixed-clock";
- #clock-cells = <0>;
- clock-frequency = <600000000>;
- };
-
- dp_aud_clk: clock1 {
- compatible = "fixed-clock";
- #clock-cells = <0>;
- clock-frequency = <22579200>;
- clock-accuracy = <100>;
- };
-};
-
-&can0 {
- clocks = <&misc_clk &misc_clk>;
-};
-
-&can1 {
- clocks = <&misc_clk &misc_clk>;
-};
-
-&fpd_dma_chan1 {
- clocks = <&clk600>, <&clk100>;
-};
-
-&fpd_dma_chan2 {
- clocks = <&clk600>, <&clk100>;
-};
-
-&fpd_dma_chan3 {
- clocks = <&clk600>, <&clk100>;
-};
-
-&fpd_dma_chan4 {
- clocks = <&clk600>, <&clk100>;
-};
-
-&fpd_dma_chan5 {
- clocks = <&clk600>, <&clk100>;
-};
-
-&fpd_dma_chan6 {
- clocks = <&clk600>, <&clk100>;
-};
-
-&fpd_dma_chan7 {
- clocks = <&clk600>, <&clk100>;
-};
-
-&fpd_dma_chan8 {
- clocks = <&clk600>, <&clk100>;
-};
-
-&gem0 {
- clocks = <&misc_clk>, <&misc_clk>, <&misc_clk>;
-};
-
-&gpio {
- clocks = <&misc_clk>;
-};
-
-&i2c0 {
- clocks = <&i2c_clk>;
-};
-
-&i2c1 {
- clocks = <&i2c_clk>;
-};
-
-&nand0 {
- clocks = <&misc_clk &misc_clk>;
-};
-
-&qspi {
- clocks = <&misc_clk &misc_clk>;
-};
-
-&sata {
- clocks = <&sata_clk>;
-};
-
-&sdhci0 {
- clocks = <&misc_clk>, <&misc_clk>;
-};
-
-&sdhci1 {
- clocks = <&misc_clk>, <&misc_clk>;
-};
-
-&spi0 {
- clocks = <&misc_clk &misc_clk>;
-};
-
-&spi1 {
- clocks = <&misc_clk &misc_clk>;
-};
-
-&uart0 {
- clocks = <&misc_clk &misc_clk>;
-};
-
-&usb0 {
- clocks = <&misc_clk>, <&misc_clk>;
-};
-
-&usb1 {
- clocks = <&misc_clk>, <&misc_clk>;
-};
-
-&watchdog0 {
- clocks= <&misc_clk>;
-};
-
-&xilinx_drm {
- clocks = <&misc_clk>;
-};
-
-&xlnx_dp {
- clocks = <&dp_aclk>, <&dp_aud_clk>;
-};
-
-&xlnx_dp_snd_codec0 {
- clocks = <&dp_aud_clk>;
-};
-
-&xlnx_dpdma {
- clocks = <&misc_clk>;
-};
diff --git a/arch/arm/dts/zynqmp-ep108.dts b/arch/arm/dts/zynqmp-ep108.dts
deleted file mode 100644
index a16ffdc3f0..0000000000
--- a/arch/arm/dts/zynqmp-ep108.dts
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
- * dts file for Xilinx ZynqMP ep108 development board
- *
- * (C) Copyright 2014 - 2015, Xilinx, Inc.
- *
- * Michal Simek <michal.simek@xilinx.com>
- *
- * SPDX-License-Identifier: GPL-2.0+
- */
-
-/dts-v1/;
-
-#include "zynqmp.dtsi"
-#include "zynqmp-ep108-clk.dtsi"
-
-/ {
- model = "ZynqMP EP108";
-
- aliases {
- ethernet0 = &gem0;
- mmc0 = &sdhci0;
- mmc1 = &sdhci1;
- serial0 = &uart0;
- spi0 = &qspi;
- spi1 = &spi0;
- spi2 = &spi1;
- usb0 = &usb0;
- usb1 = &usb1;
- };
-
- chosen {
- bootargs = "earlycon";
- stdout-path = "serial0:115200n8";
- };
-
- memory@0 {
- device_type = "memory";
- reg = <0x0 0x0 0x0 0x40000000>;
- };
-};
-
-&can0 {
- status = "okay";
-};
-
-&can1 {
- status = "okay";
-};
-
-&gem0 {
- status = "okay";
- phy-handle = <&phy0>;
- phy-mode = "rgmii-id";
- phy0: phy@0 {
- reg = <0>;
- max-speed = <100>;
- };
-};
-
-&gpio {
- status = "okay";
-};
-
-&i2c0 {
- status = "okay";
- clock-frequency = <400000>;
- eeprom@54 {
- compatible = "atmel,24c64";
- reg = <0x54>;
- };
-};
-
-&i2c1 {
- status = "okay";
- clock-frequency = <400000>;
- eeprom@55 {
- compatible = "atmel,24c64";
- reg = <0x55>;
- };
-};
-
-&nand0 {
- status = "okay";
- arasan,has-mdma;
- num-cs = <1>;
-
- partition@0 { /* for testing purpose */
- label = "nand-fsbl-uboot";
- reg = <0x0 0x0 0x400000>;
- };
- partition@1 { /* for testing purpose */
- label = "nand-linux";
- reg = <0x0 0x400000 0x1400000>;
- };
- partition@2 { /* for testing purpose */
- label = "nand-device-tree";
- reg = <0x0 0x1800000 0x400000>;
- };
- partition@3 { /* for testing purpose */
- label = "nand-rootfs";
- reg = <0x0 0x1C00000 0x1400000>;
- };
- partition@4 { /* for testing purpose */
- label = "nand-bitstream";
- reg = <0x0 0x3000000 0x400000>;
- };
- partition@5 { /* for testing purpose */
- label = "nand-misc";
- reg = <0x0 0x3400000 0xFCC00000>;
- };
-};
-
-&qspi {
- status = "okay";
- flash@0 {
- compatible = "m25p80";
- #address-cells = <1>;
- #size-cells = <1>;
- reg = <0x0>;
- spi-tx-bus-width = <1>;
- spi-rx-bus-width = <4>;
- spi-max-frequency = <10000000>;
- partition@qspi-fsbl-uboot { /* for testing purpose */
- label = "qspi-fsbl-uboot";
- reg = <0x0 0x100000>;
- };
- partition@qspi-linux { /* for testing purpose */
- label = "qspi-linux";
- reg = <0x100000 0x500000>;
- };
- partition@qspi-device-tree { /* for testing purpose */
- label = "qspi-device-tree";
- reg = <0x600000 0x20000>;
- };
- partition@qspi-rootfs { /* for testing purpose */
- label = "qspi-rootfs";
- reg = <0x620000 0x5E0000>;
- };
- };
-};
-
-&sata {
- status = "okay";
- ceva,broken-gen2;
- /* SATA Phy OOB timing settings */
- ceva,p0-cominit-params = /bits/ 8 <0x0F 0x25 0x18 0x29>;
- ceva,p0-comwake-params = /bits/ 8 <0x04 0x0B 0x08 0x0F>;
- ceva,p0-burst-params = /bits/ 8 <0x0A 0x08 0x4A 0x06>;
- ceva,p0-retry-params = /bits/ 16 <0x0216 0x7F06>;
- ceva,p1-cominit-params = /bits/ 8 <0x0F 0x25 0x18 0x29>;
- ceva,p1-comwake-params = /bits/ 8 <0x04 0x0B 0x08 0x0F>;
- ceva,p1-burst-params = /bits/ 8 <0x0A 0x08 0x4A 0x06>;
- ceva,p1-retry-params = /bits/ 16 <0x0216 0x7F06>;
-};
-
-&sdhci0 {
- status = "okay";
- bus-width = <8>;
- xlnx,mio_bank = <2>;
-};
-
-&sdhci1 {
- status = "okay";
- xlnx,mio_bank = <1>;
-};
-
-&spi0 {
- status = "okay";
- num-cs = <1>;
- spi0_flash0: spi0_flash0@0 {
- compatible = "m25p80";
- #address-cells = <1>;
- #size-cells = <1>;
- spi-max-frequency = <50000000>;
- reg = <0>;
-
- spi0_flash0@0 {
- label = "spi0_flash0";
- reg = <0x0 0x100000>;
- };
- };
-};
-
-&spi1 {
- status = "okay";
- num-cs = <1>;
- spi1_flash0: spi1_flash0@0 {
- compatible = "m25p80";
- #address-cells = <1>;
- #size-cells = <1>;
- spi-max-frequency = <50000000>;
- reg = <0>;
-
- spi1_flash0@0 {
- label = "spi1_flash0";
- reg = <0x0 0x100000>;
- };
- };
-};
-
-&uart0 {
- status = "okay";
-};
-
-&usb0 {
- status = "okay";
-};
-
-&dwc3_0 {
- status = "okay";
- dr_mode = "peripheral";
- maximum-speed = "high-speed";
-};
-
-&usb1 {
- status = "okay";
-};
-
-&dwc3_1 {
- status = "okay";
- dr_mode = "host";
- maximum-speed = "high-speed";
-};
-
-&watchdog0 {
- status = "okay";
-};
-
-&xlnx_dp {
- xlnx,max-pclock-frequency = <200000>;
-};
-
-&xlnx_dpdma {
- xlnx,axi-clock-freq = <200000000>;
-};
diff --git a/arch/arm/dts/zynqmp-zc1751-xm015-dc1.dts b/arch/arm/dts/zynqmp-zc1751-xm015-dc1.dts
index 04d82c4d2e..9062ffe919 100644
--- a/arch/arm/dts/zynqmp-zc1751-xm015-dc1.dts
+++ b/arch/arm/dts/zynqmp-zc1751-xm015-dc1.dts
@@ -11,7 +11,7 @@
/dts-v1/;
#include "zynqmp.dtsi"
-#include "zynqmp-clk.dtsi"
+#include "zynqmp-clk-ccf.dtsi"
/ {
model = "ZynqMP zc1751-xm015-dc1 RevA";
diff --git a/arch/arm/dts/zynqmp-zc1751-xm016-dc2.dts b/arch/arm/dts/zynqmp-zc1751-xm016-dc2.dts
index 7dfe960135..bf43bf8748 100644
--- a/arch/arm/dts/zynqmp-zc1751-xm016-dc2.dts
+++ b/arch/arm/dts/zynqmp-zc1751-xm016-dc2.dts
@@ -11,7 +11,7 @@
/dts-v1/;
#include "zynqmp.dtsi"
-#include "zynqmp-clk.dtsi"
+#include "zynqmp-clk-ccf.dtsi"
/ {
model = "ZynqMP zc1751-xm016-dc2 RevA";
diff --git a/arch/arm/dts/zynqmp-zc1751-xm018-dc4.dts b/arch/arm/dts/zynqmp-zc1751-xm018-dc4.dts
index 648e3ba799..39c82c592f 100644
--- a/arch/arm/dts/zynqmp-zc1751-xm018-dc4.dts
+++ b/arch/arm/dts/zynqmp-zc1751-xm018-dc4.dts
@@ -11,7 +11,7 @@
/dts-v1/;
#include "zynqmp.dtsi"
-#include "zynqmp-clk.dtsi"
+#include "zynqmp-clk-ccf.dtsi"
/ {
model = "ZynqMP zc1751-xm018-dc4";
diff --git a/arch/arm/dts/zynqmp-zc1751-xm019-dc5.dts b/arch/arm/dts/zynqmp-zc1751-xm019-dc5.dts
index f3020a5760..c774b866fb 100644
--- a/arch/arm/dts/zynqmp-zc1751-xm019-dc5.dts
+++ b/arch/arm/dts/zynqmp-zc1751-xm019-dc5.dts
@@ -12,7 +12,7 @@
/dts-v1/;
#include "zynqmp.dtsi"
-#include "zynqmp-clk.dtsi"
+#include "zynqmp-clk-ccf.dtsi"
/ {
model = "ZynqMP zc1751-xm019-dc5 RevA";
compatible = "xlnx,zynqmp-zc1751", "xlnx,zynqmp";
diff --git a/arch/arm/dts/zynqmp-zcu102-revA.dts b/arch/arm/dts/zynqmp-zcu102-revA.dts
index 64a883b96e..2be6eb0eb5 100644
--- a/arch/arm/dts/zynqmp-zcu102-revA.dts
+++ b/arch/arm/dts/zynqmp-zcu102-revA.dts
@@ -11,7 +11,7 @@
/dts-v1/;
#include "zynqmp.dtsi"
-#include "zynqmp-clk.dtsi"
+#include "zynqmp-clk-ccf.dtsi"
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/pinctrl/pinctrl-zynqmp.h>
#include <dt-bindings/phy/phy.h>
diff --git a/arch/arm/include/asm/arch-zynqmp/sys_proto.h b/arch/arm/include/asm/arch-zynqmp/sys_proto.h
index 084d55a2b0..ad3dc9aba5 100644
--- a/arch/arm/include/asm/arch-zynqmp/sys_proto.h
+++ b/arch/arm/include/asm/arch-zynqmp/sys_proto.h
@@ -11,6 +11,8 @@
#define PAYLOAD_ARG_CNT 5
#define ZYNQMP_CSU_SILICON_VER_MASK 0xF
+#define ZYNQMP_SIP_SVC_PM_SECURE_IMG_LOAD 0xC200002D
+#define KEY_PTR_LEN 32
enum {
IDCODE,
diff --git a/board/synopsys/axs10x/axs10x.c b/board/synopsys/axs10x/axs10x.c
index e6b69da3da..18f7666b15 100644
--- a/board/synopsys/axs10x/axs10x.c
+++ b/board/synopsys/axs10x/axs10x.c
@@ -47,6 +47,18 @@ int board_early_init_f(void)
}
#ifdef CONFIG_ISA_ARCV2
+
+void board_jump_and_run(ulong entry, int zero, int arch, uint params)
+{
+ void (*kernel_entry)(int zero, int arch, uint params);
+
+ kernel_entry = (void (*)(int, int, uint))entry;
+
+ smp_set_core_boot_addr(entry, -1);
+ smp_kick_all_cpus();
+ kernel_entry(zero, arch, params);
+}
+
#define RESET_VECTOR_ADDR 0x0
void smp_set_core_boot_addr(unsigned long addr, int corenr)
diff --git a/board/synopsys/hsdk/hsdk.c b/board/synopsys/hsdk/hsdk.c
index 7641978a7b..5b3a063b69 100644
--- a/board/synopsys/hsdk/hsdk.c
+++ b/board/synopsys/hsdk/hsdk.c
@@ -58,6 +58,17 @@ int board_mmc_init(bd_t *bis)
return 0;
}
+void board_jump_and_run(ulong entry, int zero, int arch, uint params)
+{
+ void (*kernel_entry)(int zero, int arch, uint params);
+
+ kernel_entry = (void (*)(int, int, uint))entry;
+
+ smp_set_core_boot_addr(entry, -1);
+ smp_kick_all_cpus();
+ kernel_entry(zero, arch, params);
+}
+
#define RESET_VECTOR_ADDR 0x0
void smp_set_core_boot_addr(unsigned long addr, int corenr)
diff --git a/board/xilinx/zynq/MAINTAINERS b/board/xilinx/zynq/MAINTAINERS
index e0dc4fed48..fc6463a8c6 100644
--- a/board/xilinx/zynq/MAINTAINERS
+++ b/board/xilinx/zynq/MAINTAINERS
@@ -1,6 +1,7 @@
ZYNQ BOARD
M: Michal Simek <monstr@monstr.eu>
S: Maintained
+F: arch/arm/dts/zynq-*
F: board/xilinx/zynq/
F: include/configs/zynq*.h
F: configs/zynq_*_defconfig
diff --git a/board/xilinx/zynq/board.c b/board/xilinx/zynq/board.c
index fb8eab07d7..838ac0f4c4 100644
--- a/board/xilinx/zynq/board.c
+++ b/board/xilinx/zynq/board.c
@@ -6,9 +6,11 @@
*/
#include <common.h>
+#include <dm/uclass.h>
#include <fdtdec.h>
#include <fpga.h>
#include <mmc.h>
+#include <wdt.h>
#include <zynqpl.h>
#include <asm/arch/hardware.h>
#include <asm/arch/sys_proto.h>
@@ -33,6 +35,22 @@ static xilinx_desc fpga045 = XILINX_XC7Z045_DESC(0x45);
static xilinx_desc fpga100 = XILINX_XC7Z100_DESC(0x100);
#endif
+#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_WDT)
+static struct udevice *watchdog_dev;
+#endif
+
+#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_BOARD_EARLY_INIT_F)
+int board_early_init_f(void)
+{
+# if defined(CONFIG_WDT)
+ /* bss is not cleared at time when watchdog_reset() is called */
+ watchdog_dev = NULL;
+# endif
+
+ return 0;
+}
+#endif
+
int board_init(void)
{
#if (defined(CONFIG_FPGA) && !defined(CONFIG_SPL_BUILD)) || \
@@ -75,6 +93,15 @@ 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");
+ }
+# endif
+
#if (defined(CONFIG_FPGA) && !defined(CONFIG_SPL_BUILD)) || \
(defined(CONFIG_SPL_FPGA_SUPPORT) && defined(CONFIG_SPL_BUILD))
fpga_init();
@@ -164,3 +191,25 @@ int dram_init(void)
return 0;
}
#endif
+
+#if defined(CONFIG_WATCHDOG)
+/* Called by macro WATCHDOG_RESET */
+void watchdog_reset(void)
+{
+# if !defined(CONFIG_SPL_BUILD)
+ static ulong next_reset;
+ ulong now;
+
+ 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
+}
+#endif
diff --git a/board/xilinx/zynqmp/Kconfig b/board/xilinx/zynqmp/Kconfig
new file mode 100644
index 0000000000..7d1f7398c3
--- /dev/null
+++ b/board/xilinx/zynqmp/Kconfig
@@ -0,0 +1,18 @@
+# Copyright (c) 2018, Xilinx, Inc.
+#
+# SPDX-License-Identifier: GPL-2.0
+
+if ARCH_ZYNQMP
+
+config CMD_ZYNQMP
+ bool "Enable ZynqMP specific commands"
+ default y
+ help
+ Enable ZynqMP specific commands like "zynqmp secure"
+ which is used for zynqmp 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/zynqmp/MAINTAINERS b/board/xilinx/zynqmp/MAINTAINERS
index 69edbf21f9..bb39f875fe 100644
--- a/board/xilinx/zynqmp/MAINTAINERS
+++ b/board/xilinx/zynqmp/MAINTAINERS
@@ -1,6 +1,7 @@
XILINX_ZYNQMP BOARDS
M: Michal Simek <michal.simek@xilinx.com>
S: Maintained
+F: arch/arm/dts/zynqmp-*
F: board/xilinx/zynqmp/
F: include/configs/xilinx_zynqmp*
F: configs/xilinx_zynqmp*
diff --git a/board/xilinx/zynqmp/Makefile b/board/xilinx/zynqmp/Makefile
index 75aab92f04..3b7a10e202 100644
--- a/board/xilinx/zynqmp/Makefile
+++ b/board/xilinx/zynqmp/Makefile
@@ -26,6 +26,10 @@ ifneq ($(call ifdef_any_of, CONFIG_ZYNQMP_PSU_INIT_ENABLED CONFIG_SPL_BUILD),)
obj-y += $(init-objs)
endif
+ifndef CONFIG_SPL_BUILD
+obj-$(CONFIG_CMD_ZYNQMP) += cmds.o
+endif
+
# Suppress "warning: function declaration isn't a prototype"
CFLAGS_REMOVE_psu_init_gpl.o := -Wstrict-prototypes
diff --git a/board/xilinx/zynqmp/cmds.c b/board/xilinx/zynqmp/cmds.c
new file mode 100644
index 0000000000..6712d7b8cf
--- /dev/null
+++ b/board/xilinx/zynqmp/cmds.c
@@ -0,0 +1,105 @@
+/*
+ * (C) Copyright 2018 Xilinx, Inc.
+ * Siva Durga Prasad Paladugu <siva.durga.paladugu@xilinx.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/io.h>
+
+static int zynqmp_verify_secure(u8 *key_ptr, u8 *src_ptr, u32 len)
+{
+ 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);
+ 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));
+
+ if (key_ptr) {
+ key_lo = lower_32_bits((ulong)key_ptr);
+ key_hi = upper_32_bits((ulong)key_ptr);
+ flush_dcache_range((ulong)key_ptr,
+ (ulong)(key_ptr + KEY_PTR_LEN));
+ }
+
+ ret = invoke_smc(ZYNQMP_SIP_SVC_PM_SECURE_IMG_LOAD, src_lo, src_hi,
+ key_lo, key_hi, ret_payload);
+ if (ret) {
+ printf("Failed: secure op status:0x%x\n", ret);
+ } else {
+ addr = (u64)ret_payload[1] << 32 | ret_payload[2];
+ printf("Verified image at 0x%llx\n", addr);
+ env_set_hex("zynqmp_verified_img_addr", addr);
+ }
+
+ return ret;
+}
+
+/**
+ * do_zynqmp - Handle the "zynqmp" command-line command
+ * @cmdtp: Command data struct pointer
+ * @flag: Command flag
+ * @argc: Command-line argument count
+ * @argv: Array of command-line arguments
+ *
+ * Processes the zynqmp specific commands
+ *
+ * Return: return 0 on success and CMD_RET_USAGE incase of misuse and error
+ */
+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;
+
+ if (argc > 5 || argc < 4 || strncmp(argv[1], "secure", 6))
+ 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;
+
+ ret = zynqmp_verify_secure(key_ptr, src_ptr, len);
+ if (ret)
+ return CMD_RET_FAILURE;
+
+ return CMD_RET_SUCCESS;
+}
+
+/***************************************************/
+#ifdef CONFIG_SYS_LONGHELP
+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";
+#endif
+
+U_BOOT_CMD(
+ zynqmp, 5, 1, do_zynqmp,
+ "Verify and load secure images",
+ zynqmp_help_text
+)
diff --git a/board/xilinx/zynqmp/zynqmp.c b/board/xilinx/zynqmp/zynqmp.c
index ff0b3c75f5..0d1bd5412b 100644
--- a/board/xilinx/zynqmp/zynqmp.c
+++ b/board/xilinx/zynqmp/zynqmp.c
@@ -31,6 +31,7 @@ static const struct {
u32 id;
u32 ver;
char *name;
+ bool evexists;
} zynqmp_devices[] = {
{
.id = 0x10,
@@ -53,11 +54,13 @@ static const struct {
{
.id = 0x20,
.name = "5ev",
+ .evexists = 1,
},
{
.id = 0x20,
.ver = 0x100,
.name = "5eg",
+ .evexists = 1,
},
{
.id = 0x20,
@@ -67,11 +70,13 @@ static const struct {
{
.id = 0x21,
.name = "4ev",
+ .evexists = 1,
},
{
.id = 0x21,
.ver = 0x100,
.name = "4eg",
+ .evexists = 1,
},
{
.id = 0x21,
@@ -81,11 +86,13 @@ static const struct {
{
.id = 0x30,
.name = "7ev",
+ .evexists = 1,
},
{
.id = 0x30,
.ver = 0x100,
.name = "7eg",
+ .evexists = 1,
},
{
.id = 0x30,
@@ -219,20 +226,48 @@ int chip_id(unsigned char id)
return val;
}
+#define ZYNQMP_VERSION_SIZE 9
+#define ZYNQMP_PL_STATUS_BIT 9
+#define ZYNQMP_PL_STATUS_MASK BIT(ZYNQMP_PL_STATUS_BIT)
+#define ZYNQMP_CSU_VERSION_MASK ~(ZYNQMP_PL_STATUS_MASK)
+
#if defined(CONFIG_FPGA) && defined(CONFIG_FPGA_ZYNQMPPL) && \
!defined(CONFIG_SPL_BUILD)
static char *zynqmp_get_silicon_idcode_name(void)
{
u32 i, id, ver;
+ char *buf;
+ static char name[ZYNQMP_VERSION_SIZE];
id = chip_id(IDCODE);
ver = chip_id(IDCODE2);
for (i = 0; i < ARRAY_SIZE(zynqmp_devices); i++) {
- if (zynqmp_devices[i].id == id && zynqmp_devices[i].ver == ver)
- return zynqmp_devices[i].name;
+ if ((zynqmp_devices[i].id == id) &&
+ (zynqmp_devices[i].ver == (ver &
+ ZYNQMP_CSU_VERSION_MASK))) {
+ strncat(name, "zu", 2);
+ strncat(name, zynqmp_devices[i].name,
+ ZYNQMP_VERSION_SIZE - 3);
+ break;
+ }
+ }
+
+ if (i >= ARRAY_SIZE(zynqmp_devices))
+ return "unknown";
+
+ if (!zynqmp_devices[i].evexists)
+ return name;
+
+ if (ver & ZYNQMP_PL_STATUS_MASK)
+ return name;
+
+ if (strstr(name, "eg") || strstr(name, "ev")) {
+ buf = strstr(name, "e");
+ *buf = '\0';
}
- return "unknown";
+
+ return name;
}
#endif
@@ -250,8 +285,6 @@ int board_early_init_f(void)
return ret;
}
-#define ZYNQMP_VERSION_SIZE 9
-
int board_init(void)
{
printf("EL Level:\tEL%d\n", current_el());
@@ -260,12 +293,7 @@ int board_init(void)
!defined(CONFIG_SPL_BUILD) || (defined(CONFIG_SPL_FPGA_SUPPORT) && \
defined(CONFIG_SPL_BUILD))
if (current_el() != 3) {
- static char version[ZYNQMP_VERSION_SIZE];
-
- strncat(version, "zu", 2);
- zynqmppl.name = strncat(version,
- zynqmp_get_silicon_idcode_name(),
- ZYNQMP_VERSION_SIZE - 3);
+ zynqmppl.name = zynqmp_get_silicon_idcode_name();
printf("Chip ID:\t%s\n", zynqmppl.name);
fpga_init();
fpga_add(fpga_xilinx, &zynqmppl);
@@ -316,6 +344,23 @@ int zynq_board_read_rom_ethaddr(unsigned char *ethaddr)
return 0;
}
+unsigned long do_go_exec(ulong (*entry)(int, char * const []), int argc,
+ char * const argv[])
+{
+ int ret = 0;
+
+ if (current_el() > 1) {
+ smp_kick_all_cpus();
+ dcache_disable();
+ armv8_switch_to_el1(0x0, 0, 0, 0, (unsigned long)entry,
+ ES_TO_AARCH64);
+ } else {
+ printf("FAIL: current EL is not above EL1\n");
+ ret = EINVAL;
+ }
+ return ret;
+}
+
#if !defined(CONFIG_SYS_SDRAM_BASE) && !defined(CONFIG_SYS_SDRAM_SIZE)
int dram_init_banksize(void)
{
diff --git a/common/board_f.c b/common/board_f.c
index 62588c5bad..ae8bdb7c5c 100644
--- a/common/board_f.c
+++ b/common/board_f.c
@@ -900,7 +900,8 @@ void board_init_f(ulong boot_flags)
hang();
#if !defined(CONFIG_ARM) && !defined(CONFIG_SANDBOX) && \
- !defined(CONFIG_EFI_APP) && !CONFIG_IS_ENABLED(X86_64)
+ !defined(CONFIG_EFI_APP) && !CONFIG_IS_ENABLED(X86_64) && \
+ !defined(CONFIG_ARC)
/* NOTREACHED - jump_to_copy() does not return */
hang();
#endif
diff --git a/configs/microblaze-generic_defconfig b/configs/microblaze-generic_defconfig
index 699dc447f0..18bec1f2e5 100644
--- a/configs/microblaze-generic_defconfig
+++ b/configs/microblaze-generic_defconfig
@@ -3,6 +3,7 @@ CONFIG_SYS_TEXT_BASE=0x29000000
CONFIG_SPL_LIBCOMMON_SUPPORT=y
CONFIG_SPL_LIBGENERIC_SUPPORT=y
CONFIG_SPL_SERIAL_SUPPORT=y
+CONFIG_SPL=y
CONFIG_TARGET_MICROBLAZE_GENERIC=y
CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR=1
CONFIG_XILINX_MICROBLAZE0_USE_BARREL=1
@@ -15,7 +16,6 @@ CONFIG_BOOTDELAY=-1
CONFIG_USE_BOOTARGS=y
CONFIG_BOOTARGS="root=romfs"
CONFIG_SYS_CONSOLE_IS_IN_ENV=y
-CONFIG_SPL=y
CONFIG_SPL_BOARD_INIT=y
CONFIG_SPL_SYS_MALLOC_SIMPLE=y
CONFIG_SPL_NOR_SUPPORT=y
diff --git a/configs/syzygy_hub_defconfig b/configs/syzygy_hub_defconfig
index 67d1f545d7..005cb9ce2e 100644
--- a/configs/syzygy_hub_defconfig
+++ b/configs/syzygy_hub_defconfig
@@ -3,6 +3,7 @@ CONFIG_SYS_VENDOR="opalkelly"
CONFIG_SYS_CONFIG_NAME="syzygy_hub"
CONFIG_ARCH_ZYNQ=y
CONFIG_SYS_TEXT_BASE=0x4000000
+CONFIG_SPL=y
CONFIG_SPL_STACK_R_ADDR=0x200000
CONFIG_DEFAULT_DEVICE_TREE="zynq-syzygy-hub"
CONFIG_DEBUG_UART=y
@@ -12,7 +13,6 @@ CONFIG_FIT_SIGNATURE=y
CONFIG_FIT_VERBOSE=y
CONFIG_BOOTCOMMAND="run $modeboot || run distro_bootcmd"
# CONFIG_DISPLAY_CPUINFO is not set
-CONFIG_SPL=y
CONFIG_SPL_STACK_R=y
CONFIG_SPL_OS_BOOT=y
CONFIG_SYS_PROMPT="Zynq> "
diff --git a/configs/topic_miami_defconfig b/configs/topic_miami_defconfig
index 8b02599b26..2dd938d09a 100644
--- a/configs/topic_miami_defconfig
+++ b/configs/topic_miami_defconfig
@@ -3,6 +3,7 @@ CONFIG_SYS_VENDOR="topic"
CONFIG_SYS_CONFIG_NAME="topic_miami"
CONFIG_ARCH_ZYNQ=y
CONFIG_SYS_TEXT_BASE=0x4000000
+CONFIG_SPL=y
CONFIG_SPL_STACK_R_ADDR=0x200000
CONFIG_BOOT_INIT_FILE="board/topic/zynq/zynq-topic-miami/ps7_regs.txt"
CONFIG_DEFAULT_DEVICE_TREE="zynq-topic-miami"
@@ -11,7 +12,6 @@ CONFIG_DISTRO_DEFAULTS=y
CONFIG_BOOTDELAY=0
CONFIG_BOOTCOMMAND="run $modeboot || run distro_bootcmd"
# CONFIG_DISPLAY_CPUINFO is not set
-CONFIG_SPL=y
CONFIG_SPL_STACK_R=y
CONFIG_SYS_PROMPT="zynq-uboot> "
CONFIG_CMD_THOR_DOWNLOAD=y
diff --git a/configs/topic_miamilite_defconfig b/configs/topic_miamilite_defconfig
index 572b2f5149..638cc34ac9 100644
--- a/configs/topic_miamilite_defconfig
+++ b/configs/topic_miamilite_defconfig
@@ -3,6 +3,7 @@ CONFIG_SYS_VENDOR="topic"
CONFIG_SYS_CONFIG_NAME="topic_miami"
CONFIG_ARCH_ZYNQ=y
CONFIG_SYS_TEXT_BASE=0x4000000
+CONFIG_SPL=y
CONFIG_SPL_STACK_R_ADDR=0x200000
CONFIG_BOOT_INIT_FILE="board/topic/zynq/zynq-topic-miamilite/ps7_regs.txt"
CONFIG_DEFAULT_DEVICE_TREE="zynq-topic-miamilite"
@@ -11,7 +12,6 @@ CONFIG_DISTRO_DEFAULTS=y
CONFIG_BOOTDELAY=0
CONFIG_BOOTCOMMAND="run $modeboot || run distro_bootcmd"
# CONFIG_DISPLAY_CPUINFO is not set
-CONFIG_SPL=y
CONFIG_SPL_STACK_R=y
CONFIG_SYS_PROMPT="zynq-uboot> "
CONFIG_CMD_THOR_DOWNLOAD=y
diff --git a/configs/topic_miamiplus_defconfig b/configs/topic_miamiplus_defconfig
index 3e8504d6a0..ef91bd5825 100644
--- a/configs/topic_miamiplus_defconfig
+++ b/configs/topic_miamiplus_defconfig
@@ -3,6 +3,7 @@ CONFIG_SYS_VENDOR="topic"
CONFIG_SYS_CONFIG_NAME="topic_miami"
CONFIG_ARCH_ZYNQ=y
CONFIG_SYS_TEXT_BASE=0x4000000
+CONFIG_SPL=y
CONFIG_SPL_STACK_R_ADDR=0x200000
CONFIG_BOOT_INIT_FILE="board/topic/zynq/zynq-topic-miamiplus/ps7_regs.txt"
CONFIG_DEFAULT_DEVICE_TREE="zynq-topic-miamiplus"
@@ -11,7 +12,6 @@ CONFIG_DISTRO_DEFAULTS=y
CONFIG_BOOTDELAY=0
CONFIG_BOOTCOMMAND="run $modeboot || run distro_bootcmd"
# CONFIG_DISPLAY_CPUINFO is not set
-CONFIG_SPL=y
CONFIG_SPL_STACK_R=y
CONFIG_SYS_PROMPT="zynq-uboot> "
CONFIG_CMD_THOR_DOWNLOAD=y
diff --git a/configs/xilinx_zynqmp_ep_defconfig b/configs/xilinx_zynqmp_ep_defconfig
deleted file mode 100644
index a0c8f28b97..0000000000
--- a/configs/xilinx_zynqmp_ep_defconfig
+++ /dev/null
@@ -1,102 +0,0 @@
-CONFIG_ARM=y
-CONFIG_SYS_CONFIG_NAME="xilinx_zynqmp_ep"
-CONFIG_ARCH_ZYNQMP=y
-CONFIG_SYS_TEXT_BASE=0x8000000
-CONFIG_SYS_MALLOC_F_LEN=0x8000
-CONFIG_ZYNQ_SDHCI_MAX_FREQ=52000000
-CONFIG_ZYNQMP_USB=y
-CONFIG_DEFAULT_DEVICE_TREE="zynqmp-ep108"
-CONFIG_DEBUG_UART=y
-CONFIG_AHCI=y
-CONFIG_DISTRO_DEFAULTS=y
-CONFIG_FIT=y
-CONFIG_FIT_VERBOSE=y
-CONFIG_SPL_LOAD_FIT=y
-# CONFIG_DISPLAY_CPUINFO is not set
-# CONFIG_DISPLAY_BOARDINFO is not set
-CONFIG_SPL=y
-CONFIG_SPL_OS_BOOT=y
-CONFIG_SYS_PROMPT="ZynqMP> "
-CONFIG_FASTBOOT=y
-CONFIG_FASTBOOT_FLASH=y
-CONFIG_FASTBOOT_FLASH_MMC_DEV=0
-# CONFIG_CMD_CONSOLE is not set
-# CONFIG_CMD_XIMG is not set
-CONFIG_CMD_THOR_DOWNLOAD=y
-# CONFIG_CMD_EDITENV is not set
-# CONFIG_CMD_ENV_EXISTS is not set
-CONFIG_CMD_CLK=y
-CONFIG_CMD_DFU=y
-# CONFIG_CMD_FPGA is not set
-CONFIG_CMD_GPIO=y
-CONFIG_CMD_GPT=y
-CONFIG_CMD_I2C=y
-# CONFIG_CMD_LOADB is not set
-# CONFIG_CMD_LOADS is not set
-CONFIG_CMD_MMC=y
-CONFIG_CMD_NAND_LOCK_UNLOCK=y
-CONFIG_CMD_USB=y
-# CONFIG_CMD_ITEST is not set
-# CONFIG_CMD_SETEXPR is not set
-CONFIG_CMD_TFTPPUT=y
-# CONFIG_CMD_NFS is not set
-CONFIG_CMD_TIME=y
-CONFIG_CMD_TIMER=y
-CONFIG_CMD_EXT4_WRITE=y
-# CONFIG_SPL_ISO_PARTITION is not set
-CONFIG_SPL_OF_CONTROL=y
-CONFIG_OF_EMBED=y
-CONFIG_ENV_IS_IN_FAT=y
-CONFIG_NET_RANDOM_ETHADDR=y
-CONFIG_SPL_DM=y
-CONFIG_SPL_DM_SEQ_ALIAS=y
-CONFIG_SCSI_AHCI=y
-CONFIG_SATA_CEVA=y
-CONFIG_DFU_RAM=y
-CONFIG_FPGA_XILINX=y
-CONFIG_FPGA_ZYNQMPPL=y
-CONFIG_DM_GPIO=y
-CONFIG_DM_I2C=y
-CONFIG_SYS_I2C_CADENCE=y
-CONFIG_MISC=y
-CONFIG_DM_MMC=y
-CONFIG_MMC_SDHCI=y
-CONFIG_MMC_SDHCI_ZYNQ=y
-CONFIG_ZYNQ_SDHCI_MIN_FREQ=100000
-CONFIG_NAND=y
-CONFIG_NAND_ARASAN=y
-CONFIG_SPI_FLASH=y
-CONFIG_SPI_FLASH_BAR=y
-CONFIG_SPI_FLASH_SPANSION=y
-CONFIG_SPI_FLASH_STMICRO=y
-CONFIG_SPI_FLASH_WINBOND=y
-# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set
-CONFIG_PHY_MARVELL=y
-CONFIG_PHY_NATSEMI=y
-CONFIG_PHY_REALTEK=y
-CONFIG_PHY_TI=y
-CONFIG_PHY_VITESSE=y
-CONFIG_DM_ETH=y
-CONFIG_PHY_GIGE=y
-CONFIG_ZYNQ_GEM=y
-CONFIG_SCSI=y
-CONFIG_DM_SCSI=y
-CONFIG_DEBUG_UART_ZYNQ=y
-CONFIG_DEBUG_UART_BASE=0xff000000
-CONFIG_DEBUG_UART_CLOCK=25000000
-CONFIG_DEBUG_UART_ANNOUNCE=y
-CONFIG_ZYNQ_SERIAL=y
-CONFIG_USB=y
-CONFIG_USB_XHCI_HCD=y
-CONFIG_USB_XHCI_DWC3=y
-CONFIG_USB_XHCI_ZYNQMP=y
-CONFIG_USB_DWC3=y
-CONFIG_USB_DWC3_GADGET=y
-CONFIG_USB_STORAGE=y
-CONFIG_USB_GADGET=y
-CONFIG_USB_GADGET_MANUFACTURER="Xilinx"
-CONFIG_USB_GADGET_VENDOR_NUM=0x03fd
-CONFIG_USB_GADGET_PRODUCT_NUM=0x0300
-CONFIG_USB_FUNCTION_THOR=y
-# CONFIG_REGEX is not set
-CONFIG_EFI_LOADER_BOUNCE_BUFFER=y
diff --git a/configs/xilinx_zynqmp_mini_emmc_defconfig b/configs/xilinx_zynqmp_mini_emmc_defconfig
index b15120e0fa..8f2596a894 100644
--- a/configs/xilinx_zynqmp_mini_emmc_defconfig
+++ b/configs/xilinx_zynqmp_mini_emmc_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_CMD_ZYNQMP is not set
CONFIG_DEFAULT_DEVICE_TREE="zynqmp-mini-emmc"
CONFIG_ENV_VARS_UBOOT_CONFIG=y
CONFIG_FIT=y
diff --git a/configs/xilinx_zynqmp_mini_nand_defconfig b/configs/xilinx_zynqmp_mini_nand_defconfig
index 55200bcb05..1fec9bab7c 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_CMD_ZYNQMP is not set
CONFIG_DEFAULT_DEVICE_TREE="zynqmp-mini-nand"
CONFIG_ENV_VARS_UBOOT_CONFIG=y
CONFIG_FIT=y
diff --git a/configs/xilinx_zynqmp_zc1751_xm015_dc1_defconfig b/configs/xilinx_zynqmp_zc1751_xm015_dc1_defconfig
index 7da0ca8789..1125ebda8a 100644
--- a/configs/xilinx_zynqmp_zc1751_xm015_dc1_defconfig
+++ b/configs/xilinx_zynqmp_zc1751_xm015_dc1_defconfig
@@ -3,6 +3,7 @@ CONFIG_SYS_CONFIG_NAME="xilinx_zynqmp_zc1751_xm015_dc1"
CONFIG_ARCH_ZYNQMP=y
CONFIG_SYS_TEXT_BASE=0x8000000
CONFIG_SYS_MALLOC_F_LEN=0x8000
+CONFIG_SPL=y
CONFIG_IDENT_STRING=" Xilinx ZynqMP ZC1751 xm015 dc1"
CONFIG_ZYNQMP_USB=y
CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zc1751-xm015-dc1"
@@ -14,7 +15,6 @@ CONFIG_FIT_VERBOSE=y
CONFIG_SPL_LOAD_FIT=y
# CONFIG_DISPLAY_CPUINFO is not set
# CONFIG_DISPLAY_BOARDINFO is not set
-CONFIG_SPL=y
CONFIG_SPL_OS_BOOT=y
CONFIG_SPL_RAM_SUPPORT=y
CONFIG_SPL_RAM_DEVICE=y
@@ -45,6 +45,7 @@ CONFIG_ENV_IS_IN_FAT=y
CONFIG_NET_RANDOM_ETHADDR=y
CONFIG_SPL_DM=y
CONFIG_SPL_DM_SEQ_ALIAS=y
+CONFIG_CLK_ZYNQMP=y
CONFIG_DFU_RAM=y
CONFIG_FPGA_XILINX=y
CONFIG_FPGA_ZYNQMPPL=y
diff --git a/configs/xilinx_zynqmp_zc1751_xm016_dc2_defconfig b/configs/xilinx_zynqmp_zc1751_xm016_dc2_defconfig
index 3e531661eb..8fc13ef0ec 100644
--- a/configs/xilinx_zynqmp_zc1751_xm016_dc2_defconfig
+++ b/configs/xilinx_zynqmp_zc1751_xm016_dc2_defconfig
@@ -4,6 +4,7 @@ CONFIG_ARCH_ZYNQMP=y
CONFIG_SYS_TEXT_BASE=0x8000000
CONFIG_SYS_MALLOC_F_LEN=0x8000
# CONFIG_SPL_LIBDISK_SUPPORT is not set
+CONFIG_SPL=y
CONFIG_IDENT_STRING=" Xilinx ZynqMP ZC1751 xm016 dc2"
# CONFIG_SPL_FAT_SUPPORT is not set
CONFIG_ZYNQMP_USB=y
@@ -15,7 +16,6 @@ CONFIG_FIT_VERBOSE=y
CONFIG_SPL_LOAD_FIT=y
# CONFIG_DISPLAY_CPUINFO is not set
# CONFIG_DISPLAY_BOARDINFO is not set
-CONFIG_SPL=y
CONFIG_SPL_OS_BOOT=y
CONFIG_SPL_RAM_SUPPORT=y
CONFIG_SPL_RAM_DEVICE=y
@@ -44,6 +44,7 @@ CONFIG_OF_EMBED=y
CONFIG_NET_RANDOM_ETHADDR=y
CONFIG_SPL_DM=y
CONFIG_SPL_DM_SEQ_ALIAS=y
+CONFIG_CLK_ZYNQMP=y
CONFIG_DFU_RAM=y
CONFIG_FPGA_XILINX=y
CONFIG_FPGA_ZYNQMPPL=y
diff --git a/configs/xilinx_zynqmp_zc1751_xm018_dc4_defconfig b/configs/xilinx_zynqmp_zc1751_xm018_dc4_defconfig
index 9bc0b77c2c..0a057bf3fe 100644
--- a/configs/xilinx_zynqmp_zc1751_xm018_dc4_defconfig
+++ b/configs/xilinx_zynqmp_zc1751_xm018_dc4_defconfig
@@ -2,6 +2,7 @@ CONFIG_ARM=y
CONFIG_ARCH_ZYNQMP=y
CONFIG_SYS_TEXT_BASE=0x8000000
CONFIG_SYS_MALLOC_F_LEN=0x8000
+CONFIG_SPL=y
CONFIG_IDENT_STRING=" Xilinx ZynqMP ZC1751 xm018 dc4"
CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zc1751-xm018-dc4"
CONFIG_DEBUG_UART=y
@@ -11,7 +12,6 @@ CONFIG_FIT_VERBOSE=y
CONFIG_SPL_LOAD_FIT=y
# CONFIG_DISPLAY_CPUINFO is not set
# CONFIG_DISPLAY_BOARDINFO is not set
-CONFIG_SPL=y
CONFIG_SPL_OS_BOOT=y
CONFIG_SPL_RAM_SUPPORT=y
CONFIG_SPL_RAM_DEVICE=y
@@ -34,6 +34,7 @@ CONFIG_ENV_IS_IN_FAT=y
CONFIG_NET_RANDOM_ETHADDR=y
CONFIG_SPL_DM=y
CONFIG_SPL_DM_SEQ_ALIAS=y
+CONFIG_CLK_ZYNQMP=y
CONFIG_FPGA_XILINX=y
CONFIG_FPGA_ZYNQMPPL=y
CONFIG_DM_GPIO=y
diff --git a/configs/xilinx_zynqmp_zc1751_xm019_dc5_defconfig b/configs/xilinx_zynqmp_zc1751_xm019_dc5_defconfig
index ac565ecf8f..47edf519f9 100644
--- a/configs/xilinx_zynqmp_zc1751_xm019_dc5_defconfig
+++ b/configs/xilinx_zynqmp_zc1751_xm019_dc5_defconfig
@@ -3,6 +3,7 @@ CONFIG_SYS_CONFIG_NAME="xilinx_zynqmp_zc1751_xm019_dc5"
CONFIG_ARCH_ZYNQMP=y
CONFIG_SYS_TEXT_BASE=0x8000000
CONFIG_SYS_MALLOC_F_LEN=0x8000
+CONFIG_SPL=y
CONFIG_IDENT_STRING=" Xilinx ZynqMP ZC1751 xm019 dc5"
CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zc1751-xm019-dc5"
CONFIG_DEBUG_UART=y
@@ -12,7 +13,6 @@ CONFIG_FIT_VERBOSE=y
CONFIG_SPL_LOAD_FIT=y
# CONFIG_DISPLAY_CPUINFO is not set
# CONFIG_DISPLAY_BOARDINFO is not set
-CONFIG_SPL=y
CONFIG_SPL_OS_BOOT=y
CONFIG_SPL_RAM_SUPPORT=y
CONFIG_SPL_RAM_DEVICE=y
@@ -34,6 +34,7 @@ CONFIG_OF_EMBED=y
CONFIG_ENV_IS_IN_FAT=y
CONFIG_SPL_DM=y
CONFIG_SPL_DM_SEQ_ALIAS=y
+CONFIG_CLK_ZYNQMP=y
CONFIG_FPGA_XILINX=y
CONFIG_FPGA_ZYNQMPPL=y
CONFIG_DM_GPIO=y
@@ -44,6 +45,8 @@ CONFIG_DM_MMC=y
CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_ZYNQ=y
CONFIG_DM_ETH=y
+CONFIG_PHY_GIGE=y
+CONFIG_ZYNQ_GEM=y
CONFIG_DEBUG_UART_ZYNQ=y
CONFIG_DEBUG_UART_BASE=0xff000000
CONFIG_DEBUG_UART_CLOCK=100000000
diff --git a/configs/xilinx_zynqmp_zcu102_rev1_0_defconfig b/configs/xilinx_zynqmp_zcu102_rev1_0_defconfig
index 1df5b0b5c6..cb3e2f5ca9 100644
--- a/configs/xilinx_zynqmp_zcu102_rev1_0_defconfig
+++ b/configs/xilinx_zynqmp_zcu102_rev1_0_defconfig
@@ -3,6 +3,7 @@ CONFIG_SYS_CONFIG_NAME="xilinx_zynqmp_zcu102"
CONFIG_ARCH_ZYNQMP=y
CONFIG_SYS_TEXT_BASE=0x8000000
CONFIG_SYS_MALLOC_F_LEN=0x8000
+CONFIG_SPL=y
CONFIG_IDENT_STRING=" Xilinx ZynqMP ZCU102 rev1.0"
CONFIG_ZYNQMP_USB=y
CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zcu102-rev1.0"
@@ -14,7 +15,6 @@ CONFIG_FIT_VERBOSE=y
CONFIG_SPL_LOAD_FIT=y
# CONFIG_DISPLAY_CPUINFO is not set
# CONFIG_DISPLAY_BOARDINFO is not set
-CONFIG_SPL=y
CONFIG_SPL_OS_BOOT=y
CONFIG_SPL_RAM_SUPPORT=y
CONFIG_SPL_RAM_DEVICE=y
@@ -48,6 +48,7 @@ CONFIG_SPL_DM=y
CONFIG_SPL_DM_SEQ_ALIAS=y
CONFIG_SCSI_AHCI=y
CONFIG_SATA_CEVA=y
+CONFIG_CLK_ZYNQMP=y
CONFIG_DFU_RAM=y
CONFIG_FPGA_XILINX=y
CONFIG_FPGA_ZYNQMPPL=y
diff --git a/configs/xilinx_zynqmp_zcu102_revA_defconfig b/configs/xilinx_zynqmp_zcu102_revA_defconfig
index c8a8362148..19b9683f02 100644
--- a/configs/xilinx_zynqmp_zcu102_revA_defconfig
+++ b/configs/xilinx_zynqmp_zcu102_revA_defconfig
@@ -3,6 +3,7 @@ CONFIG_SYS_CONFIG_NAME="xilinx_zynqmp_zcu102"
CONFIG_ARCH_ZYNQMP=y
CONFIG_SYS_TEXT_BASE=0x8000000
CONFIG_SYS_MALLOC_F_LEN=0x8000
+CONFIG_SPL=y
CONFIG_IDENT_STRING=" Xilinx ZynqMP ZCU102 revA"
CONFIG_ZYNQMP_USB=y
CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zcu102-revA"
@@ -14,7 +15,6 @@ CONFIG_FIT_VERBOSE=y
CONFIG_SPL_LOAD_FIT=y
# CONFIG_DISPLAY_CPUINFO is not set
# CONFIG_DISPLAY_BOARDINFO is not set
-CONFIG_SPL=y
CONFIG_SPL_OS_BOOT=y
CONFIG_SPL_RAM_SUPPORT=y
CONFIG_SPL_RAM_DEVICE=y
@@ -48,6 +48,7 @@ CONFIG_SPL_DM=y
CONFIG_SPL_DM_SEQ_ALIAS=y
CONFIG_SCSI_AHCI=y
CONFIG_SATA_CEVA=y
+CONFIG_CLK_ZYNQMP=y
CONFIG_DFU_RAM=y
CONFIG_FPGA_XILINX=y
CONFIG_FPGA_ZYNQMPPL=y
diff --git a/configs/xilinx_zynqmp_zcu102_revB_defconfig b/configs/xilinx_zynqmp_zcu102_revB_defconfig
index 8f85b5f675..b660200508 100644
--- a/configs/xilinx_zynqmp_zcu102_revB_defconfig
+++ b/configs/xilinx_zynqmp_zcu102_revB_defconfig
@@ -3,6 +3,7 @@ CONFIG_SYS_CONFIG_NAME="xilinx_zynqmp_zcu102"
CONFIG_ARCH_ZYNQMP=y
CONFIG_SYS_TEXT_BASE=0x8000000
CONFIG_SYS_MALLOC_F_LEN=0x8000
+CONFIG_SPL=y
CONFIG_IDENT_STRING=" Xilinx ZynqMP ZCU102 revB"
CONFIG_ZYNQMP_USB=y
CONFIG_DEFAULT_DEVICE_TREE="zynqmp-zcu102-revB"
@@ -14,7 +15,6 @@ CONFIG_FIT_VERBOSE=y
CONFIG_SPL_LOAD_FIT=y
# CONFIG_DISPLAY_CPUINFO is not set
# CONFIG_DISPLAY_BOARDINFO is not set
-CONFIG_SPL=y
CONFIG_SPL_OS_BOOT=y
CONFIG_SPL_RAM_SUPPORT=y
CONFIG_SPL_RAM_DEVICE=y
@@ -48,6 +48,7 @@ CONFIG_SPL_DM=y
CONFIG_SPL_DM_SEQ_ALIAS=y
CONFIG_SCSI_AHCI=y
CONFIG_SATA_CEVA=y
+CONFIG_CLK_ZYNQMP=y
CONFIG_DFU_RAM=y
CONFIG_FPGA_XILINX=y
CONFIG_FPGA_ZYNQMPPL=y
diff --git a/configs/zynq_cc108_defconfig b/configs/zynq_cc108_defconfig
index 3a4de92e4c..d328fe6cfe 100644
--- a/configs/zynq_cc108_defconfig
+++ b/configs/zynq_cc108_defconfig
@@ -1,6 +1,7 @@
CONFIG_ARM=y
CONFIG_ARCH_ZYNQ=y
CONFIG_SYS_TEXT_BASE=0x4000000
+CONFIG_SPL=y
CONFIG_SPL_STACK_R_ADDR=0x200000
CONFIG_DEFAULT_DEVICE_TREE="zynq-cc108"
CONFIG_DEBUG_UART=y
@@ -10,7 +11,6 @@ CONFIG_FIT_SIGNATURE=y
CONFIG_FIT_VERBOSE=y
CONFIG_BOOTCOMMAND="run $modeboot || run distro_bootcmd"
# CONFIG_DISPLAY_CPUINFO is not set
-CONFIG_SPL=y
CONFIG_SPL_STACK_R=y
CONFIG_SYS_PROMPT="Zynq> "
CONFIG_CMD_DFU=y
diff --git a/configs/zynq_cse_qspi_defconfig b/configs/zynq_cse_qspi_defconfig
index 80bb26c69f..d93cdbfba5 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_SPL=y
CONFIG_SPL_STACK_R_ADDR=0x200000
# CONFIG_ZYNQ_DDRC_INIT is not set
CONFIG_DEFAULT_DEVICE_TREE="zynq-cse-qspi-single"
@@ -11,7 +12,6 @@ CONFIG_DISTRO_DEFAULTS=y
CONFIG_BOOTDELAY=-1
# CONFIG_USE_BOOTCOMMAND is not set
# CONFIG_DISPLAY_CPUINFO is not set
-CONFIG_SPL=y
CONFIG_SPL_STACK_R=y
CONFIG_SYS_PROMPT="Zynq> "
# CONFIG_CMD_BDI is not set
diff --git a/configs/zynq_microzed_defconfig b/configs/zynq_microzed_defconfig
index 94a1a40efb..25331cac86 100644
--- a/configs/zynq_microzed_defconfig
+++ b/configs/zynq_microzed_defconfig
@@ -1,6 +1,7 @@
CONFIG_ARM=y
CONFIG_ARCH_ZYNQ=y
CONFIG_SYS_TEXT_BASE=0x4000000
+CONFIG_SPL=y
CONFIG_SPL_STACK_R_ADDR=0x200000
CONFIG_DEFAULT_DEVICE_TREE="zynq-microzed"
CONFIG_DISTRO_DEFAULTS=y
@@ -9,7 +10,6 @@ CONFIG_FIT_SIGNATURE=y
CONFIG_FIT_VERBOSE=y
CONFIG_BOOTCOMMAND="run $modeboot || run distro_bootcmd"
# CONFIG_DISPLAY_CPUINFO is not set
-CONFIG_SPL=y
CONFIG_SPL_STACK_R=y
CONFIG_SPL_OS_BOOT=y
CONFIG_SYS_PROMPT="Zynq> "
diff --git a/configs/zynq_picozed_defconfig b/configs/zynq_picozed_defconfig
index f9ee904bd4..6a841f8ecd 100644
--- a/configs/zynq_picozed_defconfig
+++ b/configs/zynq_picozed_defconfig
@@ -1,12 +1,12 @@
CONFIG_ARM=y
CONFIG_ARCH_ZYNQ=y
CONFIG_SYS_TEXT_BASE=0x4000000
+CONFIG_SPL=y
CONFIG_SPL_STACK_R_ADDR=0x200000
CONFIG_DEFAULT_DEVICE_TREE="zynq-picozed"
CONFIG_DISTRO_DEFAULTS=y
CONFIG_BOOTCOMMAND="run $modeboot || run distro_bootcmd"
# CONFIG_DISPLAY_CPUINFO is not set
-CONFIG_SPL=y
CONFIG_SPL_STACK_R=y
CONFIG_SPL_OS_BOOT=y
CONFIG_SYS_PROMPT="Zynq> "
diff --git a/configs/zynq_z_turn_defconfig b/configs/zynq_z_turn_defconfig
index 7a51b85ac8..9013239a8f 100644
--- a/configs/zynq_z_turn_defconfig
+++ b/configs/zynq_z_turn_defconfig
@@ -1,6 +1,7 @@
CONFIG_ARM=y
CONFIG_ARCH_ZYNQ=y
CONFIG_SYS_TEXT_BASE=0x4000000
+CONFIG_SPL=y
CONFIG_SPL_STACK_R_ADDR=0x200000
CONFIG_DEFAULT_DEVICE_TREE="zynq-zturn-myir"
CONFIG_DEBUG_UART=y
@@ -10,7 +11,6 @@ CONFIG_FIT_SIGNATURE=y
CONFIG_FIT_VERBOSE=y
CONFIG_BOOTCOMMAND="run $modeboot || run distro_bootcmd"
# CONFIG_DISPLAY_CPUINFO is not set
-CONFIG_SPL=y
CONFIG_SPL_STACK_R=y
CONFIG_SPL_OS_BOOT=y
CONFIG_SYS_PROMPT="Zynq> "
diff --git a/configs/zynq_zc702_defconfig b/configs/zynq_zc702_defconfig
index 8e8b80053a..72c109b2e3 100644
--- a/configs/zynq_zc702_defconfig
+++ b/configs/zynq_zc702_defconfig
@@ -2,6 +2,7 @@ CONFIG_ARM=y
CONFIG_SYS_CONFIG_NAME="zynq_zc70x"
CONFIG_ARCH_ZYNQ=y
CONFIG_SYS_TEXT_BASE=0x4000000
+CONFIG_SPL=y
CONFIG_IDENT_STRING=" Xilinx Zynq ZC702"
CONFIG_SPL_STACK_R_ADDR=0x200000
CONFIG_DEFAULT_DEVICE_TREE="zynq-zc702"
@@ -12,7 +13,6 @@ CONFIG_FIT_SIGNATURE=y
CONFIG_FIT_VERBOSE=y
CONFIG_BOOTCOMMAND="run $modeboot || run distro_bootcmd"
# CONFIG_DISPLAY_CPUINFO is not set
-CONFIG_SPL=y
CONFIG_SPL_STACK_R=y
CONFIG_SPL_OS_BOOT=y
CONFIG_SYS_PROMPT="Zynq> "
diff --git a/configs/zynq_zc706_defconfig b/configs/zynq_zc706_defconfig
index 8f83d173c5..825a7263d2 100644
--- a/configs/zynq_zc706_defconfig
+++ b/configs/zynq_zc706_defconfig
@@ -2,6 +2,7 @@ CONFIG_ARM=y
CONFIG_SYS_CONFIG_NAME="zynq_zc70x"
CONFIG_ARCH_ZYNQ=y
CONFIG_SYS_TEXT_BASE=0x4000000
+CONFIG_SPL=y
CONFIG_IDENT_STRING=" Xilinx Zynq ZC706"
CONFIG_SPL_STACK_R_ADDR=0x200000
CONFIG_DEFAULT_DEVICE_TREE="zynq-zc706"
@@ -12,7 +13,6 @@ CONFIG_FIT_SIGNATURE=y
CONFIG_FIT_VERBOSE=y
CONFIG_BOOTCOMMAND="run $modeboot || run distro_bootcmd"
# CONFIG_DISPLAY_CPUINFO is not set
-CONFIG_SPL=y
CONFIG_SPL_STACK_R=y
CONFIG_SPL_OS_BOOT=y
CONFIG_SYS_PROMPT="Zynq> "
@@ -73,3 +73,5 @@ CONFIG_USB_GADGET_PRODUCT_NUM=0x0300
CONFIG_CI_UDC=y
CONFIG_USB_GADGET_DOWNLOAD=y
CONFIG_USB_FUNCTION_THOR=y
+CONFIG_WDT=y
+CONFIG_WDT_CDNS=y
diff --git a/configs/zynq_zc770_xm010_defconfig b/configs/zynq_zc770_xm010_defconfig
index 8db30d0818..683dfe8d19 100644
--- a/configs/zynq_zc770_xm010_defconfig
+++ b/configs/zynq_zc770_xm010_defconfig
@@ -1,6 +1,7 @@
CONFIG_ARM=y
CONFIG_ARCH_ZYNQ=y
CONFIG_SYS_TEXT_BASE=0x4000000
+CONFIG_SPL=y
CONFIG_IDENT_STRING=" Xilinx Zynq ZC770 XM010"
CONFIG_SPL_STACK_R_ADDR=0x200000
CONFIG_DEFAULT_DEVICE_TREE="zynq-zc770-xm010"
@@ -11,7 +12,6 @@ CONFIG_FIT_SIGNATURE=y
CONFIG_FIT_VERBOSE=y
CONFIG_BOOTCOMMAND="run $modeboot || run distro_bootcmd"
# CONFIG_DISPLAY_CPUINFO is not set
-CONFIG_SPL=y
CONFIG_SPL_STACK_R=y
CONFIG_SPL_OS_BOOT=y
CONFIG_SYS_PROMPT="Zynq> "
diff --git a/configs/zynq_zc770_xm011_defconfig b/configs/zynq_zc770_xm011_defconfig
index b6ddf986c5..9613b8af25 100644
--- a/configs/zynq_zc770_xm011_defconfig
+++ b/configs/zynq_zc770_xm011_defconfig
@@ -1,6 +1,7 @@
CONFIG_ARM=y
CONFIG_ARCH_ZYNQ=y
CONFIG_SYS_TEXT_BASE=0x4000000
+CONFIG_SPL=y
CONFIG_IDENT_STRING=" Xilinx Zynq ZC770 XM011"
CONFIG_SPL_STACK_R_ADDR=0x200000
# CONFIG_SPL_FAT_SUPPORT is not set
@@ -12,7 +13,6 @@ CONFIG_FIT_SIGNATURE=y
CONFIG_FIT_VERBOSE=y
CONFIG_BOOTCOMMAND="run $modeboot || run distro_bootcmd"
# CONFIG_DISPLAY_CPUINFO is not set
-CONFIG_SPL=y
CONFIG_SPL_STACK_R=y
CONFIG_SPL_OS_BOOT=y
CONFIG_SYS_PROMPT="Zynq> "
diff --git a/configs/zynq_zc770_xm011_x16_defconfig b/configs/zynq_zc770_xm011_x16_defconfig
index bd0ec7b33b..884186a460 100644
--- a/configs/zynq_zc770_xm011_x16_defconfig
+++ b/configs/zynq_zc770_xm011_x16_defconfig
@@ -1,6 +1,7 @@
CONFIG_ARM=y
CONFIG_ARCH_ZYNQ=y
CONFIG_SYS_TEXT_BASE=0x4000000
+CONFIG_SPL=y
CONFIG_IDENT_STRING=" Xilinx Zynq ZC770 XM011 x16"
CONFIG_SPL_STACK_R_ADDR=0x200000
# CONFIG_SPL_FAT_SUPPORT is not set
@@ -10,9 +11,8 @@ CONFIG_DISTRO_DEFAULTS=y
CONFIG_FIT=y
CONFIG_FIT_SIGNATURE=y
CONFIG_FIT_VERBOSE=y
-# CONFIG_USE_BOOTCOMMAND is not set
+CONFIG_BOOTCOMMAND="run $modeboot || run distro_bootcmd"
# CONFIG_DISPLAY_CPUINFO is not set
-CONFIG_SPL=y
CONFIG_SPL_STACK_R=y
CONFIG_SPL_OS_BOOT=y
CONFIG_SYS_PROMPT="Zynq> "
@@ -29,7 +29,6 @@ CONFIG_CMD_CACHE=y
# CONFIG_SPL_DOS_PARTITION is not set
# CONFIG_SPL_ISO_PARTITION is not set
# CONFIG_SPL_EFI_PARTITION is not set
-CONFIG_OF_EMBED=y
CONFIG_SPL_DM_SEQ_ALIAS=y
CONFIG_FPGA_XILINX=y
CONFIG_FPGA_ZYNQPL=y
diff --git a/configs/zynq_zc770_xm012_defconfig b/configs/zynq_zc770_xm012_defconfig
index 8dbba6589d..0b3db398f9 100644
--- a/configs/zynq_zc770_xm012_defconfig
+++ b/configs/zynq_zc770_xm012_defconfig
@@ -1,6 +1,7 @@
CONFIG_ARM=y
CONFIG_ARCH_ZYNQ=y
CONFIG_SYS_TEXT_BASE=0x4000000
+CONFIG_SPL=y
CONFIG_IDENT_STRING=" Xilinx Zynq ZC770 XM012"
CONFIG_SPL_STACK_R_ADDR=0x200000
# CONFIG_SPL_FAT_SUPPORT is not set
@@ -11,7 +12,6 @@ CONFIG_FIT_SIGNATURE=y
CONFIG_FIT_VERBOSE=y
CONFIG_BOOTCOMMAND="run $modeboot || run distro_bootcmd"
# CONFIG_DISPLAY_CPUINFO is not set
-CONFIG_SPL=y
CONFIG_SPL_STACK_R=y
CONFIG_SPL_OS_BOOT=y
CONFIG_SYS_PROMPT="Zynq> "
diff --git a/configs/zynq_zc770_xm013_defconfig b/configs/zynq_zc770_xm013_defconfig
index f9eabb12b5..d7d9d80ce6 100644
--- a/configs/zynq_zc770_xm013_defconfig
+++ b/configs/zynq_zc770_xm013_defconfig
@@ -1,6 +1,7 @@
CONFIG_ARM=y
CONFIG_ARCH_ZYNQ=y
CONFIG_SYS_TEXT_BASE=0x4000000
+CONFIG_SPL=y
CONFIG_IDENT_STRING=" Xilinx Zynq ZC770 XM013"
CONFIG_SPL_STACK_R_ADDR=0x200000
# CONFIG_SPL_FAT_SUPPORT is not set
@@ -11,7 +12,6 @@ CONFIG_FIT_SIGNATURE=y
CONFIG_FIT_VERBOSE=y
CONFIG_BOOTCOMMAND="run $modeboot || run distro_bootcmd"
# CONFIG_DISPLAY_CPUINFO is not set
-CONFIG_SPL=y
CONFIG_SPL_STACK_R=y
CONFIG_SPL_OS_BOOT=y
CONFIG_SYS_PROMPT="Zynq> "
diff --git a/configs/zynq_zed_defconfig b/configs/zynq_zed_defconfig
index 7ed012833a..9f76e5ed8f 100644
--- a/configs/zynq_zed_defconfig
+++ b/configs/zynq_zed_defconfig
@@ -1,15 +1,16 @@
CONFIG_ARM=y
CONFIG_ARCH_ZYNQ=y
CONFIG_SYS_TEXT_BASE=0x4000000
+CONFIG_SPL=y
CONFIG_SPL_STACK_R_ADDR=0x200000
CONFIG_DEFAULT_DEVICE_TREE="zynq-zed"
+CONFIG_DEBUG_UART=y
CONFIG_DISTRO_DEFAULTS=y
CONFIG_FIT=y
CONFIG_FIT_SIGNATURE=y
CONFIG_FIT_VERBOSE=y
CONFIG_BOOTCOMMAND="run $modeboot || run distro_bootcmd"
# CONFIG_DISPLAY_CPUINFO is not set
-CONFIG_SPL=y
CONFIG_SPL_STACK_R=y
CONFIG_SPL_OS_BOOT=y
CONFIG_SYS_PROMPT="Zynq> "
@@ -47,6 +48,9 @@ CONFIG_PHY_MARVELL=y
CONFIG_PHY_REALTEK=y
CONFIG_PHY_XILINX=y
CONFIG_ZYNQ_GEM=y
+CONFIG_DEBUG_UART_ZYNQ=y
+CONFIG_DEBUG_UART_BASE=0xe0001000
+CONFIG_DEBUG_UART_CLOCK=50000000
CONFIG_ZYNQ_SERIAL=y
CONFIG_ZYNQ_QSPI=y
CONFIG_USB=y
diff --git a/configs/zynq_zybo_defconfig b/configs/zynq_zybo_defconfig
index 92f3e1ec26..15922d2fa1 100644
--- a/configs/zynq_zybo_defconfig
+++ b/configs/zynq_zybo_defconfig
@@ -2,6 +2,7 @@ CONFIG_ARM=y
CONFIG_SYS_CONFIG_NAME="zynq_zybo"
CONFIG_ARCH_ZYNQ=y
CONFIG_SYS_TEXT_BASE=0x4000000
+CONFIG_SPL=y
CONFIG_SPL_STACK_R_ADDR=0x200000
CONFIG_DEFAULT_DEVICE_TREE="zynq-zybo"
CONFIG_DEBUG_UART=y
@@ -11,7 +12,6 @@ CONFIG_FIT_SIGNATURE=y
CONFIG_FIT_VERBOSE=y
CONFIG_BOOTCOMMAND="run $modeboot || run distro_bootcmd"
# CONFIG_DISPLAY_CPUINFO is not set
-CONFIG_SPL=y
CONFIG_SPL_STACK_R=y
CONFIG_SPL_OS_BOOT=y
CONFIG_SYS_PROMPT="Zynq> "
diff --git a/drivers/clk/clk_zynq.c b/drivers/clk/clk_zynq.c
index 50f2a65c20..3845e07309 100644
--- a/drivers/clk/clk_zynq.c
+++ b/drivers/clk/clk_zynq.c
@@ -394,7 +394,7 @@ static ulong zynq_clk_get_rate(struct clk *clk)
return zynq_clk_get_peripheral_rate(priv, id, two_divs);
case dma_clk:
return zynq_clk_get_cpu_rate(priv, cpu_2x_clk);
- case usb0_aper_clk ... smc_aper_clk:
+ case usb0_aper_clk ... swdt_clk:
return zynq_clk_get_cpu_rate(priv, cpu_1x_clk);
default:
return -ENXIO;
diff --git a/drivers/clk/clk_zynqmp.c b/drivers/clk/clk_zynqmp.c
index bcc62904f1..4ef8662af5 100644
--- a/drivers/clk/clk_zynqmp.c
+++ b/drivers/clk/clk_zynqmp.c
@@ -226,6 +226,18 @@ static u32 zynqmp_clk_get_register(enum zynqmp_clk id)
return CRL_APB_CAN0_REF_CTRL;
case can1_ref:
return CRL_APB_CAN1_REF_CTRL;
+ case pl0:
+ return CRL_APB_PL0_REF_CTRL;
+ case pl1:
+ return CRL_APB_PL1_REF_CTRL;
+ case pl2:
+ return CRL_APB_PL2_REF_CTRL;
+ case pl3:
+ return CRL_APB_PL3_REF_CTRL;
+ case wdt:
+ return CRF_APB_TOPSW_LSBUS_CTRL;
+ case iopll_to_fpd:
+ return CRL_APB_IOPLL_TO_FPD_CTRL;
default:
debug("Invalid clk id%d\n", id);
}
@@ -278,6 +290,22 @@ static enum zynqmp_clk zynqmp_clk_get_peripheral_pll(u32 clk_ctrl)
}
}
+static enum zynqmp_clk zynqmp_clk_get_wdt_pll(u32 clk_ctrl)
+{
+ u32 srcsel = (clk_ctrl & CLK_CTRL_SRCSEL_MASK) >>
+ CLK_CTRL_SRCSEL_SHIFT;
+
+ switch (srcsel) {
+ case 2:
+ return iopll_to_fpd;
+ case 3:
+ return dpll;
+ case 0 ... 1:
+ default:
+ return apll;
+ }
+}
+
static ulong zynqmp_clk_get_pll_src(ulong clk_ctrl,
struct zynqmp_clk_priv *priv,
bool is_pre_src)
@@ -420,6 +448,49 @@ static ulong zynqmp_clk_get_peripheral_rate(struct zynqmp_clk_priv *priv,
DIV_ROUND_CLOSEST(pllrate, div0), div1);
}
+static ulong zynqmp_clk_get_wdt_rate(struct zynqmp_clk_priv *priv,
+ enum zynqmp_clk id, bool two_divs)
+{
+ enum zynqmp_clk pll;
+ u32 clk_ctrl, div0;
+ u32 div1 = 1;
+ int ret;
+ ulong pllrate;
+
+ ret = zynqmp_mmio_read(zynqmp_clk_get_register(id), &clk_ctrl);
+ if (ret) {
+ printf("%d %s mio read fail\n", __LINE__, __func__);
+ return -EIO;
+ }
+
+ div0 = (clk_ctrl & CLK_CTRL_DIV0_MASK) >> CLK_CTRL_DIV0_SHIFT;
+ if (!div0)
+ div0 = 1;
+
+ pll = zynqmp_clk_get_wdt_pll(clk_ctrl);
+ if (two_divs) {
+ ret = zynqmp_mmio_read(zynqmp_clk_get_register(pll), &clk_ctrl);
+ if (ret) {
+ printf("%d %s mio read fail\n", __LINE__, __func__);
+ return -EIO;
+ }
+ div1 = (clk_ctrl & CLK_CTRL_DIV0_MASK) >> CLK_CTRL_DIV0_SHIFT;
+ if (!div1)
+ div1 = 1;
+ }
+
+ if (pll == iopll_to_fpd)
+ pll = iopll;
+
+ pllrate = zynqmp_clk_get_pll_rate(priv, pll);
+ if (IS_ERR_VALUE(pllrate))
+ return pllrate;
+
+ return
+ DIV_ROUND_CLOSEST(
+ DIV_ROUND_CLOSEST(pllrate, div0), div1);
+}
+
static unsigned long zynqmp_clk_calc_peripheral_two_divs(ulong rate,
ulong pll_rate,
u32 *div0, u32 *div1)
@@ -510,8 +581,12 @@ static ulong zynqmp_clk_get_rate(struct clk *clk)
return zynqmp_clk_get_ddr_rate(priv);
case gem0_ref ... gem3_ref:
case qspi_ref ... can1_ref:
+ case pl0 ... pl3:
two_divs = true;
return zynqmp_clk_get_peripheral_rate(priv, id, two_divs);
+ case wdt:
+ two_divs = true;
+ return zynqmp_clk_get_wdt_rate(priv, id, two_divs);
default:
return -ENXIO;
}
diff --git a/drivers/fpga/fpga.c b/drivers/fpga/fpga.c
index 6aead27f16..ac01612d75 100644
--- a/drivers/fpga/fpga.c
+++ b/drivers/fpga/fpga.c
@@ -148,20 +148,21 @@ int fpga_add(fpga_type devtype, void *desc)
{
int devnum = FPGA_INVALID_DEVICE;
+ if (!desc) {
+ printf("%s: NULL device descriptor\n", __func__);
+ return devnum;
+ }
+
if (next_desc < 0) {
printf("%s: FPGA support not initialized!\n", __func__);
} else if ((devtype > fpga_min_type) && (devtype < fpga_undefined)) {
- if (desc) {
- if (next_desc < CONFIG_MAX_FPGA_DEVICES) {
- devnum = next_desc;
- desc_table[next_desc].devtype = devtype;
- desc_table[next_desc++].devdesc = desc;
- } else {
- printf("%s: Exceeded Max FPGA device count\n",
- __func__);
- }
+ if (next_desc < CONFIG_MAX_FPGA_DEVICES) {
+ devnum = next_desc;
+ desc_table[next_desc].devtype = devtype;
+ desc_table[next_desc++].devdesc = desc;
} else {
- printf("%s: NULL device descriptor\n", __func__);
+ printf("%s: Exceeded Max FPGA device count\n",
+ __func__);
}
} else {
printf("%s: Unsupported FPGA type %d\n", __func__, devtype);
diff --git a/drivers/mtd/nand/arasan_nfc.c b/drivers/mtd/nand/arasan_nfc.c
index 3c9a0215c5..9c82c7db33 100644
--- a/drivers/mtd/nand/arasan_nfc.c
+++ b/drivers/mtd/nand/arasan_nfc.c
@@ -86,7 +86,7 @@ struct arasan_nand_command_format {
#define ARASAN_NAND_CMD_ADDR_CYCL_MASK 0x70000000
#define ARASAN_NAND_CMD_ADDR_CYCL_SHIFT 28
-#define ARASAN_NAND_MEM_ADDR1_PAGE_MASK 0xFFFF0000
+#define ARASAN_NAND_MEM_ADDR1_PAGE_MASK 0xFFFF
#define ARASAN_NAND_MEM_ADDR1_COL_MASK 0xFFFF
#define ARASAN_NAND_MEM_ADDR1_PAGE_SHIFT 16
#define ARASAN_NAND_MEM_ADDR2_PAGE_MASK 0xFF
@@ -795,10 +795,11 @@ static int arasan_nand_erase(struct arasan_nand_command_format *curr_cmd,
writel(reg_val, &arasan_nand_base->cmd_reg);
- page = (page_addr << ARASAN_NAND_MEM_ADDR1_PAGE_SHIFT) &
+ page = (page_addr >> ARASAN_NAND_MEM_ADDR1_PAGE_SHIFT) &
ARASAN_NAND_MEM_ADDR1_PAGE_MASK;
column = page_addr & ARASAN_NAND_MEM_ADDR1_COL_MASK;
- writel(page | column, &arasan_nand_base->memadr_reg1);
+ writel(column | (page << ARASAN_NAND_MEM_ADDR1_PAGE_SHIFT),
+ &arasan_nand_base->memadr_reg1);
reg_val = readl(&arasan_nand_base->memadr_reg2);
reg_val &= ~ARASAN_NAND_MEM_ADDR2_PAGE_MASK;
diff --git a/drivers/net/zynq_gem.c b/drivers/net/zynq_gem.c
index 2cc49bca92..1390c36c61 100644
--- a/drivers/net/zynq_gem.c
+++ b/drivers/net/zynq_gem.c
@@ -325,7 +325,8 @@ static int zynq_phy_init(struct udevice *dev)
/* Enable only MDIO bus */
writel(ZYNQ_GEM_NWCTRL_MDEN_MASK, &regs->nwctrl);
- if (priv->interface != PHY_INTERFACE_MODE_SGMII) {
+ if ((priv->interface != PHY_INTERFACE_MODE_SGMII) &&
+ (priv->interface != PHY_INTERFACE_MODE_GMII)) {
ret = phy_detection(dev);
if (ret) {
printf("GEM PHY init failed\n");
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index fc46b6774d..8a66e479ab 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -1,5 +1,13 @@
menu "Watchdog Timer Support"
+config WATCHDOG
+ bool "Enable U-Boot watchdog reset"
+ help
+ This option enables U-Boot watchdog support where U-Boot is using
+ watchdog_reset function to service watchdog device in U-Boot. Enable
+ this option if you want to service enabled watchdog by U-Boot. Disable
+ this option if you want U-Boot to start watchdog but never service it.
+
config HW_WATCHDOG
bool
@@ -78,4 +86,12 @@ config WDT_ORION
Select this to enable Orion watchdog timer, which can be found on some
Marvell Armada chips.
+config WDT_CDNS
+ bool "Cadence watchdog timer support"
+ depends on WDT
+ imply WATCHDOG
+ help
+ Select this to enable Cadence watchdog timer, which can be found on some
+ Xilinx Microzed Platform.
+
endmenu
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index ab6a6b79e1..4b97df3ab6 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -22,3 +22,4 @@ obj-$(CONFIG_WDT_ASPEED) += ast_wdt.o
obj-$(CONFIG_WDT_BCM6345) += bcm6345_wdt.o
obj-$(CONFIG_BCM2835_WDT) += bcm2835_wdt.o
obj-$(CONFIG_WDT_ORION) += orion_wdt.o
+obj-$(CONFIG_WDT_CDNS) += cdns_wdt.o
diff --git a/drivers/watchdog/cdns_wdt.c b/drivers/watchdog/cdns_wdt.c
new file mode 100644
index 0000000000..71733cf8ba
--- /dev/null
+++ b/drivers/watchdog/cdns_wdt.c
@@ -0,0 +1,276 @@
+/*
+ * Cadence WDT driver - Used by Xilinx Zynq
+ * Reference: Linux kernel Cadence watchdog driver.
+ *
+ * Author(s): Shreenidhi Shedi <yesshedi@gmail.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <wdt.h>
+#include <clk.h>
+#include <linux/io.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct cdns_regs {
+ u32 zmr; /* WD Zero mode register, offset - 0x0 */
+ u32 ccr; /* Counter Control Register offset - 0x4 */
+ u32 restart; /* Restart key register, offset - 0x8 */
+ u32 status; /* Status Register, offset - 0xC */
+};
+
+struct cdns_wdt_priv {
+ bool rst;
+ u32 timeout;
+ void __iomem *reg;
+ struct cdns_regs *regs;
+};
+
+#define CDNS_WDT_DEFAULT_TIMEOUT 10
+
+/* Supports 1 - 516 sec */
+#define CDNS_WDT_MIN_TIMEOUT 1
+#define CDNS_WDT_MAX_TIMEOUT 516
+
+/* Restart key */
+#define CDNS_WDT_RESTART_KEY 0x00001999
+
+/* Counter register access key */
+#define CDNS_WDT_REGISTER_ACCESS_KEY 0x00920000
+
+/* Counter value divisor */
+#define CDNS_WDT_COUNTER_VALUE_DIVISOR 0x1000
+
+/* Clock prescaler value and selection */
+#define CDNS_WDT_PRESCALE_64 64
+#define CDNS_WDT_PRESCALE_512 512
+#define CDNS_WDT_PRESCALE_4096 4096
+#define CDNS_WDT_PRESCALE_SELECT_64 1
+#define CDNS_WDT_PRESCALE_SELECT_512 2
+#define CDNS_WDT_PRESCALE_SELECT_4096 3
+
+/* Input clock frequency */
+#define CDNS_WDT_CLK_75MHZ 75000000
+
+/* Counter maximum value */
+#define CDNS_WDT_COUNTER_MAX 0xFFF
+
+/********************* Register Map **********************************/
+
+/*
+ * Zero Mode Register - This register controls how the time out is indicated
+ * and also contains the access code to allow writes to the register (0xABC).
+ */
+#define CDNS_WDT_ZMR_WDEN_MASK 0x00000001 /* Enable the WDT */
+#define CDNS_WDT_ZMR_RSTEN_MASK 0x00000002 /* Enable the reset output */
+#define CDNS_WDT_ZMR_IRQEN_MASK 0x00000004 /* Enable IRQ output */
+#define CDNS_WDT_ZMR_RSTLEN_16 0x00000030 /* Reset pulse of 16 pclk cycles */
+#define CDNS_WDT_ZMR_ZKEY_VAL 0x00ABC000 /* Access key, 0xABC << 12 */
+
+/*
+ * Counter Control register - This register controls how fast the timer runs
+ * and the reset value and also contains the access code to allow writes to
+ * the register.
+ */
+#define CDNS_WDT_CCR_CRV_MASK 0x00003FFC /* Counter reset value */
+
+/* Write access to Registers */
+static inline void cdns_wdt_writereg(u32 *addr, u32 val)
+{
+ writel(val, addr);
+}
+
+/**
+ * cdns_wdt_reset - Reload the watchdog timer (i.e. pat the watchdog).
+ *
+ * @dev: Watchdog device
+ *
+ * Write the restart key value (0x00001999) to the restart register.
+ *
+ * Return: Always 0
+ */
+static int cdns_wdt_reset(struct udevice *dev)
+{
+ struct cdns_wdt_priv *priv = dev_get_priv(dev);
+
+ debug("%s\n", __func__);
+
+ cdns_wdt_writereg(&priv->regs->restart, CDNS_WDT_RESTART_KEY);
+
+ return 0;
+}
+
+/**
+ * cdns_wdt_start - Enable and start the watchdog.
+ *
+ * @dev: Watchdog device
+ * @timeout: Timeout value
+ * @flags: Driver flags
+ *
+ * The counter value is calculated according to the formula:
+ * count = (timeout * clock) / prescaler + 1.
+ *
+ * The calculated count is divided by 0x1000 to obtain the field value
+ * to write to counter control register.
+ *
+ * Clears the contents of prescaler and counter reset value. Sets the
+ * prescaler to 4096 and the calculated count and access key
+ * to write to CCR Register.
+ *
+ * Sets the WDT (WDEN bit) and either the Reset signal(RSTEN bit)
+ * or Interrupt signal(IRQEN) with a specified cycles and the access
+ * key to write to ZMR Register.
+ *
+ * Return: Upon success 0, failure -1.
+ */
+static int cdns_wdt_start(struct udevice *dev, u64 timeout, ulong flags)
+{
+ ulong clk_f;
+ u32 count, prescaler, ctrl_clksel, data = 0;
+ struct clk clock;
+ struct cdns_wdt_priv *priv = dev_get_priv(dev);
+
+ if (clk_get_by_index(dev, 0, &clock) < 0) {
+ dev_err(dev, "failed to get clock\n");
+ return -1;
+ }
+
+ clk_f = clk_get_rate(&clock);
+ if (IS_ERR_VALUE(clk_f)) {
+ dev_err(dev, "failed to get rate\n");
+ return -1;
+ }
+
+ debug("%s: CLK_FREQ %ld, timeout %lld\n", __func__, clk_f, timeout);
+
+ if ((timeout < CDNS_WDT_MIN_TIMEOUT) ||
+ (timeout > CDNS_WDT_MAX_TIMEOUT)) {
+ timeout = priv->timeout;
+ }
+
+ if (clk_f <= CDNS_WDT_CLK_75MHZ) {
+ prescaler = CDNS_WDT_PRESCALE_512;
+ ctrl_clksel = CDNS_WDT_PRESCALE_SELECT_512;
+ } else {
+ prescaler = CDNS_WDT_PRESCALE_4096;
+ ctrl_clksel = CDNS_WDT_PRESCALE_SELECT_4096;
+ }
+
+ /*
+ * Counter value divisor to obtain the value of
+ * counter reset to be written to control register.
+ */
+ count = (timeout * (clk_f / prescaler)) /
+ CDNS_WDT_COUNTER_VALUE_DIVISOR + 1;
+
+ if (count > CDNS_WDT_COUNTER_MAX)
+ count = CDNS_WDT_COUNTER_MAX;
+
+ cdns_wdt_writereg(&priv->regs->zmr, CDNS_WDT_ZMR_ZKEY_VAL);
+
+ count = (count << 2) & CDNS_WDT_CCR_CRV_MASK;
+
+ /* Write counter access key first to be able write to register */
+ data = count | CDNS_WDT_REGISTER_ACCESS_KEY | ctrl_clksel;
+ cdns_wdt_writereg(&priv->regs->ccr, data);
+
+ data = CDNS_WDT_ZMR_WDEN_MASK | CDNS_WDT_ZMR_RSTLEN_16 |
+ CDNS_WDT_ZMR_ZKEY_VAL;
+
+ /* Reset on timeout if specified in device tree. */
+ if (priv->rst) {
+ data |= CDNS_WDT_ZMR_RSTEN_MASK;
+ data &= ~CDNS_WDT_ZMR_IRQEN_MASK;
+ } else {
+ data &= ~CDNS_WDT_ZMR_RSTEN_MASK;
+ data |= CDNS_WDT_ZMR_IRQEN_MASK;
+ }
+
+ cdns_wdt_writereg(&priv->regs->zmr, data);
+ cdns_wdt_writereg(&priv->regs->restart, CDNS_WDT_RESTART_KEY);
+
+ return 0;
+}
+
+/**
+ * cdns_wdt_stop - Stop the watchdog.
+ *
+ * @dev: Watchdog device
+ *
+ * Read the contents of the ZMR register, clear the WDEN bit in the register
+ * and set the access key for successful write.
+ *
+ * Return: Always 0
+ */
+static int cdns_wdt_stop(struct udevice *dev)
+{
+ struct cdns_wdt_priv *priv = dev_get_priv(dev);
+
+ cdns_wdt_writereg(&priv->regs->zmr,
+ CDNS_WDT_ZMR_ZKEY_VAL & (~CDNS_WDT_ZMR_WDEN_MASK));
+
+ return 0;
+}
+
+/**
+ * cdns_wdt_probe - Probe call for the device.
+ *
+ * @dev: Handle to the udevice structure.
+ *
+ * Return: Always 0.
+ */
+static int cdns_wdt_probe(struct udevice *dev)
+{
+ struct cdns_wdt_priv *priv = dev_get_priv(dev);
+
+ debug("%s: Probing wdt%u\n", __func__, dev->seq);
+
+ priv->reg = ioremap((u32)priv->regs, sizeof(struct cdns_regs));
+
+ cdns_wdt_stop(dev);
+
+ return 0;
+}
+
+static int cdns_wdt_ofdata_to_platdata(struct udevice *dev)
+{
+ int node = dev_of_offset(dev);
+ struct cdns_wdt_priv *priv = dev_get_priv(dev);
+
+ priv->regs = devfdt_get_addr_ptr(dev);
+ if (IS_ERR(priv->regs))
+ return PTR_ERR(priv->regs);
+
+ priv->timeout = fdtdec_get_int(gd->fdt_blob, node, "timeout-sec",
+ CDNS_WDT_DEFAULT_TIMEOUT);
+
+ priv->rst = fdtdec_get_bool(gd->fdt_blob, node, "reset-on-timeout");
+
+ debug("%s: timeout %d, reset %d\n", __func__, priv->timeout, priv->rst);
+
+ return 0;
+}
+
+static const struct wdt_ops cdns_wdt_ops = {
+ .start = cdns_wdt_start,
+ .reset = cdns_wdt_reset,
+ .stop = cdns_wdt_stop,
+};
+
+static const struct udevice_id cdns_wdt_ids[] = {
+ { .compatible = "cdns,wdt-r1p2" },
+ {}
+};
+
+U_BOOT_DRIVER(cdns_wdt) = {
+ .name = "cdns_wdt",
+ .id = UCLASS_WDT,
+ .of_match = cdns_wdt_ids,
+ .probe = cdns_wdt_probe,
+ .priv_auto_alloc_size = sizeof(struct cdns_wdt_priv),
+ .ofdata_to_platdata = cdns_wdt_ofdata_to_platdata,
+ .ops = &cdns_wdt_ops,
+};
diff --git a/include/command.h b/include/command.h
index 767cabb3df..56499b8ad5 100644
--- a/include/command.h
+++ b/include/command.h
@@ -111,6 +111,8 @@ extern int common_diskboot(cmd_tbl_t *cmdtp, const char *intf, int argc,
extern int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
extern int do_poweroff(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);
+extern unsigned long do_go_exec(ulong (*entry)(int, char * const []), int argc,
+ char * const argv[]);
/*
* Error codes that commands return to cmd_process(). We use the standard 0
* and 1 for success and failure, but add one more case - failure with a
diff --git a/include/configs/xilinx_zynqmp.h b/include/configs/xilinx_zynqmp.h
index e23b0f2adb..8c0b5d9c06 100644
--- a/include/configs/xilinx_zynqmp.h
+++ b/include/configs/xilinx_zynqmp.h
@@ -21,7 +21,9 @@
#define GICC_BASE 0xF9020000
#define CONFIG_SYS_ALT_MEMTEST
-#define CONFIG_SYS_MEMTEST_SCRATCH 0xfffc0000
+#ifndef CONFIG_SYS_MEMTEST_SCRATCH
+# define CONFIG_SYS_MEMTEST_SCRATCH 0x10800000
+#endif
#ifndef CONFIG_NR_DRAM_BANKS
# define CONFIG_NR_DRAM_BANKS 2
diff --git a/include/configs/xilinx_zynqmp_ep.h b/include/configs/xilinx_zynqmp_ep.h
deleted file mode 100644
index a26377a412..0000000000
--- a/include/configs/xilinx_zynqmp_ep.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Configuration for Xilinx ZynqMP emulation platforms
- *
- * (C) Copyright 2014 - 2015 Xilinx, Inc.
- * Michal Simek <michal.simek@xilinx.com>
- * Siva Durga Prasad Paladugu <sivadur@xilinx.com>
- *
- * Based on Configuration for Versatile Express
- *
- * SPDX-License-Identifier: GPL-2.0+
- */
-
-#ifndef __CONFIG_ZYNQMP_EP_H
-#define __CONFIG_ZYNQMP_EP_H
-
-#define CONFIG_ZYNQ_EEPROM
-#define CONFIG_ZYNQMP_XHCI_LIST {ZYNQMP_USB0_XHCI_BASEADDR, \
- ZYNQMP_USB1_XHCI_BASEADDR}
-
-#define COUNTER_FREQUENCY 4000000
-
-#include <configs/xilinx_zynqmp.h>
-
-#endif /* __CONFIG_ZYNQMP_EP_H */
diff --git a/include/configs/xilinx_zynqmp_mini.h b/include/configs/xilinx_zynqmp_mini.h
index 00f4c1c087..4fbf85a9ed 100644
--- a/include/configs/xilinx_zynqmp_mini.h
+++ b/include/configs/xilinx_zynqmp_mini.h
@@ -11,6 +11,8 @@
#ifndef __CONFIG_ZYNQMP_MINI_H
#define __CONFIG_ZYNQMP_MINI_H
+#define CONFIG_SYS_MEMTEST_SCRATCH 0xfffc0000
+
#include <configs/xilinx_zynqmp.h>
/* Undef unneeded configs */
diff --git a/tools/zynqimage.c b/tools/zynqimage.c
index 021d2d3fc9..aa003a7543 100644
--- a/tools/zynqimage.c
+++ b/tools/zynqimage.c
@@ -147,6 +147,12 @@ static int zynqimage_verify_header(unsigned char *ptr, int image_size,
if (image_size < sizeof(struct zynq_header))
return -1;
+ if (zynqhdr->__reserved1 != 0)
+ return -1;
+
+ if (zynqhdr->__reserved2 != 0)
+ return -1;
+
if (zynqhdr->width_detection != HEADER_WIDTHDETECTION)
return -1;
if (zynqhdr->image_identifier != HEADER_IMAGEIDENTIFIER)
diff --git a/tools/zynqmpimage.c b/tools/zynqmpimage.c
index f48ac6dbe5..a61fb17c40 100644
--- a/tools/zynqmpimage.c
+++ b/tools/zynqmpimage.c
@@ -178,7 +178,7 @@ static void zynqmpimage_print_header(const void *ptr)
struct zynqmp_header *zynqhdr = (struct zynqmp_header *)ptr;
int i;
- printf("Image Type : Xilinx Zynq Boot Image support\n");
+ printf("Image Type : Xilinx ZynqMP Boot Image support\n");
printf("Image Offset : 0x%08x\n", le32_to_cpu(zynqhdr->image_offset));
printf("Image Size : %lu bytes (%lu bytes packed)\n",
(unsigned long)le32_to_cpu(zynqhdr->image_size),