summaryrefslogtreecommitdiff
path: root/arch/arm
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/Kconfig11
-rw-r--r--arch/arm/Makefile1
-rw-r--r--arch/arm/cpu/armv8/zynqmp/cpu.c84
-rw-r--r--arch/arm/dts/Makefile3
-rw-r--r--arch/arm/dts/zynqmp-clk.dtsi2
-rw-r--r--arch/arm/dts/zynqmp-r5.dts73
-rw-r--r--arch/arm/dts/zynqmp-zc1275-revB.dts79
-rw-r--r--arch/arm/dts/zynqmp-zcu100-revC.dts1
-rw-r--r--arch/arm/include/asm/arch-zynqmp/sys_proto.h2
-rw-r--r--arch/arm/mach-zynq/cpu.c85
-rw-r--r--arch/arm/mach-zynq/spl.c11
-rw-r--r--arch/arm/mach-zynqmp-r5/Kconfig27
-rw-r--r--arch/arm/mach-zynqmp-r5/Makefile3
-rw-r--r--arch/arm/mach-zynqmp-r5/cpu.c37
14 files changed, 379 insertions, 40 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 2bbb86c462..c9d6e0a424 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -821,6 +821,15 @@ config ARCH_ZYNQ
imply CMD_CLK
imply FAT_WRITE
imply CMD_SPL
+ imply ARCH_EARLY_INIT_R
+
+config ARCH_ZYNQMP_R5
+ bool "Xilinx ZynqMP R5 based platform"
+ select CPU_V7R
+ select OF_CONTROL
+ select DM
+ select DM_SERIAL
+ select CLK
config ARCH_ZYNQMP
bool "Xilinx ZynqMP based platform"
@@ -1344,6 +1353,8 @@ source "arch/arm/cpu/armv7/vf610/Kconfig"
source "arch/arm/mach-zynq/Kconfig"
+source "arch/arm/mach-zynqmp-r5/Kconfig"
+
source "arch/arm/cpu/armv7/Kconfig"
source "arch/arm/cpu/armv8/zynqmp/Kconfig"
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 3b1dd85716..4d6d276137 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -76,6 +76,7 @@ machine-$(CONFIG_ARCH_STM32MP) += stm32mp
machine-$(CONFIG_TEGRA) += tegra
machine-$(CONFIG_ARCH_UNIPHIER) += uniphier
machine-$(CONFIG_ARCH_ZYNQ) += zynq
+machine-$(CONFIG_ARCH_ZYNQMP_R5) += zynqmp-r5
machdirs := $(patsubst %,arch/arm/mach-%/,$(machine-y))
diff --git a/arch/arm/cpu/armv8/zynqmp/cpu.c b/arch/arm/cpu/armv8/zynqmp/cpu.c
index eb0db46065..2748d65d14 100644
--- a/arch/arm/cpu/armv8/zynqmp/cpu.c
+++ b/arch/arm/cpu/armv8/zynqmp/cpu.c
@@ -15,16 +15,28 @@
DECLARE_GLOBAL_DATA_PTR;
-static struct mm_region zynqmp_mem_map[] = {
+/*
+ * Number of filled static entries and also the first empty
+ * slot in zynqmp_mem_map.
+ */
+#define ZYNQMP_MEM_MAP_USED 4
+
#if !defined(CONFIG_ZYNQMP_NO_DDR)
- {
- .virt = 0x0UL,
- .phys = 0x0UL,
- .size = 0x80000000UL,
- .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
- PTE_BLOCK_INNER_SHARE
- },
+#define DRAM_BANKS CONFIG_NR_DRAM_BANKS
+#else
+#define DRAM_BANKS 0
#endif
+
+#if defined(CONFIG_DEFINE_TCM_OCM_MMAP)
+#define TCM_MAP 1
+#else
+#define TCM_MAP 0
+#endif
+
+/* +1 is end of list which needs to be empty */
+#define ZYNQMP_MEM_MAP_MAX (ZYNQMP_MEM_MAP_USED + DRAM_BANKS + TCM_MAP + 1)
+
+static struct mm_region zynqmp_mem_map[ZYNQMP_MEM_MAP_MAX] = {
{
.virt = 0x80000000UL,
.phys = 0x80000000UL,
@@ -32,8 +44,7 @@ static struct mm_region zynqmp_mem_map[] = {
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
PTE_BLOCK_NON_SHARE |
PTE_BLOCK_PXN | PTE_BLOCK_UXN
- },
- {
+ }, {
.virt = 0xf8000000UL,
.phys = 0xf8000000UL,
.size = 0x07e00000UL,
@@ -41,42 +52,51 @@ static struct mm_region zynqmp_mem_map[] = {
PTE_BLOCK_NON_SHARE |
PTE_BLOCK_PXN | PTE_BLOCK_UXN
}, {
-#if defined(CONFIG_DEFINE_TCM_OCM_MMAP)
- .virt = 0xffe00000UL,
- .phys = 0xffe00000UL,
- .size = 0x00200000UL,
- .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
- PTE_BLOCK_INNER_SHARE
- }, {
-#endif
.virt = 0x400000000UL,
.phys = 0x400000000UL,
.size = 0x400000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
PTE_BLOCK_NON_SHARE |
PTE_BLOCK_PXN | PTE_BLOCK_UXN
- },
-#if !defined(CONFIG_ZYNQMP_NO_DDR)
- {
- .virt = 0x800000000UL,
- .phys = 0x800000000UL,
- .size = 0x800000000UL,
- .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
- PTE_BLOCK_INNER_SHARE
- },
-#endif
- {
+ }, {
.virt = 0x1000000000UL,
.phys = 0x1000000000UL,
.size = 0xf000000000UL,
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
PTE_BLOCK_NON_SHARE |
PTE_BLOCK_PXN | PTE_BLOCK_UXN
- }, {
- /* List terminator */
- 0,
}
};
+
+void mem_map_fill(void)
+{
+ int banks = ZYNQMP_MEM_MAP_USED;
+
+#if defined(CONFIG_DEFINE_TCM_OCM_MMAP)
+ zynqmp_mem_map[banks].virt = 0xffe00000UL;
+ zynqmp_mem_map[banks].phys = 0xffe00000UL;
+ zynqmp_mem_map[banks].size = 0x00200000UL;
+ zynqmp_mem_map[banks].attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+ PTE_BLOCK_INNER_SHARE;
+ banks = banks + 1;
+#endif
+
+#if !defined(CONFIG_ZYNQMP_NO_DDR)
+ for (int i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
+ /* Zero size means no more DDR that's this is end */
+ if (!gd->bd->bi_dram[i].size)
+ break;
+
+ zynqmp_mem_map[banks].virt = gd->bd->bi_dram[i].start;
+ zynqmp_mem_map[banks].phys = gd->bd->bi_dram[i].start;
+ zynqmp_mem_map[banks].size = gd->bd->bi_dram[i].size;
+ zynqmp_mem_map[banks].attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+ PTE_BLOCK_INNER_SHARE;
+ banks = banks + 1;
+ }
+#endif
+}
+
struct mm_region *mem_map = zynqmp_mem_map;
u64 get_page_table_size(void)
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 3426a983cb..f94940a7dd 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -157,11 +157,14 @@ dtb-$(CONFIG_ARCH_ZYNQMP) += \
zynqmp-zc1232-revA.dtb \
zynqmp-zc1254-revA.dtb \
zynqmp-zc1275-revA.dtb \
+ zynqmp-zc1275-revB.dtb \
zynqmp-zc1751-xm015-dc1.dtb \
zynqmp-zc1751-xm016-dc2.dtb \
zynqmp-zc1751-xm017-dc3.dtb \
zynqmp-zc1751-xm018-dc4.dtb \
zynqmp-zc1751-xm019-dc5.dtb
+dtb-$(CONFIG_ARCH_ZYNQMP_R5) += \
+ zynqmp-r5.dtb
dtb-$(CONFIG_AM33XX) += am335x-boneblack.dtb am335x-bone.dtb \
am335x-draco.dtb \
am335x-evm.dtb \
diff --git a/arch/arm/dts/zynqmp-clk.dtsi b/arch/arm/dts/zynqmp-clk.dtsi
index a8664e8187..a795efdc15 100644
--- a/arch/arm/dts/zynqmp-clk.dtsi
+++ b/arch/arm/dts/zynqmp-clk.dtsi
@@ -219,7 +219,7 @@
};
&watchdog0 {
- clocks = <&clk250>;
+ clocks = <&clk100>;
};
&xilinx_drm {
diff --git a/arch/arm/dts/zynqmp-r5.dts b/arch/arm/dts/zynqmp-r5.dts
new file mode 100644
index 0000000000..a72172ef2e
--- /dev/null
+++ b/arch/arm/dts/zynqmp-r5.dts
@@ -0,0 +1,73 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * dts file for Xilinx ZynqMP R5
+ *
+ * (C) Copyright 2018, Xilinx, Inc.
+ *
+ * Michal Simek <michal.simek@xilinx.com>
+ */
+
+/dts-v1/;
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "xlnx,zynqmp-r5";
+ model = "Xilinx ZynqMP R5";
+
+ cpus {
+ #address-cells = <0x1>;
+ #size-cells = <0x0>;
+
+ cpu@0 {
+ compatible = "arm,cortex-r5";
+ device_type = "cpu";
+ reg = <0>;
+ };
+ };
+
+ aliases {
+ serial0 = &uart1;
+ };
+
+ memory@0 {
+ device_type = "memory";
+ reg = <0x00000000 0x20000000>;
+ };
+
+ chosen {
+ bootargs = "";
+ stdout-path = "serial0:115200n8";
+ };
+
+ clk100: clk100 {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <100000000>;
+ u-boot,dm-pre-reloc;
+ };
+
+ amba {
+ u-boot,dm-pre-reloc;
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges;
+
+ ttc0: timer@ff110000 {
+ compatible = "cdns,ttc";
+ status = "okay";
+ reg = <0xff110000 0x1000>;
+ timer-width = <32>;
+ clocks = <&clk100>;
+ };
+
+ uart1: serial@ff010000 {
+ u-boot,dm-pre-reloc;
+ compatible = "cdns,uart-r1p12", "xlnx,xuartps";
+ reg = <0xff010000 0x1000>;
+ clock-names = "uart_clk", "pclk";
+ clocks = <&clk100 &clk100>;
+ };
+ };
+};
diff --git a/arch/arm/dts/zynqmp-zc1275-revB.dts b/arch/arm/dts/zynqmp-zc1275-revB.dts
new file mode 100644
index 0000000000..f694faeeb5
--- /dev/null
+++ b/arch/arm/dts/zynqmp-zc1275-revB.dts
@@ -0,0 +1,79 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * dts file for Xilinx ZynqMP ZC1275 RevB
+ *
+ * (C) Copyright 2018, Xilinx, Inc.
+ *
+ * Michal Simek <michal.simek@xilinx.com>
+ * Siva Durga Prasad Paladugu <sivadur@xilinx.com>
+ */
+
+/dts-v1/;
+
+#include "zynqmp.dtsi"
+#include "zynqmp-clk-ccf.dtsi"
+
+/ {
+ model = "ZynqMP ZC1275 RevB";
+ compatible = "xlnx,zynqmp-zc1275-revB", "xlnx,zynqmp-zc1275", "xlnx,zynqmp";
+
+ aliases {
+ serial0 = &uart0;
+ serial1 = &dcc;
+ spi0 = &qspi;
+ mmc0 = &sdhci1;
+ };
+
+ chosen {
+ bootargs = "earlycon";
+ stdout-path = "serial0:115200n8";
+ };
+
+ memory@0 {
+ device_type = "memory";
+ reg = <0x0 0x0 0x0 0x80000000>;
+ };
+};
+
+&dcc {
+ status = "okay";
+};
+
+&qspi {
+ status = "okay";
+ flash@0 {
+ compatible = "m25p80"; /* 32MB */
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x0>;
+ spi-tx-bus-width = <1>;
+ spi-rx-bus-width = <4>;
+ spi-max-frequency = <108000000>; /* Based on DC1 spec */
+ 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>;
+ };
+ };
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&sdhci1 {
+ status = "okay";
+ no-1-8-v;
+ xlnx,mio_bank = <1>;
+};
diff --git a/arch/arm/dts/zynqmp-zcu100-revC.dts b/arch/arm/dts/zynqmp-zcu100-revC.dts
index 9114f98140..bcd9c3958f 100644
--- a/arch/arm/dts/zynqmp-zcu100-revC.dts
+++ b/arch/arm/dts/zynqmp-zcu100-revC.dts
@@ -332,6 +332,7 @@
&watchdog0 {
status = "okay";
+ reset-on-timeout;
};
&xilinx_ams {
diff --git a/arch/arm/include/asm/arch-zynqmp/sys_proto.h b/arch/arm/include/asm/arch-zynqmp/sys_proto.h
index d1db4c38bb..6056bc6c0c 100644
--- a/arch/arm/include/asm/arch-zynqmp/sys_proto.h
+++ b/arch/arm/include/asm/arch-zynqmp/sys_proto.h
@@ -45,7 +45,7 @@ int invoke_smc(u32 pm_api_id, u32 arg0, u32 arg1, u32 arg2, u32 arg3,
u32 *ret_payload);
void initialize_tcm(bool mode);
-
+void mem_map_fill(void);
int chip_id(unsigned char id);
#endif /* _ASM_ARCH_SYS_PROTO_H */
diff --git a/arch/arm/mach-zynq/cpu.c b/arch/arm/mach-zynq/cpu.c
index df4eec8887..a3422cd5cf 100644
--- a/arch/arm/mach-zynq/cpu.c
+++ b/arch/arm/mach-zynq/cpu.c
@@ -4,14 +4,45 @@
* Copyright (C) 2012 Xilinx, Inc. All rights reserved.
*/
#include <common.h>
+#include <zynqpl.h>
#include <asm/io.h>
#include <asm/arch/clk.h>
-#include <asm/arch/sys_proto.h>
#include <asm/arch/hardware.h>
+#include <asm/arch/ps7_init_gpl.h>
+#include <asm/arch/sys_proto.h>
#define ZYNQ_SILICON_VER_MASK 0xF0000000
#define ZYNQ_SILICON_VER_SHIFT 28
+#if (defined(CONFIG_FPGA) && !defined(CONFIG_SPL_BUILD)) || \
+ (defined(CONFIG_SPL_FPGA_SUPPORT) && defined(CONFIG_SPL_BUILD))
+xilinx_desc fpga = {
+ .family = xilinx_zynq,
+ .iface = devcfg,
+ .operations = &zynq_op,
+};
+#endif
+
+static const struct {
+ u8 idcode;
+#if defined(CONFIG_FPGA)
+ u32 fpga_size;
+#endif
+ char *devicename;
+} zynq_fpga_descs[] = {
+ ZYNQ_DESC(7Z007S),
+ ZYNQ_DESC(7Z010),
+ ZYNQ_DESC(7Z012S),
+ ZYNQ_DESC(7Z014S),
+ ZYNQ_DESC(7Z015),
+ ZYNQ_DESC(7Z020),
+ ZYNQ_DESC(7Z030),
+ ZYNQ_DESC(7Z035),
+ ZYNQ_DESC(7Z045),
+ ZYNQ_DESC(7Z100),
+ { /* Sentinel */ },
+};
+
int arch_cpu_init(void)
{
zynq_slcr_unlock();
@@ -59,3 +90,55 @@ void enable_caches(void)
dcache_enable();
}
#endif
+
+static int __maybe_unused cpu_desc_id(void)
+{
+ u32 idcode;
+ u8 i;
+
+ idcode = zynq_slcr_get_idcode();
+ for (i = 0; zynq_fpga_descs[i].idcode; i++) {
+ if (zynq_fpga_descs[i].idcode == idcode)
+ return i;
+ }
+
+ return -ENODEV;
+}
+
+#if defined(CONFIG_ARCH_EARLY_INIT_R)
+int arch_early_init_r(void)
+{
+#if (defined(CONFIG_FPGA) && !defined(CONFIG_SPL_BUILD)) || \
+ (defined(CONFIG_SPL_FPGA_SUPPORT) && defined(CONFIG_SPL_BUILD))
+ int cpu_id = cpu_desc_id();
+
+ if (cpu_id < 0)
+ return 0;
+
+ fpga.size = zynq_fpga_descs[cpu_id].fpga_size;
+ fpga.name = zynq_fpga_descs[cpu_id].devicename;
+ fpga_init();
+ fpga_add(fpga_xilinx, &fpga);
+#endif
+ return 0;
+}
+#endif
+
+#ifdef CONFIG_DISPLAY_CPUINFO
+int print_cpuinfo(void)
+{
+ u32 version;
+ int cpu_id = cpu_desc_id();
+
+ if (cpu_id < 0)
+ return 0;
+
+ version = zynq_get_silicon_version() << 1;
+ if (version > (PCW_SILICON_VERSION_3 << 1))
+ version += 1;
+
+ printf("CPU: Zynq %s\n", zynq_fpga_descs[cpu_id].devicename);
+ printf("Silicon: v%d.%d\n", version >> 1, version & 1);
+ return 0;
+}
+#endif
diff --git a/arch/arm/mach-zynq/spl.c b/arch/arm/mach-zynq/spl.c
index 48e3d8d57f..83297d6c69 100644
--- a/arch/arm/mach-zynq/spl.c
+++ b/arch/arm/mach-zynq/spl.c
@@ -17,11 +17,12 @@ void board_init_f(ulong dummy)
ps7_init();
arch_cpu_init();
- /*
- * The debug UART can be used from this point:
- * debug_uart_init();
- * printch('x');
- */
+
+#ifdef CONFIG_DEBUG_UART
+ /* Uart debug for sure */
+ debug_uart_init();
+ puts("Debug uart enabled\n"); /* or printch() */
+#endif
}
#ifdef CONFIG_SPL_BOARD_INIT
diff --git a/arch/arm/mach-zynqmp-r5/Kconfig b/arch/arm/mach-zynqmp-r5/Kconfig
new file mode 100644
index 0000000000..5e01754133
--- /dev/null
+++ b/arch/arm/mach-zynqmp-r5/Kconfig
@@ -0,0 +1,27 @@
+# SPDX-License-Identifier: GPL-2.0
+
+if ARCH_ZYNQMP_R5
+
+config SYS_BOARD
+ string "Board name"
+ default "zynqmp_r5"
+
+config SYS_VENDOR
+ string "Vendor name"
+ default "xilinx"
+
+config SYS_SOC
+ default "zynqmp-r5"
+
+config SYS_CONFIG_NAME
+ string "Board configuration name"
+ default "xilinx_zynqmp_r5"
+ help
+ This option contains information about board configuration name.
+ Based on this option include/configs/<CONFIG_SYS_CONFIG_NAME>.h header
+ will be used for board configuration.
+
+config SYS_MALLOC_F_LEN
+ default 0x600
+
+endif
diff --git a/arch/arm/mach-zynqmp-r5/Makefile b/arch/arm/mach-zynqmp-r5/Makefile
new file mode 100644
index 0000000000..0d39e97dd3
--- /dev/null
+++ b/arch/arm/mach-zynqmp-r5/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-y += cpu.o
diff --git a/arch/arm/mach-zynqmp-r5/cpu.c b/arch/arm/mach-zynqmp-r5/cpu.c
new file mode 100644
index 0000000000..98f63e3427
--- /dev/null
+++ b/arch/arm/mach-zynqmp-r5/cpu.c
@@ -0,0 +1,37 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2018 Xilinx, Inc. (Michal Simek)
+ */
+
+#include <common.h>
+#include <asm/armv7_mpu.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct mpu_region_config region_config[] = {
+ { 0x00000000, REGION_0, XN_DIS, PRIV_RW_USR_RW,
+ O_I_WB_RD_WR_ALLOC, REGION_1GB },
+ { 0x20000000, REGION_1, XN_EN, PRIV_RO_USR_RO,
+ O_I_WB_RD_WR_ALLOC, REGION_512MB },
+ { 0x40000000, REGION_2, XN_EN, PRIV_RO_USR_RO,
+ O_I_WB_RD_WR_ALLOC, REGION_1GB },
+};
+
+int arch_cpu_init(void)
+{
+ gd->cpu_clk = CONFIG_CPU_FREQ_HZ;
+
+ setup_mpu_regions(region_config, sizeof(region_config) /
+ sizeof(struct mpu_region_config));
+
+ return 0;
+}
+
+/*
+ * Perform the low-level reset.
+ */
+void reset_cpu(ulong addr)
+{
+ while (1)
+ ;
+}