diff --git a/src/soc/xilinx/Kconfig b/src/soc/xilinx/Kconfig new file mode 100644 index 0000000000..95100a0203 --- /dev/null +++ b/src/soc/xilinx/Kconfig @@ -0,0 +1,4 @@ +## SPDX-License-Identifier: GPL-2.0-only + +# Load all chipsets +source "src/soc/xilinx/*/Kconfig" diff --git a/src/soc/xilinx/zynq7000/Kconfig b/src/soc/xilinx/zynq7000/Kconfig new file mode 100644 index 0000000000..3254435e15 --- /dev/null +++ b/src/soc/xilinx/zynq7000/Kconfig @@ -0,0 +1,17 @@ +## SPDX-License-Identifier: GPL-2.0-only +# +config SOC_XILINX_ZYNQ7000 + bool + default n + select ARCH_BOOTBLOCK_ARMV7 + select ARCH_VERSTAGE_ARMV7 + select ARCH_ROMSTAGE_ARMV7 + select ARCH_RAMSTAGE_ARMV7 + +if SOC_XILINX_ZYNQ7000 + +config MEMLAYOUT_LD_FILE + string + default "src/soc/xilinx/zynq7000/memlayout.ld" + +endif diff --git a/src/soc/xilinx/zynq7000/Makefile.mk b/src/soc/xilinx/zynq7000/Makefile.mk new file mode 100644 index 0000000000..b6b4e1c2ee --- /dev/null +++ b/src/soc/xilinx/zynq7000/Makefile.mk @@ -0,0 +1,15 @@ +# SPDX-License-Identifier: GPL-2.0-only +ifeq ($(CONFIG_SOC_XILINX_ZYNQ7000),y) + +bootblock-y += timer.c +romstage-y += timer.c +ramstage-y += timer.c + +romstage-y += cbmem.c +ramstage-y += soc.c + +bootblock-y += reset.c +romstage-y += reset.c +ramstage-y += reset.c + +endif diff --git a/src/soc/xilinx/zynq7000/cbmem.c b/src/soc/xilinx/zynq7000/cbmem.c new file mode 100644 index 0000000000..eb0f0f4f46 --- /dev/null +++ b/src/soc/xilinx/zynq7000/cbmem.c @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include + +uintptr_t cbmem_top_chipset(void) +{ + return CONFIG_DRAM_SIZE_MB * MiB; +} diff --git a/src/soc/xilinx/zynq7000/memlayout.ld b/src/soc/xilinx/zynq7000/memlayout.ld new file mode 100644 index 0000000000..1ebd0d8ba9 --- /dev/null +++ b/src/soc/xilinx/zynq7000/memlayout.ld @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include + +#include + +SECTIONS +{ + SRAM_START(0x00000000) + BOOTBLOCK(0x00000000, 20K) + FMAP_CACHE(0x00000000+20K, 2K) + CBFS_MCACHE(0x00000000+20K+2K, 8K) + TTB(0x00008000, 16K) + ROMSTAGE(0x00008000+16K, 40K) + + PRERAM_CBFS_CACHE(0x00008000+16K+40K, 20K) + + STACK(0x0001b000, 4K) + SRAM_END(0x30000) + + DRAM_START(0x100000) + RAMSTAGE(0x100000, 2M) + POSTRAM_CBFS_CACHE(0x300000, 32M) +} diff --git a/src/soc/xilinx/zynq7000/reset.c b/src/soc/xilinx/zynq7000/reset.c new file mode 100644 index 0000000000..339acb6d87 --- /dev/null +++ b/src/soc/xilinx/zynq7000/reset.c @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include + +#define SLCR_UNLOCK ((void *)0xF8000008u) +#define SLCR_UNLOCK_KEY 0xDF0D +#define PSS_RST_CTRL ((void *)0xF8000200u) +void do_board_reset(void) +{ + write16(SLCR_UNLOCK, SLCR_UNLOCK_KEY); + write32(PSS_RST_CTRL, 1); +} diff --git a/src/soc/xilinx/zynq7000/soc.c b/src/soc/xilinx/zynq7000/soc.c new file mode 100644 index 0000000000..987e437f3c --- /dev/null +++ b/src/soc/xilinx/zynq7000/soc.c @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include + +static void soc_enable(struct device *dev) +{ + ram_range(dev, 0, 0, CONFIG_DRAM_SIZE_MB * (uint64_t)MiB); +} + +struct chip_operations soc_xilinx_zynq7000_ops = { + .name = "Xilinx Zynq 7000", + .enable_dev = soc_enable, +}; diff --git a/src/soc/xilinx/zynq7000/timer.c b/src/soc/xilinx/zynq7000/timer.c new file mode 100644 index 0000000000..0448aa6b72 --- /dev/null +++ b/src/soc/xilinx/zynq7000/timer.c @@ -0,0 +1,38 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include + +#define G_TIMER_COUNTER_0 ((void *)0xF8F00200u) +#define G_TIMER_COUNTER_1 ((void *)0xF8F00204u) +#define G_TIMER_CTRL ((void *)0xF8F00208u) + +#define CLK_PER_USEC 108 + +static inline uint64_t timer_raw_value(void) +{ + uint32_t upper, lower; + do { + upper = read32(G_TIMER_COUNTER_1); + lower = read32(G_TIMER_COUNTER_0); + } while (upper != read32(G_TIMER_COUNTER_1)); + + return (((uint64_t)upper) << 32) | lower; +} + +void init_timer(void) +{ + /* Disable timer */ + write32(G_TIMER_CTRL, read32(G_TIMER_CTRL) & ~0x1); + write32(G_TIMER_COUNTER_0, 0); + write32(G_TIMER_COUNTER_1, 0); + /* Enable timer */ + write32(G_TIMER_CTRL, read32(G_TIMER_CTRL) | 0x1); +} + +void timer_monotonic_get(struct mono_time *mt) +{ + mono_time_set_usecs(mt, timer_raw_value() / CLK_PER_USEC); +}