summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/Kconfig4
-rw-r--r--arch/arm/Makefile1
-rw-r--r--arch/arm/cpu/armv7/Makefile1
-rw-r--r--arch/arm/cpu/armv7/zynq/config.mk7
-rw-r--r--arch/arm/cpu/armv8/zynqmp/Makefile1
-rw-r--r--arch/arm/cpu/armv8/zynqmp/clk.c3
-rw-r--r--arch/arm/cpu/armv8/zynqmp/cpu.c166
-rw-r--r--arch/arm/cpu/armv8/zynqmp/mp.c242
-rw-r--r--arch/arm/dts/Makefile3
-rw-r--r--arch/arm/dts/zynq-picozed.dts23
-rw-r--r--arch/arm/include/asm/arch-zynq/gpio.h10
-rw-r--r--arch/arm/include/asm/arch-zynqmp/gpio.h12
-rw-r--r--arch/arm/include/asm/arch-zynqmp/hardware.h53
-rw-r--r--arch/arm/mach-zynq/Kconfig (renamed from arch/arm/cpu/armv7/zynq/Kconfig)6
-rw-r--r--arch/arm/mach-zynq/Makefile (renamed from arch/arm/cpu/armv7/zynq/Makefile)1
-rw-r--r--arch/arm/mach-zynq/clk.c (renamed from arch/arm/cpu/armv7/zynq/clk.c)0
-rw-r--r--arch/arm/mach-zynq/cpu.c (renamed from arch/arm/cpu/armv7/zynq/cpu.c)0
-rw-r--r--arch/arm/mach-zynq/ddrc.c (renamed from arch/arm/cpu/armv7/zynq/ddrc.c)0
-rw-r--r--arch/arm/mach-zynq/include/mach/clk.h (renamed from arch/arm/include/asm/arch-zynq/clk.h)0
-rw-r--r--arch/arm/mach-zynq/include/mach/gpio.h76
-rw-r--r--arch/arm/mach-zynq/include/mach/hardware.h (renamed from arch/arm/include/asm/arch-zynq/hardware.h)0
-rw-r--r--arch/arm/mach-zynq/include/mach/sys_proto.h (renamed from arch/arm/include/asm/arch-zynq/sys_proto.h)0
-rw-r--r--arch/arm/mach-zynq/lowlevel_init.S (renamed from arch/arm/cpu/armv7/zynq/lowlevel_init.S)0
-rw-r--r--arch/arm/mach-zynq/slcr.c (renamed from arch/arm/cpu/armv7/zynq/slcr.c)7
-rw-r--r--arch/arm/mach-zynq/spl.c (renamed from arch/arm/cpu/armv7/zynq/spl.c)2
-rw-r--r--arch/arm/mach-zynq/timer.c (renamed from arch/arm/cpu/armv7/zynq/timer.c)4
-rw-r--r--arch/arm/mach-zynq/u-boot-spl.lds (renamed from arch/arm/cpu/armv7/zynq/u-boot-spl.lds)0
-rw-r--r--arch/arm/mach-zynq/u-boot.lds (renamed from arch/arm/cpu/armv7/zynq/u-boot.lds)0
28 files changed, 594 insertions, 28 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 2167e29..00be305 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -649,7 +649,7 @@ config TARGET_COLIBRI_VF
bool "Support Colibri VF50/61"
select CPU_V7
-config ZYNQ
+config ARCH_ZYNQ
bool "Xilinx Zynq Platform"
select CPU_V7
select SUPPORT_SPL
@@ -837,7 +837,7 @@ source "arch/arm/mach-uniphier/Kconfig"
source "arch/arm/mach-versatile/Kconfig"
-source "arch/arm/cpu/armv7/zynq/Kconfig"
+source "arch/arm/mach-zynq/Kconfig"
source "arch/arm/cpu/armv7/Kconfig"
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index bd4749c..2a5620d 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -55,6 +55,7 @@ machine-$(CONFIG_ORION5X) += orion5x
machine-$(CONFIG_TEGRA) += tegra
machine-$(CONFIG_ARCH_UNIPHIER) += uniphier
machine-$(CONFIG_ARCH_VERSATILE) += versatile
+machine-$(CONFIG_ARCH_ZYNQ) += zynq
machdirs := $(patsubst %,arch/arm/mach-%/,$(machine-y))
diff --git a/arch/arm/cpu/armv7/Makefile b/arch/arm/cpu/armv7/Makefile
index e6249f1..fcccd0c 100644
--- a/arch/arm/cpu/armv7/Makefile
+++ b/arch/arm/cpu/armv7/Makefile
@@ -56,4 +56,3 @@ obj-$(if $(filter stv0991,$(SOC)),y) += stv0991/
obj-$(CONFIG_ARCH_SUNXI) += sunxi/
obj-$(CONFIG_U8500) += u8500/
obj-$(CONFIG_VF610) += vf610/
-obj-$(CONFIG_ZYNQ) += zynq/
diff --git a/arch/arm/cpu/armv7/zynq/config.mk b/arch/arm/cpu/armv7/zynq/config.mk
deleted file mode 100644
index 778a377..0000000
--- a/arch/arm/cpu/armv7/zynq/config.mk
+++ /dev/null
@@ -1,7 +0,0 @@
-#
-# Copyright (C) 2013 - 2015 Xilinx, Inc. All rights reserved.
-#
-# SPDX-License-Identifier: GPL-2.0
-#
-# Allow NEON instructions (needed for lowlevel_init.S with GNU toolchain)
-PLATFORM_RELFLAGS += -mfpu=neon
diff --git a/arch/arm/cpu/armv8/zynqmp/Makefile b/arch/arm/cpu/armv8/zynqmp/Makefile
index a997e04..efab5ea 100644
--- a/arch/arm/cpu/armv8/zynqmp/Makefile
+++ b/arch/arm/cpu/armv8/zynqmp/Makefile
@@ -7,3 +7,4 @@
obj-y += clk.o
obj-y += cpu.o
+obj-$(CONFIG_MP) += mp.o
diff --git a/arch/arm/cpu/armv8/zynqmp/clk.c b/arch/arm/cpu/armv8/zynqmp/clk.c
index 0af619d..9218586 100644
--- a/arch/arm/cpu/armv8/zynqmp/clk.c
+++ b/arch/arm/cpu/armv8/zynqmp/clk.c
@@ -6,6 +6,7 @@
*/
#include <common.h>
+#include <asm/arch/clk.h>
#include <asm/arch/hardware.h>
#include <asm/arch/sys_proto.h>
@@ -16,6 +17,8 @@ unsigned long get_uart_clk(int dev_id)
u32 ver = zynqmp_get_silicon_version();
switch (ver) {
+ case ZYNQMP_CSU_VERSION_VELOCE:
+ return 48000;
case ZYNQMP_CSU_VERSION_EP108:
return 25000000;
}
diff --git a/arch/arm/cpu/armv8/zynqmp/cpu.c b/arch/arm/cpu/armv8/zynqmp/cpu.c
index 6fae03c..60d7d20 100644
--- a/arch/arm/cpu/armv8/zynqmp/cpu.c
+++ b/arch/arm/cpu/armv8/zynqmp/cpu.c
@@ -20,9 +20,175 @@ unsigned int zynqmp_get_silicon_version(void)
gd->cpu_clk = get_tbclk();
switch (gd->cpu_clk) {
+ case 0 ... 1000000:
+ return ZYNQMP_CSU_VERSION_VELOCE;
case 50000000:
return ZYNQMP_CSU_VERSION_QEMU;
}
return ZYNQMP_CSU_VERSION_EP108;
}
+
+#ifndef CONFIG_SYS_DCACHE_OFF
+#include <asm/armv8/mmu.h>
+
+#define SECTION_SHIFT_L1 30UL
+#define SECTION_SHIFT_L2 21UL
+#define BLOCK_SIZE_L0 0x8000000000UL
+#define BLOCK_SIZE_L1 (1 << SECTION_SHIFT_L1)
+#define BLOCK_SIZE_L2 (1 << SECTION_SHIFT_L2)
+
+#define TCR_TG1_4K (1 << 31)
+#define TCR_EPD1_DISABLE (1 << 23)
+#define ZYNQMO_VA_BITS 40
+#define ZYNQMP_TCR TCR_TG1_4K | \
+ TCR_EPD1_DISABLE | \
+ TCR_SHARED_OUTER | \
+ TCR_SHARED_INNER | \
+ TCR_IRGN_WBWA | \
+ TCR_ORGN_WBWA | \
+ TCR_T0SZ(ZYNQMO_VA_BITS)
+
+#define MEMORY_ATTR PMD_SECT_AF | PMD_SECT_INNER_SHARE | \
+ PMD_ATTRINDX(MT_NORMAL) | \
+ PMD_TYPE_SECT
+#define DEVICE_ATTR PMD_SECT_AF | PMD_SECT_PXN | \
+ PMD_SECT_UXN | PMD_ATTRINDX(MT_DEVICE_NGNRNE) | \
+ PMD_TYPE_SECT
+
+/* 4K size is required to place 512 entries in each level */
+#define TLB_TABLE_SIZE 0x1000
+
+struct attr_tbl {
+ u32 num;
+ u64 attr;
+};
+
+static struct attr_tbl attr_tbll1t0[4] = { {16, 0x0},
+ {8, DEVICE_ATTR},
+ {32, MEMORY_ATTR},
+ {456, DEVICE_ATTR}
+ };
+static struct attr_tbl attr_tbll2t3[4] = { {0x180, DEVICE_ATTR},
+ {0x40, 0x0},
+ {0x3F, DEVICE_ATTR},
+ {0x1, MEMORY_ATTR}
+ };
+
+/*
+ * This mmu table looks as below
+ * Level 0 table contains two entries to 512GB sizes. One is Level1 Table 0
+ * and other Level1 Table1.
+ * Level1 Table0 contains entries for each 1GB from 0 to 511GB.
+ * Level1 Table1 contains entries for each 1GB from 512GB to 1TB.
+ * Level2 Table0, Level2 Table1, Level2 Table2 and Level2 Table3 contains
+ * entries for each 2MB starting from 0GB, 1GB, 2GB and 3GB respectively.
+ */
+static void zynqmp_mmu_setup(void)
+{
+ int el;
+ u32 index_attr;
+ u64 i, section_l1t0, section_l1t1;
+ u64 section_l2t0, section_l2t1, section_l2t2, section_l2t3;
+ u64 *level0_table = (u64 *)gd->arch.tlb_addr;
+ u64 *level1_table_0 = (u64 *)(gd->arch.tlb_addr + TLB_TABLE_SIZE);
+ u64 *level1_table_1 = (u64 *)(gd->arch.tlb_addr + (2 * TLB_TABLE_SIZE));
+ u64 *level2_table_0 = (u64 *)(gd->arch.tlb_addr + (3 * TLB_TABLE_SIZE));
+ u64 *level2_table_1 = (u64 *)(gd->arch.tlb_addr + (4 * TLB_TABLE_SIZE));
+ u64 *level2_table_2 = (u64 *)(gd->arch.tlb_addr + (5 * TLB_TABLE_SIZE));
+ u64 *level2_table_3 = (u64 *)(gd->arch.tlb_addr + (6 * TLB_TABLE_SIZE));
+
+ level0_table[0] =
+ (u64)level1_table_0 | PMD_TYPE_TABLE;
+ level0_table[1] =
+ (u64)level1_table_1 | PMD_TYPE_TABLE;
+
+ /*
+ * set level 1 table 0, covering 0 to 512GB
+ * set level 1 table 1, covering 512GB to 1TB
+ */
+ section_l1t0 = 0;
+ section_l1t1 = BLOCK_SIZE_L0;
+
+ index_attr = 0;
+ for (i = 0; i < 512; i++) {
+ level1_table_0[i] = section_l1t0;
+ level1_table_0[i] |= attr_tbll1t0[index_attr].attr;
+ attr_tbll1t0[index_attr].num--;
+ if (attr_tbll1t0[index_attr].num == 0)
+ index_attr++;
+ level1_table_1[i] = section_l1t1;
+ level1_table_1[i] |= DEVICE_ATTR;
+ section_l1t0 += BLOCK_SIZE_L1;
+ section_l1t1 += BLOCK_SIZE_L1;
+ }
+
+ level1_table_0[0] =
+ (u64)level2_table_0 | PMD_TYPE_TABLE;
+ level1_table_0[1] =
+ (u64)level2_table_1 | PMD_TYPE_TABLE;
+ level1_table_0[2] =
+ (u64)level2_table_2 | PMD_TYPE_TABLE;
+ level1_table_0[3] =
+ (u64)level2_table_3 | PMD_TYPE_TABLE;
+
+ section_l2t0 = 0;
+ section_l2t1 = section_l2t0 + BLOCK_SIZE_L1; /* 1GB */
+ section_l2t2 = section_l2t1 + BLOCK_SIZE_L1; /* 2GB */
+ section_l2t3 = section_l2t2 + BLOCK_SIZE_L1; /* 3GB */
+
+ index_attr = 0;
+
+ for (i = 0; i < 512; i++) {
+ level2_table_0[i] = section_l2t0 | MEMORY_ATTR;
+ level2_table_1[i] = section_l2t1 | MEMORY_ATTR;
+ level2_table_2[i] = section_l2t2 | DEVICE_ATTR;
+ level2_table_3[i] = section_l2t3 |
+ attr_tbll2t3[index_attr].attr;
+ attr_tbll2t3[index_attr].num--;
+ if (attr_tbll2t3[index_attr].num == 0)
+ index_attr++;
+ section_l2t0 += BLOCK_SIZE_L2;
+ section_l2t1 += BLOCK_SIZE_L2;
+ section_l2t2 += BLOCK_SIZE_L2;
+ section_l2t3 += BLOCK_SIZE_L2;
+ }
+
+ /* flush new MMU table */
+ flush_dcache_range(gd->arch.tlb_addr,
+ gd->arch.tlb_addr + gd->arch.tlb_size);
+
+ /* point TTBR to the new table */
+ el = current_el();
+ set_ttbr_tcr_mair(el, gd->arch.tlb_addr,
+ ZYNQMP_TCR, MEMORY_ATTRIBUTES);
+
+ set_sctlr(get_sctlr() | CR_M);
+}
+
+int arch_cpu_init(void)
+{
+ icache_enable();
+ __asm_invalidate_dcache_all();
+ __asm_invalidate_tlb_all();
+ return 0;
+}
+
+/*
+ * This function is called from lib/board.c.
+ * It recreates MMU table in main memory. MMU and d-cache are enabled earlier.
+ * There is no need to disable d-cache for this operation.
+ */
+void enable_caches(void)
+{
+ /* The data cache is not active unless the mmu is enabled */
+ if (!(get_sctlr() & CR_M)) {
+ invalidate_dcache_all();
+ __asm_invalidate_tlb_all();
+ zynqmp_mmu_setup();
+ }
+ puts("Enabling Caches...\n");
+
+ set_sctlr(get_sctlr() | CR_C);
+}
+#endif
diff --git a/arch/arm/cpu/armv8/zynqmp/mp.c b/arch/arm/cpu/armv8/zynqmp/mp.c
new file mode 100644
index 0000000..17e32a7
--- /dev/null
+++ b/arch/arm/cpu/armv8/zynqmp/mp.c
@@ -0,0 +1,242 @@
+/*
+ * (C) Copyright 2014 - 2015 Xilinx, Inc.
+ * Michal Simek <michal.simek@xilinx.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/io.h>
+
+#define LOCK 0
+#define SPLIT 1
+
+#define HALT 0
+#define RELEASE 1
+
+#define ZYNQMP_BOOTADDR_HIGH_MASK 0xFFFFFFFF
+#define ZYNQMP_R5_HIVEC_ADDR 0xFFFF0000
+#define ZYNQMP_R5_LOVEC_ADDR 0x0
+#define ZYNQMP_RPU_CFG_CPU_HALT_MASK 0x01
+#define ZYNQMP_RPU_CFG_HIVEC_MASK 0x04
+#define ZYNQMP_RPU_GLBL_CTRL_SPLIT_LOCK_MASK 0x08
+#define ZYNQMP_RPU_GLBL_CTRL_TCM_COMB_MASK 0x40
+#define ZYNQMP_RPU_GLBL_CTRL_SLCLAMP_MASK 0x10
+
+#define ZYNQMP_CRLAPB_RST_LPD_AMBA_RST_MASK 0x04
+#define ZYNQMP_CRLAPB_RST_LPD_R50_RST_MASK 0x01
+#define ZYNQMP_CRLAPB_RST_LPD_R51_RST_MASK 0x02
+#define ZYNQMP_CRLAPB_CPU_R5_CTRL_CLKACT_MASK 0x1000000
+
+#define ZYNQMP_TCM_START_ADDRESS 0xFFE00000
+#define ZYNQMP_TCM_BOTH_SIZE 0x40000
+
+#define ZYNQMP_CORE_APU0 0
+#define ZYNQMP_CORE_APU3 3
+
+#define ZYNQMP_MAX_CORES 6
+
+int is_core_valid(unsigned int core)
+{
+ if (core < ZYNQMP_MAX_CORES)
+ return 1;
+
+ return 0;
+}
+
+int cpu_reset(int nr)
+{
+ puts("Feature is not implemented.\n");
+ return 0;
+}
+
+static void set_r5_halt_mode(u8 halt, u8 mode)
+{
+ u32 tmp;
+
+ tmp = readl(&rpu_base->rpu0_cfg);
+ if (halt == HALT)
+ tmp &= ~ZYNQMP_RPU_CFG_CPU_HALT_MASK;
+ else
+ tmp |= ZYNQMP_RPU_CFG_CPU_HALT_MASK;
+ writel(tmp, &rpu_base->rpu0_cfg);
+
+ if (mode == LOCK) {
+ tmp = readl(&rpu_base->rpu1_cfg);
+ if (halt == HALT)
+ tmp &= ~ZYNQMP_RPU_CFG_CPU_HALT_MASK;
+ else
+ tmp |= ZYNQMP_RPU_CFG_CPU_HALT_MASK;
+ writel(tmp, &rpu_base->rpu1_cfg);
+ }
+}
+
+static void set_r5_tcm_mode(u8 mode)
+{
+ u32 tmp;
+
+ tmp = readl(&rpu_base->rpu_glbl_ctrl);
+ if (mode == LOCK) {
+ tmp &= ~ZYNQMP_RPU_GLBL_CTRL_SPLIT_LOCK_MASK;
+ tmp |= ZYNQMP_RPU_GLBL_CTRL_TCM_COMB_MASK |
+ ZYNQMP_RPU_GLBL_CTRL_SLCLAMP_MASK;
+ } else {
+ tmp |= ZYNQMP_RPU_GLBL_CTRL_SPLIT_LOCK_MASK;
+ tmp &= ~(ZYNQMP_RPU_GLBL_CTRL_TCM_COMB_MASK |
+ ZYNQMP_RPU_GLBL_CTRL_SLCLAMP_MASK);
+ }
+
+ writel(tmp, &rpu_base->rpu_glbl_ctrl);
+}
+
+static void set_r5_reset(u8 mode)
+{
+ u32 tmp;
+
+ tmp = readl(&crlapb_base->rst_lpd_top);
+ tmp |= (ZYNQMP_CRLAPB_RST_LPD_AMBA_RST_MASK |
+ ZYNQMP_CRLAPB_RST_LPD_R50_RST_MASK);
+
+ if (mode == LOCK)
+ tmp |= ZYNQMP_CRLAPB_RST_LPD_R51_RST_MASK;
+
+ writel(tmp, &crlapb_base->rst_lpd_top);
+}
+
+static void release_r5_reset(u8 mode)
+{
+ u32 tmp;
+
+ tmp = readl(&crlapb_base->rst_lpd_top);
+ tmp &= ~(ZYNQMP_CRLAPB_RST_LPD_AMBA_RST_MASK |
+ ZYNQMP_CRLAPB_RST_LPD_R50_RST_MASK);
+
+ if (mode == LOCK)
+ tmp &= ~ZYNQMP_CRLAPB_RST_LPD_R51_RST_MASK;
+
+ writel(tmp, &crlapb_base->rst_lpd_top);
+}
+
+static void enable_clock_r5(void)
+{
+ u32 tmp;
+
+ tmp = readl(&crlapb_base->cpu_r5_ctrl);
+ tmp |= ZYNQMP_CRLAPB_CPU_R5_CTRL_CLKACT_MASK;
+ writel(tmp, &crlapb_base->cpu_r5_ctrl);
+
+ /* Give some delay for clock
+ * to propogate */
+ udelay(0x500);
+}
+
+int cpu_disable(int nr)
+{
+ if (nr >= ZYNQMP_CORE_APU0 && nr <= ZYNQMP_CORE_APU3) {
+ u32 val = readl(&crfapb_base->rst_fpd_apu);
+ val |= 1 << nr;
+ writel(val, &crfapb_base->rst_fpd_apu);
+ } else {
+ set_r5_reset(LOCK);
+ }
+
+ return 0;
+}
+
+int cpu_status(int nr)
+{
+ if (nr >= ZYNQMP_CORE_APU0 && nr <= ZYNQMP_CORE_APU3) {
+ u32 addr_low = readl(((u8 *)&apu_base->rvbar_addr0_l) + nr * 8);
+ u32 addr_high = readl(((u8 *)&apu_base->rvbar_addr0_h) +
+ nr * 8);
+ u32 val = readl(&crfapb_base->rst_fpd_apu);
+ val &= 1 << nr;
+ printf("APU CPU%d %s - starting address HI: %x, LOW: %x\n",
+ nr, val ? "OFF" : "ON" , addr_high, addr_low);
+ } else {
+ u32 val = readl(&crlapb_base->rst_lpd_top);
+ val &= 1 << (nr - 4);
+ printf("RPU CPU%d %s\n", nr - 4, val ? "OFF" : "ON");
+ }
+
+ return 0;
+}
+
+static void set_r5_start(u8 high)
+{
+ u32 tmp;
+
+ tmp = readl(&rpu_base->rpu0_cfg);
+ if (high)
+ tmp |= ZYNQMP_RPU_CFG_HIVEC_MASK;
+ else
+ tmp &= ~ZYNQMP_RPU_CFG_HIVEC_MASK;
+ writel(tmp, &rpu_base->rpu0_cfg);
+
+ tmp = readl(&rpu_base->rpu1_cfg);
+ if (high)
+ tmp |= ZYNQMP_RPU_CFG_HIVEC_MASK;
+ else
+ tmp &= ~ZYNQMP_RPU_CFG_HIVEC_MASK;
+ writel(tmp, &rpu_base->rpu1_cfg);
+}
+
+int cpu_release(int nr, int argc, char * const argv[])
+{
+ if (nr >= ZYNQMP_CORE_APU0 && nr <= ZYNQMP_CORE_APU3) {
+ u64 boot_addr = simple_strtoull(argv[0], NULL, 16);
+ /* HIGH */
+ writel((u32)(boot_addr >> 32),
+ ((u8 *)&apu_base->rvbar_addr0_h) + nr * 8);
+ /* LOW */
+ writel((u32)(boot_addr & ZYNQMP_BOOTADDR_HIGH_MASK),
+ ((u8 *)&apu_base->rvbar_addr0_l) + nr * 8);
+
+ u32 val = readl(&crfapb_base->rst_fpd_apu);
+ val &= ~(1 << nr);
+ writel(val, &crfapb_base->rst_fpd_apu);
+ } else {
+ if (argc != 2) {
+ printf("Invalid number of arguments to release.\n");
+ printf("<addr> <mode>-Start addr lockstep or split\n");
+ return 1;
+ }
+
+ u32 boot_addr = simple_strtoul(argv[0], NULL, 16);
+ if (!(boot_addr == ZYNQMP_R5_LOVEC_ADDR ||
+ boot_addr == ZYNQMP_R5_HIVEC_ADDR)) {
+ printf("Invalid starting address 0x%x\n", boot_addr);
+ printf("0 or 0xffff0000 are permitted\n");
+ return 1;
+ }
+
+ if (!strncmp(argv[1], "lockstep", 8)) {
+ printf("R5 lockstep mode\n");
+ set_r5_tcm_mode(LOCK);
+ set_r5_halt_mode(HALT, LOCK);
+
+ if (boot_addr == 0)
+ set_r5_start(0);
+ else
+ set_r5_start(1);
+
+ enable_clock_r5();
+ release_r5_reset(LOCK);
+ set_r5_halt_mode(RELEASE, LOCK);
+ } else if (!strncmp(argv[1], "split", 5)) {
+ printf("R5 split mode\n");
+ set_r5_tcm_mode(SPLIT);
+ set_r5_halt_mode(HALT, SPLIT);
+ enable_clock_r5();
+ release_r5_reset(SPLIT);
+ set_r5_halt_mode(RELEASE, SPLIT);
+ } else {
+ printf("Unsupported mode\n");
+ return 1;
+ }
+ }
+
+ return 0;
+}
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 09708d9..46a6171 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -39,11 +39,12 @@ dtb-$(CONFIG_ARCH_UNIPHIER) += \
uniphier-ph1-pro4-ref.dtb \
uniphier-ph1-ld4-ref.dtb \
uniphier-ph1-sld8-ref.dtb
-dtb-$(CONFIG_ZYNQ) += zynq-zc702.dtb \
+dtb-$(CONFIG_ARCH_ZYNQ) += zynq-zc702.dtb \
zynq-zc706.dtb \
zynq-zed.dtb \
zynq-zybo.dtb \
zynq-microzed.dtb \
+ zynq-picozed.dtb \
zynq-zc770-xm010.dtb \
zynq-zc770-xm012.dtb \
zynq-zc770-xm013.dtb
diff --git a/arch/arm/dts/zynq-picozed.dts b/arch/arm/dts/zynq-picozed.dts
new file mode 100644
index 0000000..686b98f
--- /dev/null
+++ b/arch/arm/dts/zynq-picozed.dts
@@ -0,0 +1,23 @@
+/*
+ * Avnet PicoZed board DTS
+ *
+ * Copyright (C) 2015 Xilinx, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+/dts-v1/;
+#include "zynq-7000.dtsi"
+
+/ {
+ model = "Zynq PicoZed Board";
+ compatible = "xlnx,zynq-picozed", "xlnx,zynq-7000";
+
+ aliases {
+ serial0 = &uart1;
+ };
+
+ memory {
+ device_type = "memory";
+ reg = <0 0x40000000>;
+ };
+};
diff --git a/arch/arm/include/asm/arch-zynq/gpio.h b/arch/arm/include/asm/arch-zynq/gpio.h
deleted file mode 100644
index a26ae87..0000000
--- a/arch/arm/include/asm/arch-zynq/gpio.h
+++ /dev/null
@@ -1,10 +0,0 @@
-/*
- * Copyright (c) 2013 Xilinx, Inc.
- *
- * SPDX-License-Identifier: GPL-2.0+
- */
-
-#ifndef _ZYNQ_GPIO_H
-#define _ZYNQ_GPIO_H
-
-#endif /* _ZYNQ_GPIO_H */
diff --git a/arch/arm/include/asm/arch-zynqmp/gpio.h b/arch/arm/include/asm/arch-zynqmp/gpio.h
new file mode 100644
index 0000000..098bbde
--- /dev/null
+++ b/arch/arm/include/asm/arch-zynqmp/gpio.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright 2015 Xilinx, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __ARCH_ZYNQMP_GPIO_H
+#define __ARCH_ZYNQMP_GPIO_H
+
+/* Empty file - sdhci requires this. */
+
+#endif
diff --git a/arch/arm/include/asm/arch-zynqmp/hardware.h b/arch/arm/include/asm/arch-zynqmp/hardware.h
index 97fb49a..c9dc49d 100644
--- a/arch/arm/include/asm/arch-zynqmp/hardware.h
+++ b/arch/arm/include/asm/arch-zynqmp/hardware.h
@@ -11,6 +11,12 @@
#define ZYNQ_SERIAL_BASEADDR0 0xFF000000
#define ZYNQ_SERIAL_BASEADDR1 0xFF001000
+#define ZYNQ_SPI_BASEADDR0 0xFF040000
+#define ZYNQ_SPI_BASEADDR1 0xFF050000
+
+#define ZYNQ_I2C_BASEADDR0 0xFF020000
+#define ZYNQ_I2C_BASEADDR1 0xFF030000
+
#define ZYNQ_SDHCI_BASEADDR0 0xFF160000
#define ZYNQ_SDHCI_BASEADDR1 0xFF170000
@@ -18,11 +24,15 @@
#define ZYNQMP_CRL_APB_TIMESTAMP_REF_CTRL_CLKACT 0x1000000
struct crlapb_regs {
- u32 reserved0[74];
+ u32 reserved0[36];
+ u32 cpu_r5_ctrl; /* 0x90 */
+ u32 reserved1[37];
u32 timestamp_ref_ctrl; /* 0x128 */
- u32 reserved0_1[53];
+ u32 reserved2[53];
u32 boot_mode; /* 0x200 */
- u32 reserved1[26];
+ u32 reserved3[14];
+ u32 rst_lpd_top; /* 0x23C */
+ u32 reserved4[26];
};
#define crlapb_base ((struct crlapb_regs *)ZYNQMP_CRL_APB_BASEADDR)
@@ -41,12 +51,47 @@ struct iou_scntr {
/* Bootmode setting values */
#define BOOT_MODES_MASK 0x0000000F
-#define SD_MODE 0x00000005
+#define SD_MODE 0x00000003
+#define EMMC_MODE 0x00000006
#define JTAG_MODE 0x00000000
+#define ZYNQMP_RPU_BASEADDR 0xFF9A0000
+
+struct rpu_regs {
+ u32 rpu_glbl_ctrl;
+ u32 reserved0[63];
+ u32 rpu0_cfg; /* 0x100 */
+ u32 reserved1[63];
+ u32 rpu1_cfg; /* 0x200 */
+};
+
+#define rpu_base ((struct rpu_regs *)ZYNQMP_RPU_BASEADDR)
+
+#define ZYNQMP_CRF_APB_BASEADDR 0xFD1A0000
+
+struct crfapb_regs {
+ u32 reserved0[65];
+ u32 rst_fpd_apu; /* 0x104 */
+ u32 reserved1;
+};
+
+#define crfapb_base ((struct crfapb_regs *)ZYNQMP_CRF_APB_BASEADDR)
+
+#define ZYNQMP_APU_BASEADDR 0xFD5C0000
+
+struct apu_regs {
+ u32 reserved0[16];
+ u32 rvbar_addr0_l; /* 0x40 */
+ u32 rvbar_addr0_h; /* 0x44 */
+ u32 reserved1[20];
+};
+
+#define apu_base ((struct apu_regs *)ZYNQMP_APU_BASEADDR)
+
/* Board version value */
#define ZYNQMP_CSU_VERSION_SILICON 0x0
#define ZYNQMP_CSU_VERSION_EP108 0x1
+#define ZYNQMP_CSU_VERSION_VELOCE 0x2
#define ZYNQMP_CSU_VERSION_QEMU 0x3
#endif /* _ASM_ARCH_HARDWARE_H */
diff --git a/arch/arm/cpu/armv7/zynq/Kconfig b/arch/arm/mach-zynq/Kconfig
index 3a52535..1046ece 100644
--- a/arch/arm/cpu/armv7/zynq/Kconfig
+++ b/arch/arm/mach-zynq/Kconfig
@@ -1,4 +1,4 @@
-if ZYNQ
+if ARCH_ZYNQ
choice
prompt "Xilinx Zynq board select"
@@ -9,6 +9,9 @@ config TARGET_ZYNQ_ZED
config TARGET_ZYNQ_MICROZED
bool "Zynq MicroZed"
+config TARGET_ZYNQ_PICOZED
+ bool "Zynq PicoZed"
+
config TARGET_ZYNQ_ZC70X
bool "Zynq ZC702/ZC706 Board"
@@ -32,6 +35,7 @@ config SYS_SOC
config SYS_CONFIG_NAME
default "zynq_zed" if TARGET_ZYNQ_ZED
default "zynq_microzed" if TARGET_ZYNQ_MICROZED
+ default "zynq_picozed" if TARGET_ZYNQ_PICOZED
default "zynq_zc70x" if TARGET_ZYNQ_ZC70X
default "zynq_zc770" if TARGET_ZYNQ_ZC770
default "zynq_zybo" if TARGET_ZYNQ_ZYBO
diff --git a/arch/arm/cpu/armv7/zynq/Makefile b/arch/arm/mach-zynq/Makefile
index 901f2ce..bf29b4d 100644
--- a/arch/arm/cpu/armv7/zynq/Makefile
+++ b/arch/arm/mach-zynq/Makefile
@@ -14,4 +14,5 @@ obj-y += ddrc.o
obj-y += slcr.o
obj-y += clk.o
obj-y += lowlevel_init.o
+AFLAGS_lowlevel_init.o := -mfpu=neon
obj-$(CONFIG_SPL_BUILD) += spl.o
diff --git a/arch/arm/cpu/armv7/zynq/clk.c b/arch/arm/mach-zynq/clk.c
index d2885dc..d2885dc 100644
--- a/arch/arm/cpu/armv7/zynq/clk.c
+++ b/arch/arm/mach-zynq/clk.c
diff --git a/arch/arm/cpu/armv7/zynq/cpu.c b/arch/arm/mach-zynq/cpu.c
index 914b1fe..914b1fe 100644
--- a/arch/arm/cpu/armv7/zynq/cpu.c
+++ b/arch/arm/mach-zynq/cpu.c
diff --git a/arch/arm/cpu/armv7/zynq/ddrc.c b/arch/arm/mach-zynq/ddrc.c
index 5b20acc..5b20acc 100644
--- a/arch/arm/cpu/armv7/zynq/ddrc.c
+++ b/arch/arm/mach-zynq/ddrc.c
diff --git a/arch/arm/include/asm/arch-zynq/clk.h b/arch/arm/mach-zynq/include/mach/clk.h
index 250c5bc..250c5bc 100644
--- a/arch/arm/include/asm/arch-zynq/clk.h
+++ b/arch/arm/mach-zynq/include/mach/clk.h
diff --git a/arch/arm/mach-zynq/include/mach/gpio.h b/arch/arm/mach-zynq/include/mach/gpio.h
new file mode 100644
index 0000000..9e1e7da
--- /dev/null
+++ b/arch/arm/mach-zynq/include/mach/gpio.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2013 Xilinx, Inc.
+ * Copyright (c) 2015 DAVE Embedded Systems
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _ZYNQ_GPIO_H
+#define _ZYNQ_GPIO_H
+
+#define ZYNQ_GPIO_BASE_ADDRESS 0xE000A000
+
+/* Maximum banks */
+#define ZYNQ_GPIO_MAX_BANK 4
+
+#define ZYNQ_GPIO_BANK0_NGPIO 32
+#define ZYNQ_GPIO_BANK1_NGPIO 22
+#define ZYNQ_GPIO_BANK2_NGPIO 32
+#define ZYNQ_GPIO_BANK3_NGPIO 32
+
+#define ZYNQ_GPIO_NR_GPIOS (ZYNQ_GPIO_BANK0_NGPIO + \
+ ZYNQ_GPIO_BANK1_NGPIO + \
+ ZYNQ_GPIO_BANK2_NGPIO + \
+ ZYNQ_GPIO_BANK3_NGPIO)
+
+#define ZYNQ_GPIO_BANK0_PIN_MIN 0
+#define ZYNQ_GPIO_BANK0_PIN_MAX (ZYNQ_GPIO_BANK0_PIN_MIN + \
+ ZYNQ_GPIO_BANK0_NGPIO - 1)
+#define ZYNQ_GPIO_BANK1_PIN_MIN (ZYNQ_GPIO_BANK0_PIN_MAX + 1)
+#define ZYNQ_GPIO_BANK1_PIN_MAX (ZYNQ_GPIO_BANK1_PIN_MIN + \
+ ZYNQ_GPIO_BANK1_NGPIO - 1)
+#define ZYNQ_GPIO_BANK2_PIN_MIN (ZYNQ_GPIO_BANK1_PIN_MAX + 1)
+#define ZYNQ_GPIO_BANK2_PIN_MAX (ZYNQ_GPIO_BANK2_PIN_MIN + \
+ ZYNQ_GPIO_BANK2_NGPIO - 1)
+#define ZYNQ_GPIO_BANK3_PIN_MIN (ZYNQ_GPIO_BANK2_PIN_MAX + 1)
+#define ZYNQ_GPIO_BANK3_PIN_MAX (ZYNQ_GPIO_BANK3_PIN_MIN + \
+ ZYNQ_GPIO_BANK3_NGPIO - 1)
+
+/* Register offsets for the GPIO device */
+/* LSW Mask & Data -WO */
+#define ZYNQ_GPIO_DATA_LSW_OFFSET(BANK) (0x000 + (8 * BANK))
+/* MSW Mask & Data -WO */
+#define ZYNQ_GPIO_DATA_MSW_OFFSET(BANK) (0x004 + (8 * BANK))
+/* Data Register-RW */
+#define ZYNQ_GPIO_DATA_RO_OFFSET(BANK) (0x060 + (4 * BANK))
+/* Direction mode reg-RW */
+#define ZYNQ_GPIO_DIRM_OFFSET(BANK) (0x204 + (0x40 * BANK))
+/* Output enable reg-RW */
+#define ZYNQ_GPIO_OUTEN_OFFSET(BANK) (0x208 + (0x40 * BANK))
+/* Interrupt mask reg-RO */
+#define ZYNQ_GPIO_INTMASK_OFFSET(BANK) (0x20C + (0x40 * BANK))
+/* Interrupt enable reg-WO */
+#define ZYNQ_GPIO_INTEN_OFFSET(BANK) (0x210 + (0x40 * BANK))
+/* Interrupt disable reg-WO */
+#define ZYNQ_GPIO_INTDIS_OFFSET(BANK) (0x214 + (0x40 * BANK))
+/* Interrupt status reg-RO */
+#define ZYNQ_GPIO_INTSTS_OFFSET(BANK) (0x218 + (0x40 * BANK))
+/* Interrupt type reg-RW */
+#define ZYNQ_GPIO_INTTYPE_OFFSET(BANK) (0x21C + (0x40 * BANK))
+/* Interrupt polarity reg-RW */
+#define ZYNQ_GPIO_INTPOL_OFFSET(BANK) (0x220 + (0x40 * BANK))
+/* Interrupt on any, reg-RW */
+#define ZYNQ_GPIO_INTANY_OFFSET(BANK) (0x224 + (0x40 * BANK))
+
+/* Disable all interrupts mask */
+#define ZYNQ_GPIO_IXR_DISABLE_ALL 0xFFFFFFFF
+
+/* Mid pin number of a bank */
+#define ZYNQ_GPIO_MID_PIN_NUM 16
+
+/* GPIO upper 16 bit mask */
+#define ZYNQ_GPIO_UPPER_MASK 0xFFFF0000
+
+#define BIT(x) (1<<x)
+
+#endif /* _ZYNQ_GPIO_H */
diff --git a/arch/arm/include/asm/arch-zynq/hardware.h b/arch/arm/mach-zynq/include/mach/hardware.h
index e2e0b73..e2e0b73 100644
--- a/arch/arm/include/asm/arch-zynq/hardware.h
+++ b/arch/arm/mach-zynq/include/mach/hardware.h
diff --git a/arch/arm/include/asm/arch-zynq/sys_proto.h b/arch/arm/mach-zynq/include/mach/sys_proto.h
index 9d50e24..9d50e24 100644
--- a/arch/arm/include/asm/arch-zynq/sys_proto.h
+++ b/arch/arm/mach-zynq/include/mach/sys_proto.h
diff --git a/arch/arm/cpu/armv7/zynq/lowlevel_init.S b/arch/arm/mach-zynq/lowlevel_init.S
index 6d714b7..6d714b7 100644
--- a/arch/arm/cpu/armv7/zynq/lowlevel_init.S
+++ b/arch/arm/mach-zynq/lowlevel_init.S
diff --git a/arch/arm/cpu/armv7/zynq/slcr.c b/arch/arm/mach-zynq/slcr.c
index 2521589..05f4099 100644
--- a/arch/arm/cpu/armv7/zynq/slcr.c
+++ b/arch/arm/mach-zynq/slcr.c
@@ -129,11 +129,18 @@ out:
void zynq_slcr_devcfg_disable(void)
{
+ u32 reg_val;
+
zynq_slcr_unlock();
/* Disable AXI interface by asserting FPGA resets */
writel(0xF, &slcr_base->fpga_rst_ctrl);
+ /* Disable Level shifters before setting PS-PL */
+ reg_val = readl(&slcr_base->lvl_shftr_en);
+ reg_val &= ~0xF;
+ writel(reg_val, &slcr_base->lvl_shftr_en);
+
/* Set Level Shifters DT618760 */
writel(0xA, &slcr_base->lvl_shftr_en);
diff --git a/arch/arm/cpu/armv7/zynq/spl.c b/arch/arm/mach-zynq/spl.c
index b80c357..13025f0 100644
--- a/arch/arm/cpu/armv7/zynq/spl.c
+++ b/arch/arm/mach-zynq/spl.c
@@ -85,6 +85,6 @@ __weak void ps7_init(void)
{
/*
* This function is overridden by the one in
- * board/xilinx/zynq/ps7_init.c, if it exists.
+ * board/xilinx/zynq/ps7_init_gpl.c, if it exists.
*/
}
diff --git a/arch/arm/cpu/armv7/zynq/timer.c b/arch/arm/mach-zynq/timer.c
index 303dbcf..5ed9642 100644
--- a/arch/arm/cpu/armv7/zynq/timer.c
+++ b/arch/arm/mach-zynq/timer.c
@@ -93,7 +93,9 @@ ulong get_timer_masked(void)
gd->arch.tbl += gd->arch.lastinc - now;
} else {
/* We have an overflow ... */
- gd->arch.tbl += gd->arch.lastinc + TIMER_LOAD_VAL - now + 1;
+ gd->arch.tbl += gd->arch.lastinc + (TIMER_LOAD_VAL /
+ (gd->arch.timer_rate_hz / CONFIG_SYS_HZ)) -
+ now + 1;
}
gd->arch.lastinc = now;
diff --git a/arch/arm/cpu/armv7/zynq/u-boot-spl.lds b/arch/arm/mach-zynq/u-boot-spl.lds
index 0f2f756..0f2f756 100644
--- a/arch/arm/cpu/armv7/zynq/u-boot-spl.lds
+++ b/arch/arm/mach-zynq/u-boot-spl.lds
diff --git a/arch/arm/cpu/armv7/zynq/u-boot.lds b/arch/arm/mach-zynq/u-boot.lds
index 4dc9bb0..4dc9bb0 100644
--- a/arch/arm/cpu/armv7/zynq/u-boot.lds
+++ b/arch/arm/mach-zynq/u-boot.lds