diff options
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/Kconfig | 11 | ||||
-rw-r--r-- | arch/arm/Makefile | 1 | ||||
-rw-r--r-- | arch/arm/cpu/armv8/zynqmp/cpu.c | 84 | ||||
-rw-r--r-- | arch/arm/dts/Makefile | 3 | ||||
-rw-r--r-- | arch/arm/dts/zynqmp-clk.dtsi | 2 | ||||
-rw-r--r-- | arch/arm/dts/zynqmp-r5.dts | 73 | ||||
-rw-r--r-- | arch/arm/dts/zynqmp-zc1275-revB.dts | 79 | ||||
-rw-r--r-- | arch/arm/dts/zynqmp-zcu100-revC.dts | 1 | ||||
-rw-r--r-- | arch/arm/include/asm/arch-zynqmp/sys_proto.h | 2 | ||||
-rw-r--r-- | arch/arm/mach-zynq/cpu.c | 85 | ||||
-rw-r--r-- | arch/arm/mach-zynq/spl.c | 11 | ||||
-rw-r--r-- | arch/arm/mach-zynqmp-r5/Kconfig | 27 | ||||
-rw-r--r-- | arch/arm/mach-zynqmp-r5/Makefile | 3 | ||||
-rw-r--r-- | arch/arm/mach-zynqmp-r5/cpu.c | 37 |
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) + ; +} |