aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2015-04-29 06:46:33 -0400
committerTom Rini <trini@konsulko.com>2015-04-29 06:46:33 -0400
commitace97d26176a3ebc9ec07738450de93eea35975c (patch)
tree7de5b3cdc2f269ae1426540ae9f74b420423f132
parent1692515e51a190b2ad1e2c54fdaa15fbb8387ba7 (diff)
parent5ca269a4df21a7e326eb3b3f7788177d064fe782 (diff)
downloadu-boot-ace97d26176a3ebc9ec07738450de93eea35975c.zip
u-boot-ace97d26176a3ebc9ec07738450de93eea35975c.tar.gz
u-boot-ace97d26176a3ebc9ec07738450de93eea35975c.tar.bz2
Merge branch 'zynq' of git://www.denx.de/git/u-boot-microblaze
-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
-rw-r--r--board/xilinx/zynq/.gitignore1
-rw-r--r--board/xilinx/zynq/Makefile4
-rw-r--r--board/xilinx/zynq/legacy.c2
-rw-r--r--board/xilinx/zynqmp/zynqmp.c9
-rw-r--r--configs/zynq_microzed_defconfig2
-rw-r--r--configs/zynq_picozed_defconfig6
-rw-r--r--configs/zynq_zc70x_defconfig2
-rw-r--r--configs/zynq_zc770_xm010_defconfig2
-rw-r--r--configs/zynq_zc770_xm012_defconfig2
-rw-r--r--configs/zynq_zc770_xm013_defconfig2
-rw-r--r--configs/zynq_zed_defconfig2
-rw-r--r--configs/zynq_zybo_defconfig2
-rw-r--r--drivers/gpio/Makefile1
-rw-r--r--drivers/gpio/zynq_gpio.c220
-rw-r--r--drivers/mmc/zynq_sdhci.c2
-rw-r--r--drivers/serial/serial_zynq.c8
-rw-r--r--include/configs/xilinx_zynqmp.h41
-rw-r--r--include/configs/zynq-common.h7
-rw-r--r--include/configs/zynq_picozed.h27
47 files changed, 914 insertions, 50 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 778a377e..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
diff --git a/board/xilinx/zynq/.gitignore b/board/xilinx/zynq/.gitignore
index 7c36bc9..c455361 100644
--- a/board/xilinx/zynq/.gitignore
+++ b/board/xilinx/zynq/.gitignore
@@ -1,2 +1 @@
-ps7_init.[ch]
ps7_init_gpl.[ch]
diff --git a/board/xilinx/zynq/Makefile b/board/xilinx/zynq/Makefile
index 3b1eb4f..054c3d8 100644
--- a/board/xilinx/zynq/Makefile
+++ b/board/xilinx/zynq/Makefile
@@ -9,9 +9,7 @@ obj-y := board.o
# Please copy ps7_init_gpl.c/h from hw project to this directory
obj-$(CONFIG_SPL_BUILD) += \
- $(if $(wildcard $(srctree)/$(src)/ps7_init_gpl.c), ps7_init_gpl.o, \
- $(if $(wildcard $(srctree)/$(src)/ps7_init.c), ps7_init.o legacy.o))
+ $(if $(wildcard $(srctree)/$(src)/ps7_init_gpl.c), ps7_init_gpl.o)
# Suppress "warning: function declaration isn't a prototype"
CFLAGS_REMOVE_ps7_init_gpl.o := -Wstrict-prototypes
-CFLAGS_REMOVE_ps7_init.o := -Wstrict-prototypes
diff --git a/board/xilinx/zynq/legacy.c b/board/xilinx/zynq/legacy.c
deleted file mode 100644
index 4ae913e..0000000
--- a/board/xilinx/zynq/legacy.c
+++ /dev/null
@@ -1,2 +0,0 @@
-
-#warning usage of ps7_init files is deprecated please use ps7_init_gpl
diff --git a/board/xilinx/zynqmp/zynqmp.c b/board/xilinx/zynqmp/zynqmp.c
index 1325bca..f5ff64d 100644
--- a/board/xilinx/zynqmp/zynqmp.c
+++ b/board/xilinx/zynqmp/zynqmp.c
@@ -56,14 +56,18 @@ int board_mmc_init(bd_t *bd)
{
int ret = 0;
+ u32 ver = zynqmp_get_silicon_version();
+
+ if (ver != ZYNQMP_CSU_VERSION_VELOCE) {
#if defined(CONFIG_ZYNQ_SDHCI)
# if defined(CONFIG_ZYNQ_SDHCI0)
- ret = zynq_sdhci_init(ZYNQ_SDHCI_BASEADDR0);
+ ret = zynq_sdhci_init(ZYNQ_SDHCI_BASEADDR0);
# endif
# if defined(CONFIG_ZYNQ_SDHCI1)
- ret |= zynq_sdhci_init(ZYNQ_SDHCI_BASEADDR1);
+ ret |= zynq_sdhci_init(ZYNQ_SDHCI_BASEADDR1);
# endif
#endif
+ }
return ret;
}
@@ -79,6 +83,7 @@ int board_late_init(void)
switch (bootmode) {
case SD_MODE:
+ case EMMC_MODE:
setenv("modeboot", "sdboot");
break;
default:
diff --git a/configs/zynq_microzed_defconfig b/configs/zynq_microzed_defconfig
index 95cfe89..40d675f 100644
--- a/configs/zynq_microzed_defconfig
+++ b/configs/zynq_microzed_defconfig
@@ -1,6 +1,6 @@
CONFIG_SPL=y
CONFIG_ARM=y
-CONFIG_ZYNQ=y
+CONFIG_ARCH_ZYNQ=y
CONFIG_TARGET_ZYNQ_MICROZED=y
CONFIG_OF_CONTROL=y
# CONFIG_SYS_MALLOC_F is not set
diff --git a/configs/zynq_picozed_defconfig b/configs/zynq_picozed_defconfig
new file mode 100644
index 0000000..61852cb
--- /dev/null
+++ b/configs/zynq_picozed_defconfig
@@ -0,0 +1,6 @@
+CONFIG_SPL=y
+CONFIG_ARM=y
+CONFIG_ARCH_ZYNQ=y
+CONFIG_TARGET_ZYNQ_PICOZED=y
+CONFIG_OF_CONTROL=n
+CONFIG_DEFAULT_DEVICE_TREE="zynq-picozed"
diff --git a/configs/zynq_zc70x_defconfig b/configs/zynq_zc70x_defconfig
index 81fb4af..7c3cb2d 100644
--- a/configs/zynq_zc70x_defconfig
+++ b/configs/zynq_zc70x_defconfig
@@ -1,6 +1,6 @@
CONFIG_SPL=y
CONFIG_ARM=y
-CONFIG_ZYNQ=y
+CONFIG_ARCH_ZYNQ=y
CONFIG_TARGET_ZYNQ_ZC70X=y
CONFIG_OF_CONTROL=y
CONFIG_DEFAULT_DEVICE_TREE="zynq-zc702"
diff --git a/configs/zynq_zc770_xm010_defconfig b/configs/zynq_zc770_xm010_defconfig
index fc39cca..36b95fa 100644
--- a/configs/zynq_zc770_xm010_defconfig
+++ b/configs/zynq_zc770_xm010_defconfig
@@ -1,7 +1,7 @@
CONFIG_SPL=y
CONFIG_SYS_EXTRA_OPTIONS="ZC770_XM010"
CONFIG_ARM=y
-CONFIG_ZYNQ=y
+CONFIG_ARCH_ZYNQ=y
CONFIG_TARGET_ZYNQ_ZC770=y
CONFIG_OF_CONTROL=y
CONFIG_DEFAULT_DEVICE_TREE="zynq-zc770-xm010"
diff --git a/configs/zynq_zc770_xm012_defconfig b/configs/zynq_zc770_xm012_defconfig
index 21e52fb..6c5eecc 100644
--- a/configs/zynq_zc770_xm012_defconfig
+++ b/configs/zynq_zc770_xm012_defconfig
@@ -1,7 +1,7 @@
CONFIG_SPL=y
CONFIG_SYS_EXTRA_OPTIONS="ZC770_XM012"
CONFIG_ARM=y
-CONFIG_ZYNQ=y
+CONFIG_ARCH_ZYNQ=y
CONFIG_TARGET_ZYNQ_ZC770=y
CONFIG_OF_CONTROL=y
CONFIG_DEFAULT_DEVICE_TREE="zynq-zc770-xm012"
diff --git a/configs/zynq_zc770_xm013_defconfig b/configs/zynq_zc770_xm013_defconfig
index 2c38012..eabc106 100644
--- a/configs/zynq_zc770_xm013_defconfig
+++ b/configs/zynq_zc770_xm013_defconfig
@@ -1,7 +1,7 @@
CONFIG_SPL=y
CONFIG_SYS_EXTRA_OPTIONS="ZC770_XM013"
CONFIG_ARM=y
-CONFIG_ZYNQ=y
+CONFIG_ARCH_ZYNQ=y
CONFIG_TARGET_ZYNQ_ZC770=y
CONFIG_OF_CONTROL=y
CONFIG_DEFAULT_DEVICE_TREE="zynq-zc770-xm013"
diff --git a/configs/zynq_zed_defconfig b/configs/zynq_zed_defconfig
index d4dc5bb..b2b4b99 100644
--- a/configs/zynq_zed_defconfig
+++ b/configs/zynq_zed_defconfig
@@ -1,6 +1,6 @@
CONFIG_SPL=y
CONFIG_ARM=y
-CONFIG_ZYNQ=y
+CONFIG_ARCH_ZYNQ=y
CONFIG_TARGET_ZYNQ_ZED=y
CONFIG_OF_CONTROL=y
CONFIG_DEFAULT_DEVICE_TREE="zynq-zed"
diff --git a/configs/zynq_zybo_defconfig b/configs/zynq_zybo_defconfig
index 7d06073..da55320 100644
--- a/configs/zynq_zybo_defconfig
+++ b/configs/zynq_zybo_defconfig
@@ -1,6 +1,6 @@
CONFIG_SPL=y
CONFIG_ARM=y
-CONFIG_ZYNQ=y
+CONFIG_ARCH_ZYNQ=y
CONFIG_TARGET_ZYNQ_ZYBO=y
CONFIG_OF_CONTROL=y
CONFIG_DEFAULT_DEVICE_TREE="zynq-zybo"
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 8ca8b05..fb40e09 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -43,3 +43,4 @@ oby-$(CONFIG_SX151X) += sx151x.o
obj-$(CONFIG_SUNXI_GPIO) += sunxi_gpio.o
obj-$(CONFIG_LPC32XX_GPIO) += lpc32xx_gpio.o
obj-$(CONFIG_STM32_GPIO) += stm32_gpio.o
+obj-$(CONFIG_ZYNQ_GPIO) += zynq_gpio.o
diff --git a/drivers/gpio/zynq_gpio.c b/drivers/gpio/zynq_gpio.c
new file mode 100644
index 0000000..83a2c46
--- /dev/null
+++ b/drivers/gpio/zynq_gpio.c
@@ -0,0 +1,220 @@
+/*
+ * Xilinx Zynq GPIO device driver
+ *
+ * Copyright (C) 2015 DAVE Embedded Systems <devel@dave.eu>
+ *
+ * Most of code taken from linux kernel driver (linux/drivers/gpio/gpio-zynq.c)
+ * Copyright (C) 2009 - 2014 Xilinx, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/gpio.h>
+#include <asm/io.h>
+#include <asm/errno.h>
+
+/**
+ * zynq_gpio_get_bank_pin - Get the bank number and pin number within that bank
+ * for a given pin in the GPIO device
+ * @pin_num: gpio pin number within the device
+ * @bank_num: an output parameter used to return the bank number of the gpio
+ * pin
+ * @bank_pin_num: an output parameter used to return pin number within a bank
+ * for the given gpio pin
+ *
+ * Returns the bank number and pin offset within the bank.
+ */
+static inline void zynq_gpio_get_bank_pin(unsigned int pin_num,
+ unsigned int *bank_num,
+ unsigned int *bank_pin_num)
+{
+ switch (pin_num) {
+ case ZYNQ_GPIO_BANK0_PIN_MIN ... ZYNQ_GPIO_BANK0_PIN_MAX:
+ *bank_num = 0;
+ *bank_pin_num = pin_num;
+ break;
+ case ZYNQ_GPIO_BANK1_PIN_MIN ... ZYNQ_GPIO_BANK1_PIN_MAX:
+ *bank_num = 1;
+ *bank_pin_num = pin_num - ZYNQ_GPIO_BANK1_PIN_MIN;
+ break;
+ case ZYNQ_GPIO_BANK2_PIN_MIN ... ZYNQ_GPIO_BANK2_PIN_MAX:
+ *bank_num = 2;
+ *bank_pin_num = pin_num - ZYNQ_GPIO_BANK2_PIN_MIN;
+ break;
+ case ZYNQ_GPIO_BANK3_PIN_MIN ... ZYNQ_GPIO_BANK3_PIN_MAX:
+ *bank_num = 3;
+ *bank_pin_num = pin_num - ZYNQ_GPIO_BANK3_PIN_MIN;
+ break;
+ default:
+ printf("invalid GPIO pin number: %u\n", pin_num);
+ *bank_num = 0;
+ *bank_pin_num = 0;
+ break;
+ }
+}
+
+int gpio_is_valid(unsigned gpio)
+{
+ return (gpio >= 0) && (gpio < ZYNQ_GPIO_NR_GPIOS);
+}
+
+static int check_gpio(unsigned gpio)
+{
+ if (!gpio_is_valid(gpio)) {
+ printf("ERROR : check_gpio: invalid GPIO %d\n", gpio);
+ return -1;
+ }
+ return 0;
+}
+
+/**
+ * gpio_get_value - Get the state of the specified pin of GPIO device
+ * @gpio: gpio pin number within the device
+ *
+ * This function reads the state of the specified pin of the GPIO device.
+ *
+ * Return: 0 if the pin is low, 1 if pin is high.
+ */
+int gpio_get_value(unsigned gpio)
+{
+ u32 data;
+ unsigned int bank_num, bank_pin_num;
+
+ if (check_gpio(gpio) < 0)
+ return -1;
+
+ zynq_gpio_get_bank_pin(gpio, &bank_num, &bank_pin_num);
+
+ data = readl(ZYNQ_GPIO_BASE_ADDRESS +
+ ZYNQ_GPIO_DATA_RO_OFFSET(bank_num));
+
+ return (data >> bank_pin_num) & 1;
+}
+
+/**
+ * gpio_set_value - Modify the value of the pin with specified value
+ * @gpio: gpio pin number within the device
+ * @value: value used to modify the value of the specified pin
+ *
+ * This function calculates the register offset (i.e to lower 16 bits or
+ * upper 16 bits) based on the given pin number and sets the value of a
+ * gpio pin to the specified value. The value is either 0 or non-zero.
+ */
+int gpio_set_value(unsigned gpio, int value)
+{
+ unsigned int reg_offset, bank_num, bank_pin_num;
+
+ if (check_gpio(gpio) < 0)
+ return -1;
+
+ zynq_gpio_get_bank_pin(gpio, &bank_num, &bank_pin_num);
+
+ if (bank_pin_num >= ZYNQ_GPIO_MID_PIN_NUM) {
+ /* only 16 data bits in bit maskable reg */
+ bank_pin_num -= ZYNQ_GPIO_MID_PIN_NUM;
+ reg_offset = ZYNQ_GPIO_DATA_MSW_OFFSET(bank_num);
+ } else {
+ reg_offset = ZYNQ_GPIO_DATA_LSW_OFFSET(bank_num);
+ }
+
+ /*
+ * get the 32 bit value to be written to the mask/data register where
+ * the upper 16 bits is the mask and lower 16 bits is the data
+ */
+ value = !!value;
+ value = ~(1 << (bank_pin_num + ZYNQ_GPIO_MID_PIN_NUM)) &
+ ((value << bank_pin_num) | ZYNQ_GPIO_UPPER_MASK);
+
+ writel(value, ZYNQ_GPIO_BASE_ADDRESS + reg_offset);
+
+ return 0;
+}
+
+/**
+ * gpio_direction_input - Set the direction of the specified GPIO pin as input
+ * @gpio: gpio pin number within the device
+ *
+ * This function uses the read-modify-write sequence to set the direction of
+ * the gpio pin as input.
+ *
+ * Return: -1 if invalid gpio specified, 0 if successul
+ */
+int gpio_direction_input(unsigned gpio)
+{
+ u32 reg;
+ unsigned int bank_num, bank_pin_num;
+
+ if (check_gpio(gpio) < 0)
+ return -1;
+
+ zynq_gpio_get_bank_pin(gpio, &bank_num, &bank_pin_num);
+
+ /* bank 0 pins 7 and 8 are special and cannot be used as inputs */
+ if (bank_num == 0 && (bank_pin_num == 7 || bank_pin_num == 8))
+ return -1;
+
+ /* clear the bit in direction mode reg to set the pin as input */
+ reg = readl(ZYNQ_GPIO_BASE_ADDRESS + ZYNQ_GPIO_DIRM_OFFSET(bank_num));
+ reg &= ~BIT(bank_pin_num);
+ writel(reg, ZYNQ_GPIO_BASE_ADDRESS + ZYNQ_GPIO_DIRM_OFFSET(bank_num));
+
+ return 0;
+}
+
+/**
+ * gpio_direction_output - Set the direction of the specified GPIO pin as output
+ * @gpio: gpio pin number within the device
+ * @value: value to be written to specified pin
+ *
+ * This function sets the direction of specified GPIO pin as output, configures
+ * the Output Enable register for the pin and uses zynq_gpio_set to set
+ * the value of the pin to the value specified.
+ *
+ * Return: 0 always
+ */
+int gpio_direction_output(unsigned gpio, int value)
+{
+ u32 reg;
+ unsigned int bank_num, bank_pin_num;
+
+ if (check_gpio(gpio) < 0)
+ return -1;
+
+ zynq_gpio_get_bank_pin(gpio, &bank_num, &bank_pin_num);
+
+ /* set the GPIO pin as output */
+ reg = readl(ZYNQ_GPIO_BASE_ADDRESS + ZYNQ_GPIO_DIRM_OFFSET(bank_num));
+ reg |= BIT(bank_pin_num);
+ writel(reg, ZYNQ_GPIO_BASE_ADDRESS + ZYNQ_GPIO_DIRM_OFFSET(bank_num));
+
+ /* configure the output enable reg for the pin */
+ reg = readl(ZYNQ_GPIO_BASE_ADDRESS + ZYNQ_GPIO_OUTEN_OFFSET(bank_num));
+ reg |= BIT(bank_pin_num);
+ writel(reg, ZYNQ_GPIO_BASE_ADDRESS + ZYNQ_GPIO_OUTEN_OFFSET(bank_num));
+
+ /* set the state of the pin */
+ gpio_set_value(gpio, value);
+ return 0;
+}
+
+/**
+ * Request a gpio before using it.
+ *
+ * NOTE: Argument 'label' is unused.
+ */
+int gpio_request(unsigned gpio, const char *label)
+{
+ if (check_gpio(gpio) < 0)
+ return -1;
+
+ return 0;
+}
+
+/**
+ * Reset and free the gpio after using it.
+ */
+int gpio_free(unsigned gpio)
+{
+ return 0;
+}
diff --git a/drivers/mmc/zynq_sdhci.c b/drivers/mmc/zynq_sdhci.c
index 7887f11..d4f3882 100644
--- a/drivers/mmc/zynq_sdhci.c
+++ b/drivers/mmc/zynq_sdhci.c
@@ -25,7 +25,7 @@ int zynq_sdhci_init(phys_addr_t regbase)
host->name = "zynq_sdhci";
host->ioaddr = (void *)regbase;
- host->quirks = SDHCI_QUIRK_NO_CD | SDHCI_QUIRK_WAIT_SEND_CMD |
+ host->quirks = SDHCI_QUIRK_WAIT_SEND_CMD |
SDHCI_QUIRK_BROKEN_R1B;
host->version = sdhci_readw(host, SDHCI_HOST_VERSION);
diff --git a/drivers/serial/serial_zynq.c b/drivers/serial/serial_zynq.c
index 3e2b8dc..9278763 100644
--- a/drivers/serial/serial_zynq.c
+++ b/drivers/serial/serial_zynq.c
@@ -48,10 +48,16 @@ static void uart_zynq_serial_setbrg(const int port)
/* Calculation results. */
unsigned int calc_bauderror, bdiv, bgen;
unsigned long calc_baud = 0;
- unsigned long baud = gd->baudrate;
+ unsigned long baud;
unsigned long clock = get_uart_clk(port);
struct uart_zynq *regs = uart_zynq_ports[port];
+ /* Covering case where input clock is so slow */
+ if (clock < 1000000 && gd->baudrate > 4800)
+ gd->baudrate = 4800;
+
+ baud = gd->baudrate;
+
/* master clock
* Baud rate = ------------------
* bgen * (bdiv + 1)
diff --git a/include/configs/xilinx_zynqmp.h b/include/configs/xilinx_zynqmp.h
index 511ecca..880d29c 100644
--- a/include/configs/xilinx_zynqmp.h
+++ b/include/configs/xilinx_zynqmp.h
@@ -36,7 +36,7 @@
#define CPU_RELEASE_ADDR 0xFFFFFF0
/* Cache Definitions */
-#define CONFIG_SYS_DCACHE_OFF
+#define CONFIG_SYS_CACHELINE_SIZE 64
#define CONFIG_IDENT_STRING " Xilinx ZynqMP"
@@ -61,13 +61,25 @@
#define CONFIG_SYS_BAUDRATE_TABLE \
{ 4800, 9600, 19200, 38400, 57600, 115200 }
+#define CONFIG_ZYNQ_SDHCI0
+
/* Command line configuration */
#define CONFIG_CMD_ENV
#define CONFIG_CMD_EXT2
#define CONFIG_CMD_EXT4
#define CONFIG_CMD_FAT
+#define CONFIG_CMD_FS_GENERIC
#define CONFIG_CMD_MEMORY
#define CONFIG_DOS_PARTITION
+#define CONFIG_CMD_ELF
+#define CONFIG_MP
+
+/* SPI */
+#ifdef CONFIG_ZYNQ_SPI
+# define CONFIG_SPI_FLASH
+# define CONFIG_SPI_FLASH_SST
+# define CONFIG_CMD_SF
+#endif
#if defined(CONFIG_ZYNQ_SDHCI0) || defined(CONFIG_ZYNQ_SDHCI1)
# define CONFIG_MMC
@@ -90,8 +102,8 @@
"kernel_addr=0x80000\0" \
"fdt_addr=0x7000000\0" \
"fdt_high=0x10000000\0" \
- "sdboot=mmcinfo && fatload mmc 0:0 $fdt_addr system.dtb && " \
- "fatload mmc 0:0 $kernel_addr Image && booti $kernel_addr - $fdt_addr\0"
+ "sdboot=mmcinfo && load mmc 0:0 $fdt_addr system.dtb && " \
+ "load mmc 0:0 $kernel_addr Image && booti $kernel_addr - $fdt_addr\0"
#define CONFIG_BOOTARGS "setenv bootargs console=ttyPS0,${baudrate} " \
"earlycon=cdns,mmio,0xff000000,${baudrate}n8"
@@ -117,6 +129,29 @@
#define CONFIG_CMDLINE_EDITING
#define CONFIG_SYS_MAXARGS 64
+#define CONFIG_ZYNQ_I2C0
+#define CONFIG_SYS_I2C_ZYNQ
+
+/* I2C */
+#if defined(CONFIG_SYS_I2C_ZYNQ)
+# define CONFIG_CMD_I2C
+# define CONFIG_SYS_I2C
+# define CONFIG_SYS_I2C_ZYNQ_SPEED 100000
+# define CONFIG_SYS_I2C_ZYNQ_SLAVE 0
+#endif
+
+#define CONFIG_ZYNQMP_EEPROM
+
+/* EEPROM */
+#ifdef CONFIG_ZYNQMP_EEPROM
+# define CONFIG_CMD_EEPROM
+# define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 2
+# define CONFIG_SYS_I2C_EEPROM_ADDR 0x54
+# define CONFIG_SYS_EEPROM_PAGE_WRITE_BITS 4
+# define CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS 5
+# define CONFIG_SYS_EEPROM_SIZE (64 * 1024)
+#endif
+
#define CONFIG_FIT
#define CONFIG_FIT_VERBOSE /* enable fit_format_{error,warning}() */
diff --git a/include/configs/zynq-common.h b/include/configs/zynq-common.h
index 485babd..b83e037 100644
--- a/include/configs/zynq-common.h
+++ b/include/configs/zynq-common.h
@@ -39,6 +39,9 @@
# define CONFIG_ZYNQ_SERIAL
#endif
+#define CONFIG_ZYNQ_GPIO
+#define CONFIG_CMD_GPIO
+
/* Ethernet driver */
#if defined(CONFIG_ZYNQ_GEM0) || defined(CONFIG_ZYNQ_GEM1)
# define CONFIG_NET_MULTI
@@ -291,7 +294,7 @@
# define CONFIG_SYS_MMC_MAX_DEVICE 1
#endif
-#define CONFIG_SYS_LDSCRIPT "arch/arm/cpu/armv7/zynq/u-boot.lds"
+#define CONFIG_SYS_LDSCRIPT "arch/arm/mach-zynq/u-boot.lds"
/* Commands */
#include <config_cmd_default.h>
@@ -309,7 +312,7 @@
#define CONFIG_SPL_SERIAL_SUPPORT
#define CONFIG_SPL_BOARD_INIT
-#define CONFIG_SPL_LDSCRIPT "arch/arm/cpu/armv7/zynq/u-boot-spl.lds"
+#define CONFIG_SPL_LDSCRIPT "arch/arm/mach-zynq/u-boot-spl.lds"
/* MMC support */
#ifdef CONFIG_ZYNQ_SDHCI0
diff --git a/include/configs/zynq_picozed.h b/include/configs/zynq_picozed.h
new file mode 100644
index 0000000..d116e05
--- /dev/null
+++ b/include/configs/zynq_picozed.h
@@ -0,0 +1,27 @@
+/*
+ * (C) Copyright 2015 Xilinx, Inc.
+ *
+ * Configuration for PicoZed
+ * See zynq-common.h for Zynq common configs
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __CONFIG_ZYNQ_PICOZED_H
+#define __CONFIG_ZYNQ_PICOZED_H
+
+#define CONFIG_SYS_SDRAM_SIZE (1024 * 1024 * 1024)
+
+#define CONFIG_ZYNQ_SERIAL_UART1
+#define CONFIG_ZYNQ_GEM0
+#define CONFIG_ZYNQ_GEM_PHY_ADDR0 0
+
+#define CONFIG_SYS_NO_FLASH
+
+#define CONFIG_ZYNQ_SDHCI1
+#define CONFIG_ZYNQ_USB
+#define CONFIG_ZYNQ_BOOT_FREEBSD
+
+#include <configs/zynq-common.h>
+
+#endif /* __CONFIG_ZYNQ_PICOZED_H */