From f11d4ab0b37ede1eed45540ac4e2384b3d19ce98 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Thu, 20 Dec 2018 09:41:12 +0100 Subject: arm64: zynqmp: Do not protect zynqmp_pmufw_version() There is hard dependency for CLK_ZYNQMP to have zynqmp_pmufw_version() but also FPGA code is calling this function which is possible to use without actual CLK_ZYNQMP firmware driver to be enabled. This patch enables the case where only fixed-clock CLK setup is used. Signed-off-by: Michal Simek --- arch/arm/cpu/armv8/zynqmp/cpu.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'arch') diff --git a/arch/arm/cpu/armv8/zynqmp/cpu.c b/arch/arm/cpu/armv8/zynqmp/cpu.c index 4ee8e3f627e..5ef1a52862c 100644 --- a/arch/arm/cpu/armv8/zynqmp/cpu.c +++ b/arch/arm/cpu/armv8/zynqmp/cpu.c @@ -179,8 +179,7 @@ int __maybe_unused invoke_smc(u32 pm_api_id, u32 arg0, u32 arg1, u32 arg2, return regs.regs[0]; } -#if defined(CONFIG_CLK_ZYNQMP) -unsigned int zynqmp_pmufw_version(void) +unsigned int __maybe_unused zynqmp_pmufw_version(void) { int ret; u32 ret_payload[PAYLOAD_ARG_CNT]; @@ -202,7 +201,6 @@ unsigned int zynqmp_pmufw_version(void) return pm_api_version; } -#endif static int zynqmp_mmio_rawwrite(const u32 address, const u32 mask, -- cgit v1.2.3 From e7c9de6617e6a51e6502920c5b3e5a41a0bf6973 Mon Sep 17 00:00:00 2001 From: Siva Durga Prasad Paladugu Date: Thu, 3 Jan 2019 15:44:24 +0530 Subject: arm64: zynqmp: Fix mmc node names to be in sync with kernel This patches renames sd nodes in dts to be in line with kernel. This patch also modifies the references for the same in code. It checks mmc first to have no time penalty for new DT node names based on left-to-right expression evaluation. Signed-off-by: Siva Durga Prasad Paladugu Signed-off-by: Michal Simek --- arch/arm/dts/zynqmp.dtsi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/dts/zynqmp.dtsi b/arch/arm/dts/zynqmp.dtsi index 80ac9a6ac7b..831d6e1ecc4 100644 --- a/arch/arm/dts/zynqmp.dtsi +++ b/arch/arm/dts/zynqmp.dtsi @@ -700,7 +700,7 @@ /* dma-coherent; */ }; - sdhci0: sdhci@ff160000 { + sdhci0: mmc@ff160000 { u-boot,dm-pre-reloc; compatible = "xlnx,zynqmp-8.9a", "arasan,sdhci-8.9a"; status = "disabled"; @@ -715,7 +715,7 @@ nvmem-cell-names = "soc_revision"; }; - sdhci1: sdhci@ff170000 { + sdhci1: mmc@ff170000 { u-boot,dm-pre-reloc; compatible = "xlnx,zynqmp-8.9a", "arasan,sdhci-8.9a"; status = "disabled"; -- cgit v1.2.3 From fa7971574cfa6b4dc5ca72501b2f2b01159884f2 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Tue, 15 Jan 2019 08:52:46 +0100 Subject: arm64: versal: Setup DM_ETH/MMC if NET/MMC is enabled Setup proper ETH/MMC dependency for the whole platform. Signed-off-by: Michal Simek --- arch/arm/Kconfig | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index d6b1629a00a..d69958b5a25 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -886,6 +886,8 @@ config ARCH_VERSAL select ARM64 select CLK select DM + select DM_ETH if NET + select DM_MMC if MMC select DM_SERIAL select OF_CONTROL -- cgit v1.2.3 From fb69310850b69d7d13085e243fea52079f406340 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Tue, 15 Jan 2019 08:52:51 +0100 Subject: arm64: zynqmp: Setup DM_ETH/MMC if NET/MMC is enabled Setup proper ETH/MMC dependency for the whole platform. Signed-off-by: Michal Simek --- arch/arm/Kconfig | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index d69958b5a25..271d883d99f 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -941,6 +941,8 @@ config ARCH_ZYNQMP select ARM64 select CLK select DM + select DM_ETH if NET + select DM_MMC if MMC select DM_SERIAL select DM_USB if USB select OF_CONTROL -- cgit v1.2.3 From 6f96fb508df5c23c34fb801f75e7b7166833e435 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Tue, 15 Jan 2019 09:06:46 +0100 Subject: ARM: zynqmp_r5: Setup DM_ETH/MMC if NET/MMC is enabled Setup proper ETH/MMC dependency for the whole platform. Signed-off-by: Michal Simek --- arch/arm/Kconfig | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 271d883d99f..8346b172ac6 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -931,6 +931,8 @@ config ARCH_ZYNQMP_R5 select CLK select CPU_V7R select DM + select DM_ETH if NET + select DM_MMC if MMC select DM_SERIAL select OF_CONTROL imply CMD_DM -- cgit v1.2.3 From 088f83ee3a194af798adb56e27c20b37c49b034a Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Tue, 15 Jan 2019 10:50:39 +0100 Subject: arm64: zynqmp: Setup proper SPI dependency Select DM_SPI/DM_SPI_FLASH for the whole SoC. Signed-off-by: Michal Simek --- arch/arm/Kconfig | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 8346b172ac6..a65e0c52116 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -946,6 +946,8 @@ config ARCH_ZYNQMP select DM_ETH if NET select DM_MMC if MMC select DM_SERIAL + select DM_SPI if SPI + select DM_SPI_FLASH if DM_SPI select DM_USB if USB select OF_CONTROL select SPL_BOARD_INIT if SPL -- cgit v1.2.3 From 274ccb5b1175e1d87a5b2eaf2f82826b079382b5 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Thu, 17 Jan 2019 08:22:43 +0100 Subject: arm64: zynqmp: Move SoC sources to mach-zynqmp Similar changes was done for Zynq in past and this patch just follow this pattern to separate cpu code from SoC code. Move arch/arm/cpu/armv8/zynqmp/* -> arch/arm/mach-zynqmp/* And also fix references to these files. Based on "ARM: zynq: move SoC sources to mach-zynq" (sha1: 0107f2403669f764ab726d0d404e35bb9447bbcc) Signed-off-by: Michal Simek --- arch/arm/Kconfig | 4 +- arch/arm/Makefile | 1 + arch/arm/cpu/armv8/Makefile | 1 - arch/arm/cpu/armv8/zynqmp/Kconfig | 156 ------------ arch/arm/cpu/armv8/zynqmp/Makefile | 10 - arch/arm/cpu/armv8/zynqmp/clk.c | 45 ---- arch/arm/cpu/armv8/zynqmp/cpu.c | 260 -------------------- arch/arm/cpu/armv8/zynqmp/handoff.c | 86 ------- arch/arm/cpu/armv8/zynqmp/mp.c | 297 ----------------------- arch/arm/cpu/armv8/zynqmp/psu_spl_init.c | 79 ------ arch/arm/cpu/armv8/zynqmp/spl.c | 134 ---------- arch/arm/include/asm/arch-zynqmp/clk.h | 12 - arch/arm/include/asm/arch-zynqmp/gpio.h | 11 - arch/arm/include/asm/arch-zynqmp/hardware.h | 159 ------------ arch/arm/include/asm/arch-zynqmp/psu_init_gpl.h | 25 -- arch/arm/include/asm/arch-zynqmp/sys_proto.h | 75 ------ arch/arm/mach-k3/arm64-mmu.c | 2 +- arch/arm/mach-tegra/arm64-mmu.c | 2 +- arch/arm/mach-zynqmp/Kconfig | 156 ++++++++++++ arch/arm/mach-zynqmp/Makefile | 10 + arch/arm/mach-zynqmp/clk.c | 45 ++++ arch/arm/mach-zynqmp/cpu.c | 260 ++++++++++++++++++++ arch/arm/mach-zynqmp/handoff.c | 86 +++++++ arch/arm/mach-zynqmp/include/mach/clk.h | 12 + arch/arm/mach-zynqmp/include/mach/gpio.h | 11 + arch/arm/mach-zynqmp/include/mach/hardware.h | 159 ++++++++++++ arch/arm/mach-zynqmp/include/mach/psu_init_gpl.h | 25 ++ arch/arm/mach-zynqmp/include/mach/sys_proto.h | 75 ++++++ arch/arm/mach-zynqmp/mp.c | 297 +++++++++++++++++++++++ arch/arm/mach-zynqmp/psu_spl_init.c | 79 ++++++ arch/arm/mach-zynqmp/spl.c | 134 ++++++++++ 31 files changed, 1354 insertions(+), 1354 deletions(-) delete mode 100644 arch/arm/cpu/armv8/zynqmp/Kconfig delete mode 100644 arch/arm/cpu/armv8/zynqmp/Makefile delete mode 100644 arch/arm/cpu/armv8/zynqmp/clk.c delete mode 100644 arch/arm/cpu/armv8/zynqmp/cpu.c delete mode 100644 arch/arm/cpu/armv8/zynqmp/handoff.c delete mode 100644 arch/arm/cpu/armv8/zynqmp/mp.c delete mode 100644 arch/arm/cpu/armv8/zynqmp/psu_spl_init.c delete mode 100644 arch/arm/cpu/armv8/zynqmp/spl.c delete mode 100644 arch/arm/include/asm/arch-zynqmp/clk.h delete mode 100644 arch/arm/include/asm/arch-zynqmp/gpio.h delete mode 100644 arch/arm/include/asm/arch-zynqmp/hardware.h delete mode 100644 arch/arm/include/asm/arch-zynqmp/psu_init_gpl.h delete mode 100644 arch/arm/include/asm/arch-zynqmp/sys_proto.h create mode 100644 arch/arm/mach-zynqmp/Kconfig create mode 100644 arch/arm/mach-zynqmp/Makefile create mode 100644 arch/arm/mach-zynqmp/clk.c create mode 100644 arch/arm/mach-zynqmp/cpu.c create mode 100644 arch/arm/mach-zynqmp/handoff.c create mode 100644 arch/arm/mach-zynqmp/include/mach/clk.h create mode 100644 arch/arm/mach-zynqmp/include/mach/gpio.h create mode 100644 arch/arm/mach-zynqmp/include/mach/hardware.h create mode 100644 arch/arm/mach-zynqmp/include/mach/psu_init_gpl.h create mode 100644 arch/arm/mach-zynqmp/include/mach/sys_proto.h create mode 100644 arch/arm/mach-zynqmp/mp.c create mode 100644 arch/arm/mach-zynqmp/psu_spl_init.c create mode 100644 arch/arm/mach-zynqmp/spl.c (limited to 'arch') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index a65e0c52116..2298e6e7d75 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1503,14 +1503,14 @@ source "arch/arm/cpu/armv7/vf610/Kconfig" source "arch/arm/mach-zynq/Kconfig" +source "arch/arm/mach-zynqmp/Kconfig" + source "arch/arm/mach-versal/Kconfig" source "arch/arm/mach-zynqmp-r5/Kconfig" source "arch/arm/cpu/armv7/Kconfig" -source "arch/arm/cpu/armv8/zynqmp/Kconfig" - source "arch/arm/cpu/armv8/Kconfig" source "arch/arm/mach-imx/Kconfig" diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 87d9d4b9f74..817302523ae 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -81,6 +81,7 @@ machine-$(CONFIG_ARCH_STM32MP) += stm32mp machine-$(CONFIG_TEGRA) += tegra machine-$(CONFIG_ARCH_UNIPHIER) += uniphier machine-$(CONFIG_ARCH_ZYNQ) += zynq +machine-$(CONFIG_ARCH_ZYNQMP) += zynqmp machine-$(CONFIG_ARCH_VERSAL) += versal machine-$(CONFIG_ARCH_ZYNQMP_R5) += zynqmp-r5 diff --git a/arch/arm/cpu/armv8/Makefile b/arch/arm/cpu/armv8/Makefile index 52c8daa0496..4c4b13c9e75 100644 --- a/arch/arm/cpu/armv8/Makefile +++ b/arch/arm/cpu/armv8/Makefile @@ -29,7 +29,6 @@ obj-$(CONFIG_$(SPL_)ARMV8_SEC_FIRMWARE_SUPPORT) += sec_firmware.o sec_firmware_a obj-$(CONFIG_FSL_LAYERSCAPE) += fsl-layerscape/ obj-$(CONFIG_S32V234) += s32v234/ -obj-$(CONFIG_ARCH_ZYNQMP) += zynqmp/ obj-$(CONFIG_TARGET_HIKEY) += hisilicon/ obj-$(CONFIG_ARMV8_PSCI) += psci.o obj-$(CONFIG_ARCH_SUNXI) += lowlevel_init.o diff --git a/arch/arm/cpu/armv8/zynqmp/Kconfig b/arch/arm/cpu/armv8/zynqmp/Kconfig deleted file mode 100644 index 8a311e1c894..00000000000 --- a/arch/arm/cpu/armv8/zynqmp/Kconfig +++ /dev/null @@ -1,156 +0,0 @@ -if ARCH_ZYNQMP - -config SPL_FAT_SUPPORT - default y - -config SPL_LIBCOMMON_SUPPORT - default y - -config SPL_LIBDISK_SUPPORT - default y - -config SPL_LIBGENERIC_SUPPORT - default y - -config SPL_MMC_SUPPORT - default y if MMC_SDHCI_ZYNQ - -config SPL_SERIAL_SUPPORT - default y - -config SPL_SPI_FLASH_SUPPORT - default y if ZYNQ_QSPI - -config SPL_SPI_SUPPORT - default y if ZYNQ_QSPI - -config SYS_BOARD - default "zynqmp" - -config SYS_VENDOR - string "Vendor name" - default "xilinx" - -config SYS_SOC - default "zynqmp" - -config SYS_CONFIG_NAME - string "Board configuration name" - default "xilinx_zynqmp" - help - This option contains information about board configuration name. - Based on this option include/configs/.h header - will be used for board configuration. - -config SYS_MEM_RSVD_FOR_MMU - bool "Reserve memory for MMU Table" - help - If defined this option is used to setup different space for - MMU table than the one which will be allocated during - relocation. - -config BOOT_INIT_FILE - string "boot.bin init register filename" - depends on SPL - default "" - help - Add register writes to boot.bin format (max 256 pairs). - Expect a table of register-value pairs, e.g. "0x12345678 0x4321" - -config PMUFW_INIT_FILE - string "PMU firmware" - depends on SPL - default "" - help - Include external PMUFW (Platform Management Unit FirmWare) to - a Xilinx bootable image (boot.bin). - -config ZYNQMP_USB - bool "Configure ZynqMP USB" - -config ZYNQMP_NO_DDR - bool "Disable DDR MMU mapping" - help - This option configures MMU with no DDR to avoid speculative - access to DDR memory where DDR is not present. - -config SYS_MALLOC_F_LEN - default 0x600 - -config DEFINE_TCM_OCM_MMAP - bool "Define TCM and OCM memory in MMU Table" - default y if MP - help - This option if enabled defines the TCM and OCM memory and its - memory attributes in MMU table entry. - -config ZYNQMP_PSU_INIT_ENABLED - bool "Include psu_init" - help - Include psu_init to full u-boot. SPL include psu_init by default. - -config SPL_ZYNQMP_ALT_BOOTMODE_ENABLED - bool "Overwrite SPL bootmode" - depends on SPL - help - Overwrite bootmode selected via boot mode pins to tell SPL what should - be the next boot device. - -config ZYNQ_SDHCI_MAX_FREQ - default 200000000 - -config SPL_ZYNQMP_ALT_BOOTMODE - hex - default 0x0 if JTAG_MODE - default 0x1 if QSPI_MODE_24BIT - default 0x2 if QSPI_MODE_32BIT - default 0x3 if SD_MODE - default 0x4 if NAND_MODE - default 0x5 if SD_MODE1 - default 0x6 if EMMC_MODE - default 0x7 if USB_MODE - default 0xa if SW_USBHOST_MODE - default 0xb if SW_SATA_MODE - default 0xe if SD1_LSHFT_MODE - -choice - prompt "Boot mode" - depends on SPL_ZYNQMP_ALT_BOOTMODE_ENABLED - default JTAG_MODE - -config JTAG_MODE - bool "JTAG_MODE" - -config QSPI_MODE_24BIT - bool "QSPI_MODE_24BIT" - -config QSPI_MODE_32BIT - bool "QSPI_MODE_32BIT" - -config SD_MODE - bool "SD_MODE" - -config SD_MODE1 - bool "SD_MODE1" - -config NAND_MODE - bool "NAND_MODE" - -config EMMC_MODE - bool "EMMC_MODE" - -config USB_MODE - bool "USB" - -config SW_USBHOST_MODE - bool "SW USBHOST_MODE" - -config SW_SATA_MODE - bool "SW SATA_MODE" - -config SD1_LSHFT_MODE - bool "SD1_LSHFT_MODE" - -endchoice - -endif diff --git a/arch/arm/cpu/armv8/zynqmp/Makefile b/arch/arm/cpu/armv8/zynqmp/Makefile deleted file mode 100644 index 8a3b0747244..00000000000 --- a/arch/arm/cpu/armv8/zynqmp/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0+ -# -# (C) Copyright 2014 - 2015 Xilinx, Inc. -# Michal Simek - -obj-y += clk.o -obj-y += cpu.o -obj-$(CONFIG_MP) += mp.o -obj-$(CONFIG_SPL_BUILD) += spl.o handoff.o -obj-$(CONFIG_ZYNQMP_PSU_INIT_ENABLED) += psu_spl_init.o diff --git a/arch/arm/cpu/armv8/zynqmp/clk.c b/arch/arm/cpu/armv8/zynqmp/clk.c deleted file mode 100644 index 0593b6310fd..00000000000 --- a/arch/arm/cpu/armv8/zynqmp/clk.c +++ /dev/null @@ -1,45 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * (C) Copyright 2014 - 2015 Xilinx, Inc. - * Michal Simek - */ - -#include -#include -#include -#include - -DECLARE_GLOBAL_DATA_PTR; - -unsigned long zynqmp_get_system_timer_freq(void) -{ - u32 ver = zynqmp_get_silicon_version(); - - switch (ver) { - case ZYNQMP_CSU_VERSION_QEMU: - return 50000000; - } - - return 100000000; -} - -#ifdef CONFIG_CLOCKS -/** - * set_cpu_clk_info() - Initialize clock framework - * Always returns zero. - * - * This function is called from common code after relocation and sets up the - * clock framework. The framework must not be used before this function had been - * called. - */ -int set_cpu_clk_info(void) -{ - gd->cpu_clk = get_tbclk(); - - gd->bd->bi_arm_freq = gd->cpu_clk / 1000000; - - gd->bd->bi_dsp_freq = 0; - - return 0; -} -#endif diff --git a/arch/arm/cpu/armv8/zynqmp/cpu.c b/arch/arm/cpu/armv8/zynqmp/cpu.c deleted file mode 100644 index 5ef1a52862c..00000000000 --- a/arch/arm/cpu/armv8/zynqmp/cpu.c +++ /dev/null @@ -1,260 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * (C) Copyright 2014 - 2015 Xilinx, Inc. - * Michal Simek - */ - -#include -#include -#include -#include -#include - -#define ZYNQ_SILICON_VER_MASK 0xF000 -#define ZYNQ_SILICON_VER_SHIFT 12 - -DECLARE_GLOBAL_DATA_PTR; - -/* - * 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) -#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, - .size = 0x70000000UL, - .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | - PTE_BLOCK_NON_SHARE | - PTE_BLOCK_PXN | PTE_BLOCK_UXN - }, { - .virt = 0xf8000000UL, - .phys = 0xf8000000UL, - .size = 0x07e00000UL, - .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | - PTE_BLOCK_NON_SHARE | - PTE_BLOCK_PXN | PTE_BLOCK_UXN - }, { - .virt = 0x400000000UL, - .phys = 0x400000000UL, - .size = 0x400000000UL, - .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | - PTE_BLOCK_NON_SHARE | - PTE_BLOCK_PXN | PTE_BLOCK_UXN - }, { - .virt = 0x1000000000UL, - .phys = 0x1000000000UL, - .size = 0xf000000000UL, - .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | - PTE_BLOCK_NON_SHARE | - PTE_BLOCK_PXN | PTE_BLOCK_UXN - } -}; - -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) -{ - return 0x14000; -} - -#if defined(CONFIG_SYS_MEM_RSVD_FOR_MMU) || defined(CONFIG_DEFINE_TCM_OCM_MMAP) -void tcm_init(u8 mode) -{ - puts("WARNING: Initializing TCM overwrites TCM content\n"); - initialize_tcm(mode); - memset((void *)ZYNQMP_TCM_BASE_ADDR, 0, ZYNQMP_TCM_SIZE); -} -#endif - -#ifdef CONFIG_SYS_MEM_RSVD_FOR_MMU -int reserve_mmu(void) -{ - tcm_init(TCM_LOCK); - gd->arch.tlb_size = PGTABLE_SIZE; - gd->arch.tlb_addr = ZYNQMP_TCM_BASE_ADDR; - - return 0; -} -#endif - -static unsigned int zynqmp_get_silicon_version_secure(void) -{ - u32 ver; - - ver = readl(&csu_base->version); - ver &= ZYNQMP_SILICON_VER_MASK; - ver >>= ZYNQMP_SILICON_VER_SHIFT; - - return ver; -} - -unsigned int zynqmp_get_silicon_version(void) -{ - if (current_el() == 3) - return zynqmp_get_silicon_version_secure(); - - gd->cpu_clk = get_tbclk(); - - switch (gd->cpu_clk) { - case 50000000: - return ZYNQMP_CSU_VERSION_QEMU; - } - - return ZYNQMP_CSU_VERSION_SILICON; -} - -#define ZYNQMP_MMIO_READ 0xC2000014 -#define ZYNQMP_MMIO_WRITE 0xC2000013 - -int __maybe_unused invoke_smc(u32 pm_api_id, u32 arg0, u32 arg1, u32 arg2, - u32 arg3, u32 *ret_payload) -{ - /* - * Added SIP service call Function Identifier - * Make sure to stay in x0 register - */ - struct pt_regs regs; - - regs.regs[0] = pm_api_id; - regs.regs[1] = ((u64)arg1 << 32) | arg0; - regs.regs[2] = ((u64)arg3 << 32) | arg2; - - smc_call(®s); - - if (ret_payload != NULL) { - ret_payload[0] = (u32)regs.regs[0]; - ret_payload[1] = upper_32_bits(regs.regs[0]); - ret_payload[2] = (u32)regs.regs[1]; - ret_payload[3] = upper_32_bits(regs.regs[1]); - ret_payload[4] = (u32)regs.regs[2]; - } - - return regs.regs[0]; -} - -unsigned int __maybe_unused zynqmp_pmufw_version(void) -{ - int ret; - u32 ret_payload[PAYLOAD_ARG_CNT]; - static u32 pm_api_version = ZYNQMP_PM_VERSION_INVALID; - - /* - * Get PMU version only once and later - * just return stored values instead of - * asking PMUFW again. - */ - if (pm_api_version == ZYNQMP_PM_VERSION_INVALID) { - ret = invoke_smc(ZYNQMP_SIP_SVC_GET_API_VERSION, 0, 0, 0, 0, - ret_payload); - pm_api_version = ret_payload[1]; - - if (ret) - panic("PMUFW is not found - Please load it!\n"); - } - - return pm_api_version; -} - -static int zynqmp_mmio_rawwrite(const u32 address, - const u32 mask, - const u32 value) -{ - u32 data; - u32 value_local = value; - int ret; - - ret = zynqmp_mmio_read(address, &data); - if (ret) - return ret; - - data &= ~mask; - value_local &= mask; - value_local |= data; - writel(value_local, (ulong)address); - return 0; -} - -static int zynqmp_mmio_rawread(const u32 address, u32 *value) -{ - *value = readl((ulong)address); - return 0; -} - -int zynqmp_mmio_write(const u32 address, - const u32 mask, - const u32 value) -{ - if (IS_ENABLED(CONFIG_SPL_BUILD) || current_el() == 3) - return zynqmp_mmio_rawwrite(address, mask, value); - else - return invoke_smc(ZYNQMP_MMIO_WRITE, address, mask, - value, 0, NULL); - - return -EINVAL; -} - -int zynqmp_mmio_read(const u32 address, u32 *value) -{ - u32 ret_payload[PAYLOAD_ARG_CNT]; - u32 ret; - - if (!value) - return -EINVAL; - - if (IS_ENABLED(CONFIG_SPL_BUILD) || current_el() == 3) { - ret = zynqmp_mmio_rawread(address, value); - } else { - ret = invoke_smc(ZYNQMP_MMIO_READ, address, 0, 0, - 0, ret_payload); - *value = ret_payload[1]; - } - - return ret; -} diff --git a/arch/arm/cpu/armv8/zynqmp/handoff.c b/arch/arm/cpu/armv8/zynqmp/handoff.c deleted file mode 100644 index f71ff7b3d25..00000000000 --- a/arch/arm/cpu/armv8/zynqmp/handoff.c +++ /dev/null @@ -1,86 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Copyright 2016 - 2017 Xilinx, Inc. - * - * Michal Simek - */ - -#include -#include -#include -#include - -/* - * atfhandoffparams - * Parameter bitfield encoding - * ----------------------------------------------------------------------------- - * Exec State 0 0 -> Aarch64, 1-> Aarch32 - * endianness 1 0 -> LE, 1 -> BE - * secure (TZ) 2 0 -> Non secure, 1 -> secure - * EL 3:4 00 -> EL0, 01 -> EL1, 10 -> EL2, 11 -> EL3 - * CPU# 5:6 00 -> A53_0, 01 -> A53_1, 10 -> A53_2, 11 -> A53_3 - */ - -#define FSBL_FLAGS_ESTATE_SHIFT 0 -#define FSBL_FLAGS_ESTATE_MASK (1 << FSBL_FLAGS_ESTATE_SHIFT) -#define FSBL_FLAGS_ESTATE_A64 0 -#define FSBL_FLAGS_ESTATE_A32 1 - -#define FSBL_FLAGS_ENDIAN_SHIFT 1 -#define FSBL_FLAGS_ENDIAN_MASK (1 << FSBL_FLAGS_ENDIAN_SHIFT) -#define FSBL_FLAGS_ENDIAN_LE 0 -#define FSBL_FLAGS_ENDIAN_BE 1 - -#define FSBL_FLAGS_TZ_SHIFT 2 -#define FSBL_FLAGS_TZ_MASK (1 << FSBL_FLAGS_TZ_SHIFT) -#define FSBL_FLAGS_NON_SECURE 0 -#define FSBL_FLAGS_SECURE 1 - -#define FSBL_FLAGS_EL_SHIFT 3 -#define FSBL_FLAGS_EL_MASK (3 << FSBL_FLAGS_EL_SHIFT) -#define FSBL_FLAGS_EL0 0 -#define FSBL_FLAGS_EL1 1 -#define FSBL_FLAGS_EL2 2 -#define FSBL_FLAGS_EL3 3 - -#define FSBL_FLAGS_CPU_SHIFT 5 -#define FSBL_FLAGS_CPU_MASK (3 << FSBL_FLAGS_CPU_SHIFT) -#define FSBL_FLAGS_A53_0 0 -#define FSBL_FLAGS_A53_1 1 -#define FSBL_FLAGS_A53_2 2 -#define FSBL_FLAGS_A53_3 3 - -#define FSBL_MAX_PARTITIONS 8 - -/* Structure corresponding to each partition entry */ -struct xfsbl_partition { - uint64_t entry_point; - uint64_t flags; -}; - -/* Structure for handoff parameters to ARM Trusted Firmware (ATF) */ -struct xfsbl_atf_handoff_params { - uint8_t magic[4]; - uint32_t num_entries; - struct xfsbl_partition partition[FSBL_MAX_PARTITIONS]; -}; - -#ifdef CONFIG_SPL_OS_BOOT -void handoff_setup(void) -{ - struct xfsbl_atf_handoff_params *atfhandoffparams; - - atfhandoffparams = (void *)CONFIG_SPL_TEXT_BASE; - atfhandoffparams->magic[0] = 'X'; - atfhandoffparams->magic[1] = 'L'; - atfhandoffparams->magic[2] = 'N'; - atfhandoffparams->magic[3] = 'X'; - - atfhandoffparams->num_entries = 1; - atfhandoffparams->partition[0].entry_point = CONFIG_SYS_TEXT_BASE; - atfhandoffparams->partition[0].flags = FSBL_FLAGS_EL2 << - FSBL_FLAGS_EL_SHIFT; - - writel(CONFIG_SPL_TEXT_BASE, &pmu_base->gen_storage6); -} -#endif diff --git a/arch/arm/cpu/armv8/zynqmp/mp.c b/arch/arm/cpu/armv8/zynqmp/mp.c deleted file mode 100644 index 2a71870ae7b..00000000000 --- a/arch/arm/cpu/armv8/zynqmp/mp.c +++ /dev/null @@ -1,297 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * (C) Copyright 2014 - 2015 Xilinx, Inc. - * Michal Simek - */ - -#include -#include -#include -#include - -#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(u32 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 propagate */ - udelay(0x500); -} - -int cpu_disable(u32 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(u32 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); -} - -static void write_tcm_boot_trampoline(u32 boot_addr) -{ - if (boot_addr) { - /* - * Boot trampoline is simple ASM code below. - * - * b over; - * label: - * .word 0 - * over: ldr r0, =label - * ldr r1, [r0] - * bx r1 - */ - debug("Write boot trampoline for %x\n", boot_addr); - writel(0xea000000, ZYNQMP_TCM_START_ADDRESS); - writel(boot_addr, ZYNQMP_TCM_START_ADDRESS + 0x4); - writel(0xe59f0004, ZYNQMP_TCM_START_ADDRESS + 0x8); - writel(0xe5901000, ZYNQMP_TCM_START_ADDRESS + 0xc); - writel(0xe12fff11, ZYNQMP_TCM_START_ADDRESS + 0x10); - writel(0x00000004, ZYNQMP_TCM_START_ADDRESS + 0x14); // address for - } -} - -void initialize_tcm(bool mode) -{ - if (!mode) { - set_r5_tcm_mode(LOCK); - set_r5_halt_mode(HALT, LOCK); - enable_clock_r5(); - release_r5_reset(LOCK); - } else { - set_r5_tcm_mode(SPLIT); - set_r5_halt_mode(HALT, SPLIT); - enable_clock_r5(); - release_r5_reset(SPLIT); - } -} - -int cpu_release(u32 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(" -Start addr lockstep or split\n"); - return 1; - } - - u32 boot_addr = simple_strtoul(argv[0], NULL, 16); - u32 boot_addr_uniq = 0; - if (!(boot_addr == ZYNQMP_R5_LOVEC_ADDR || - boot_addr == ZYNQMP_R5_HIVEC_ADDR)) { - printf("Using TCM jump trampoline for address 0x%x\n", - boot_addr); - /* Save boot address for later usage */ - boot_addr_uniq = boot_addr; - /* - * R5 needs to start from LOVEC at TCM - * OCM will be probably occupied by ATF - */ - boot_addr = ZYNQMP_R5_LOVEC_ADDR; - } - - /* - * Since we don't know where the user may have loaded the image - * for an R5 we have to flush all the data cache to ensure - * the R5 sees it. - */ - flush_dcache_all(); - - if (!strncmp(argv[1], "lockstep", 8)) { - printf("R5 lockstep mode\n"); - set_r5_reset(LOCK); - set_r5_tcm_mode(LOCK); - set_r5_halt_mode(HALT, LOCK); - set_r5_start(boot_addr); - enable_clock_r5(); - release_r5_reset(LOCK); - dcache_disable(); - write_tcm_boot_trampoline(boot_addr_uniq); - dcache_enable(); - set_r5_halt_mode(RELEASE, LOCK); - } else if (!strncmp(argv[1], "split", 5)) { - printf("R5 split mode\n"); - set_r5_reset(SPLIT); - set_r5_tcm_mode(SPLIT); - set_r5_halt_mode(HALT, SPLIT); - set_r5_start(boot_addr); - enable_clock_r5(); - release_r5_reset(SPLIT); - dcache_disable(); - write_tcm_boot_trampoline(boot_addr_uniq); - dcache_enable(); - set_r5_halt_mode(RELEASE, SPLIT); - } else { - printf("Unsupported mode\n"); - return 1; - } - } - - return 0; -} diff --git a/arch/arm/cpu/armv8/zynqmp/psu_spl_init.c b/arch/arm/cpu/armv8/zynqmp/psu_spl_init.c deleted file mode 100644 index b357de32358..00000000000 --- a/arch/arm/cpu/armv8/zynqmp/psu_spl_init.c +++ /dev/null @@ -1,79 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Copyright 2018 Xilinx, Inc. - * - * Michal Simek - */ -#include -#include -#include - -#define PSU_MASK_POLL_TIME 1100000 - -int __maybe_unused mask_pollonvalue(unsigned long add, u32 mask, u32 value) -{ - int i = 0; - - while ((__raw_readl(add) & mask) != value) { - if (i == PSU_MASK_POLL_TIME) - return 0; - i++; - } - return 1; -} - -__weak int mask_poll(u32 add, u32 mask) -{ - int i = 0; - unsigned long addr = add; - - while (!(__raw_readl(addr) & mask)) { - if (i == PSU_MASK_POLL_TIME) - return 0; - i++; - } - return 1; -} - -__weak u32 mask_read(u32 add, u32 mask) -{ - unsigned long addr = add; - - return __raw_readl(addr) & mask; -} - -__weak void mask_delay(u32 delay) -{ - udelay(delay); -} - -__weak void psu_mask_write(unsigned long offset, unsigned long mask, - unsigned long val) -{ - unsigned long regval = 0; - - regval = readl(offset); - regval &= ~(mask); - regval |= (val & mask); - writel(regval, offset); -} - -__weak void prog_reg(unsigned long addr, unsigned long mask, - unsigned long shift, unsigned long value) -{ - int rdata = 0; - - rdata = readl(addr); - rdata = rdata & (~mask); - rdata = rdata | (value << shift); - writel(rdata, addr); -} - -__weak int psu_init(void) -{ - /* - * This function is overridden by the one in - * board/xilinx/zynqmp/(platform)/psu_init_gpl.c, if it exists. - */ - return -1; -} diff --git a/arch/arm/cpu/armv8/zynqmp/spl.c b/arch/arm/cpu/armv8/zynqmp/spl.c deleted file mode 100644 index 01f31d0f0ed..00000000000 --- a/arch/arm/cpu/armv8/zynqmp/spl.c +++ /dev/null @@ -1,134 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Copyright 2015 - 2016 Xilinx, Inc. - * - * Michal Simek - */ - -#include -#include -#include - -#include -#include -#include -#include - -void board_init_f(ulong dummy) -{ - board_early_init_f(); - board_early_init_r(); - -#ifdef CONFIG_DEBUG_UART - /* Uart debug for sure */ - debug_uart_init(); - puts("Debug uart enabled\n"); /* or printch() */ -#endif - /* Delay is required for clocks to be propagated */ - udelay(1000000); - - /* Clear the BSS */ - memset(__bss_start, 0, __bss_end - __bss_start); - - /* No need to call timer init - it is empty for ZynqMP */ - board_init_r(NULL, 0); -} - -static void ps_mode_reset(ulong mode) -{ - writel(mode << ZYNQMP_CRL_APB_BOOT_PIN_CTRL_OUT_EN_SHIFT, - &crlapb_base->boot_pin_ctrl); - udelay(5); - writel(mode << ZYNQMP_CRL_APB_BOOT_PIN_CTRL_OUT_VAL_SHIFT | - mode << ZYNQMP_CRL_APB_BOOT_PIN_CTRL_OUT_EN_SHIFT, - &crlapb_base->boot_pin_ctrl); -} - -/* - * Set default PS_MODE1 which is used for USB ULPI phy reset - * Also other resets can be connected to this certain pin - */ -#ifndef MODE_RESET -# define MODE_RESET PS_MODE1 -#endif - -#ifdef CONFIG_SPL_BOARD_INIT -void spl_board_init(void) -{ - preloader_console_init(); - ps_mode_reset(MODE_RESET); - board_init(); -} -#endif - -u32 spl_boot_device(void) -{ - u32 reg = 0; - u8 bootmode; - -#if defined(CONFIG_SPL_ZYNQMP_ALT_BOOTMODE_ENABLED) - /* Change default boot mode at run-time */ - writel(CONFIG_SPL_ZYNQMP_ALT_BOOTMODE << BOOT_MODE_ALT_SHIFT, - &crlapb_base->boot_mode); -#endif - - reg = readl(&crlapb_base->boot_mode); - if (reg >> BOOT_MODE_ALT_SHIFT) - reg >>= BOOT_MODE_ALT_SHIFT; - - bootmode = reg & BOOT_MODES_MASK; - - switch (bootmode) { - case JTAG_MODE: - return BOOT_DEVICE_RAM; -#ifdef CONFIG_SPL_MMC_SUPPORT - case SD_MODE1: - case SD1_LSHFT_MODE: /* not working on silicon v1 */ -/* if both controllers enabled, then these two are the second controller */ -#if defined(CONFIG_ZYNQ_SDHCI0) && defined(CONFIG_ZYNQ_SDHCI1) - return BOOT_DEVICE_MMC2; -/* else, fall through, the one SDHCI controller that is enabled is number 1 */ -#endif - case SD_MODE: - case EMMC_MODE: - return BOOT_DEVICE_MMC1; -#endif -#ifdef CONFIG_SPL_DFU_SUPPORT - case USB_MODE: - return BOOT_DEVICE_DFU; -#endif -#ifdef CONFIG_SPL_SATA_SUPPORT - case SW_SATA_MODE: - return BOOT_DEVICE_SATA; -#endif -#ifdef CONFIG_SPL_SPI_SUPPORT - case QSPI_MODE_24BIT: - case QSPI_MODE_32BIT: - return BOOT_DEVICE_SPI; -#endif - default: - printf("Invalid Boot Mode:0x%x\n", bootmode); - break; - } - - return 0; -} - -#ifdef CONFIG_SPL_OS_BOOT -int spl_start_uboot(void) -{ - handoff_setup(); - - return 0; -} -#endif - -#ifdef CONFIG_SPL_LOAD_FIT -int board_fit_config_name_match(const char *name) -{ - /* Just empty function now - can't decide what to choose */ - debug("%s: %s\n", __func__, name); - - return 0; -} -#endif diff --git a/arch/arm/include/asm/arch-zynqmp/clk.h b/arch/arm/include/asm/arch-zynqmp/clk.h deleted file mode 100644 index cfd44c8e0f7..00000000000 --- a/arch/arm/include/asm/arch-zynqmp/clk.h +++ /dev/null @@ -1,12 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * (C) Copyright 2014 - 2015 Xilinx, Inc. - * Michal Simek - */ - -#ifndef _ASM_ARCH_CLK_H_ -#define _ASM_ARCH_CLK_H_ - -unsigned long zynqmp_get_system_timer_freq(void); - -#endif /* _ASM_ARCH_CLK_H_ */ diff --git a/arch/arm/include/asm/arch-zynqmp/gpio.h b/arch/arm/include/asm/arch-zynqmp/gpio.h deleted file mode 100644 index 542a5fc3e94..00000000000 --- a/arch/arm/include/asm/arch-zynqmp/gpio.h +++ /dev/null @@ -1,11 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Copyright 2015 Xilinx, Inc. - */ - -#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 deleted file mode 100644 index 8a505edab3c..00000000000 --- a/arch/arm/include/asm/arch-zynqmp/hardware.h +++ /dev/null @@ -1,159 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * (C) Copyright 2014 - 2015 Xilinx, Inc. - * Michal Simek - */ - -#ifndef _ASM_ARCH_HARDWARE_H -#define _ASM_ARCH_HARDWARE_H - -#define ZYNQ_GEM_BASEADDR0 0xFF0B0000 -#define ZYNQ_GEM_BASEADDR1 0xFF0C0000 -#define ZYNQ_GEM_BASEADDR2 0xFF0D0000 -#define ZYNQ_GEM_BASEADDR3 0xFF0E0000 - -#define ZYNQ_I2C_BASEADDR0 0xFF020000 -#define ZYNQ_I2C_BASEADDR1 0xFF030000 - -#define ARASAN_NAND_BASEADDR 0xFF100000 - -#define ZYNQMP_TCM_BASE_ADDR 0xFFE00000 -#define ZYNQMP_TCM_SIZE 0x40000 - -#define ZYNQMP_CRL_APB_BASEADDR 0xFF5E0000 -#define ZYNQMP_CRL_APB_TIMESTAMP_REF_CTRL_CLKACT 0x1000000 -#define ZYNQMP_CRL_APB_BOOT_PIN_CTRL_OUT_EN_SHIFT 0 -#define ZYNQMP_CRL_APB_BOOT_PIN_CTRL_OUT_VAL_SHIFT 8 - -#define PS_MODE0 BIT(0) -#define PS_MODE1 BIT(1) -#define PS_MODE2 BIT(2) -#define PS_MODE3 BIT(3) - -#define RESET_REASON_DEBUG_SYS BIT(6) -#define RESET_REASON_SOFT BIT(5) -#define RESET_REASON_SRST BIT(4) -#define RESET_REASON_PSONLY BIT(3) -#define RESET_REASON_PMU BIT(2) -#define RESET_REASON_INTERNAL BIT(1) -#define RESET_REASON_EXTERNAL BIT(0) - -struct crlapb_regs { - u32 reserved0[36]; - u32 cpu_r5_ctrl; /* 0x90 */ - u32 reserved1[37]; - u32 timestamp_ref_ctrl; /* 0x128 */ - u32 reserved2[53]; - u32 boot_mode; /* 0x200 */ - u32 reserved3_0[7]; - u32 reset_reason; /* 0x220 */ - u32 reserved3_1[6]; - u32 rst_lpd_top; /* 0x23C */ - u32 reserved4[4]; - u32 boot_pin_ctrl; /* 0x250 */ - u32 reserved5[21]; -}; - -#define crlapb_base ((struct crlapb_regs *)ZYNQMP_CRL_APB_BASEADDR) - -#define ZYNQMP_IOU_SCNTR_SECURE 0xFF260000 -#define ZYNQMP_IOU_SCNTR_COUNTER_CONTROL_REGISTER_EN 0x1 -#define ZYNQMP_IOU_SCNTR_COUNTER_CONTROL_REGISTER_HDBG 0x2 - -struct iou_scntr_secure { - u32 counter_control_register; - u32 reserved0[7]; - u32 base_frequency_id_register; -}; - -#define iou_scntr_secure ((struct iou_scntr_secure *)ZYNQMP_IOU_SCNTR_SECURE) - -/* Bootmode setting values */ -#define BOOT_MODES_MASK 0x0000000F -#define QSPI_MODE_24BIT 0x00000001 -#define QSPI_MODE_32BIT 0x00000002 -#define SD_MODE 0x00000003 /* sd 0 */ -#define SD_MODE1 0x00000005 /* sd 1 */ -#define NAND_MODE 0x00000004 -#define EMMC_MODE 0x00000006 -#define USB_MODE 0x00000007 -#define SD1_LSHFT_MODE 0x0000000E /* SD1 Level shifter */ -#define JTAG_MODE 0x00000000 -#define BOOT_MODE_USE_ALT 0x100 -#define BOOT_MODE_ALT_SHIFT 12 -/* SW secondary boot modes 0xa - 0xd */ -#define SW_USBHOST_MODE 0x0000000A -#define SW_SATA_MODE 0x0000000B - -#define ZYNQMP_IOU_SLCR_BASEADDR 0xFF180000 - -struct iou_slcr_regs { - u32 mio_pin[78]; - u32 reserved[442]; -}; - -#define slcr_base ((struct iou_slcr_regs *)ZYNQMP_IOU_SLCR_BASEADDR) - -#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_BASEADDR 0xFFCA0000 -#define ZYNQMP_CSU_VERSION_SILICON 0x0 -#define ZYNQMP_CSU_VERSION_QEMU 0x3 - -#define ZYNQMP_CSU_VERSION_EMPTY_SHIFT 20 - -#define ZYNQMP_SILICON_VER_MASK 0xF000 -#define ZYNQMP_SILICON_VER_SHIFT 12 - -struct csu_regs { - u32 reserved0[17]; - u32 version; -}; - -#define csu_base ((struct csu_regs *)ZYNQMP_CSU_BASEADDR) - -#define ZYNQMP_PMU_BASEADDR 0xFFD80000 - -struct pmu_regs { - u32 reserved[18]; - u32 gen_storage6; /* 0x48 */ -}; - -#define pmu_base ((struct pmu_regs *)ZYNQMP_PMU_BASEADDR) - -#define ZYNQMP_CSU_IDCODE_ADDR 0xFFCA0040 -#define ZYNQMP_CSU_VER_ADDR 0xFFCA0044 - -#endif /* _ASM_ARCH_HARDWARE_H */ diff --git a/arch/arm/include/asm/arch-zynqmp/psu_init_gpl.h b/arch/arm/include/asm/arch-zynqmp/psu_init_gpl.h deleted file mode 100644 index 15e54c04938..00000000000 --- a/arch/arm/include/asm/arch-zynqmp/psu_init_gpl.h +++ /dev/null @@ -1,25 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ - -#ifndef _PSU_INIT_GPL_H_ /* prevent circular inclusions */ -#define _PSU_INIT_GPL_H_ - -#include -#include - -int mask_pollonvalue(unsigned long add, u32 mask, u32 value); - -int mask_poll(u32 add, u32 mask); - -u32 mask_read(u32 add, u32 mask); - -void mask_delay(u32 delay); - -void psu_mask_write(unsigned long offset, unsigned long mask, - unsigned long val); - -void prog_reg(unsigned long addr, unsigned long mask, - unsigned long shift, unsigned long value); - -int psu_init(void); - -#endif /* _PSU_INIT_GPL_H_ */ diff --git a/arch/arm/include/asm/arch-zynqmp/sys_proto.h b/arch/arm/include/asm/arch-zynqmp/sys_proto.h deleted file mode 100644 index 385c8825f2f..00000000000 --- a/arch/arm/include/asm/arch-zynqmp/sys_proto.h +++ /dev/null @@ -1,75 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * (C) Copyright 2014 - 2015 Xilinx, Inc. - * Michal Simek - */ - -#ifndef _ASM_ARCH_SYS_PROTO_H -#define _ASM_ARCH_SYS_PROTO_H - -#define PAYLOAD_ARG_CNT 5 - -#define ZYNQMP_CSU_SILICON_VER_MASK 0xF -#define ZYNQMP_SIP_SVC_PM_SECURE_IMG_LOAD 0xC200002D -#define KEY_PTR_LEN 32 - -#define ZYNQMP_FPGA_BIT_AUTH_DDR 1 -#define ZYNQMP_FPGA_BIT_AUTH_OCM 2 -#define ZYNQMP_FPGA_BIT_ENC_USR_KEY 3 -#define ZYNQMP_FPGA_BIT_ENC_DEV_KEY 4 -#define ZYNQMP_FPGA_BIT_NS 5 - -#define ZYNQMP_FPGA_AUTH_DDR 1 - -#define ZYNQMP_SIP_SVC_GET_API_VERSION 0xC2000001 - -#define ZYNQMP_PM_VERSION_MAJOR 1 -#define ZYNQMP_PM_VERSION_MINOR 0 -#define ZYNQMP_PM_VERSION_MAJOR_SHIFT 16 -#define ZYNQMP_PM_VERSION_MINOR_MASK 0xFFFF - -#define ZYNQMP_PM_VERSION \ - ((ZYNQMP_PM_VERSION_MAJOR << ZYNQMP_PM_VERSION_MAJOR_SHIFT) | \ - ZYNQMP_PM_VERSION_MINOR) - -#define ZYNQMP_PM_VERSION_INVALID ~0 - -#define PMUFW_V1_0 ((1 << ZYNQMP_PM_VERSION_MAJOR_SHIFT) | 0) - -enum { - IDCODE, - VERSION, - IDCODE2, -}; - -enum { - ZYNQMP_SILICON_V1, - ZYNQMP_SILICON_V2, - ZYNQMP_SILICON_V3, - ZYNQMP_SILICON_V4, -}; - -enum { - TCM_LOCK, - TCM_SPLIT, -}; - -int zynq_board_read_rom_ethaddr(unsigned char *ethaddr); -unsigned int zynqmp_get_silicon_version(void); - -void handoff_setup(void); - -unsigned int zynqmp_pmufw_version(void); -int zynqmp_mmio_write(const u32 address, const u32 mask, const u32 value); -int zynqmp_mmio_read(const u32 address, u32 *value); -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); -#if defined(CONFIG_SYS_MEM_RSVD_FOR_MMU) || defined(CONFIG_DEFINE_TCM_OCM_MMAP) -void tcm_init(u8 mode); -#endif - -#endif /* _ASM_ARCH_SYS_PROTO_H */ diff --git a/arch/arm/mach-k3/arm64-mmu.c b/arch/arm/mach-k3/arm64-mmu.c index f8b93fe4584..a75ba1ffdba 100644 --- a/arch/arm/mach-k3/arm64-mmu.c +++ b/arch/arm/mach-k3/arm64-mmu.c @@ -4,7 +4,7 @@ * * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/ * Lokesh Vutla - * (This file is derived from arch/arm/cpu/armv8/zynqmp/cpu.c) + * (This file is derived from arch/arm/mach-zynqmp/cpu.c) * */ diff --git a/arch/arm/mach-tegra/arm64-mmu.c b/arch/arm/mach-tegra/arm64-mmu.c index 702fde1dea1..d45b1faaa2c 100644 --- a/arch/arm/mach-tegra/arm64-mmu.c +++ b/arch/arm/mach-tegra/arm64-mmu.c @@ -2,7 +2,7 @@ /* * (C) Copyright 2014 - 2015 Xilinx, Inc. * Michal Simek - * (This file derived from arch/arm/cpu/armv8/zynqmp/cpu.c) + * (This file derived from arch/arm/mach-zynqmp/cpu.c) * * Copyright (c) 2015, NVIDIA CORPORATION. All rights reserved. */ diff --git a/arch/arm/mach-zynqmp/Kconfig b/arch/arm/mach-zynqmp/Kconfig new file mode 100644 index 00000000000..8a311e1c894 --- /dev/null +++ b/arch/arm/mach-zynqmp/Kconfig @@ -0,0 +1,156 @@ +if ARCH_ZYNQMP + +config SPL_FAT_SUPPORT + default y + +config SPL_LIBCOMMON_SUPPORT + default y + +config SPL_LIBDISK_SUPPORT + default y + +config SPL_LIBGENERIC_SUPPORT + default y + +config SPL_MMC_SUPPORT + default y if MMC_SDHCI_ZYNQ + +config SPL_SERIAL_SUPPORT + default y + +config SPL_SPI_FLASH_SUPPORT + default y if ZYNQ_QSPI + +config SPL_SPI_SUPPORT + default y if ZYNQ_QSPI + +config SYS_BOARD + default "zynqmp" + +config SYS_VENDOR + string "Vendor name" + default "xilinx" + +config SYS_SOC + default "zynqmp" + +config SYS_CONFIG_NAME + string "Board configuration name" + default "xilinx_zynqmp" + help + This option contains information about board configuration name. + Based on this option include/configs/.h header + will be used for board configuration. + +config SYS_MEM_RSVD_FOR_MMU + bool "Reserve memory for MMU Table" + help + If defined this option is used to setup different space for + MMU table than the one which will be allocated during + relocation. + +config BOOT_INIT_FILE + string "boot.bin init register filename" + depends on SPL + default "" + help + Add register writes to boot.bin format (max 256 pairs). + Expect a table of register-value pairs, e.g. "0x12345678 0x4321" + +config PMUFW_INIT_FILE + string "PMU firmware" + depends on SPL + default "" + help + Include external PMUFW (Platform Management Unit FirmWare) to + a Xilinx bootable image (boot.bin). + +config ZYNQMP_USB + bool "Configure ZynqMP USB" + +config ZYNQMP_NO_DDR + bool "Disable DDR MMU mapping" + help + This option configures MMU with no DDR to avoid speculative + access to DDR memory where DDR is not present. + +config SYS_MALLOC_F_LEN + default 0x600 + +config DEFINE_TCM_OCM_MMAP + bool "Define TCM and OCM memory in MMU Table" + default y if MP + help + This option if enabled defines the TCM and OCM memory and its + memory attributes in MMU table entry. + +config ZYNQMP_PSU_INIT_ENABLED + bool "Include psu_init" + help + Include psu_init to full u-boot. SPL include psu_init by default. + +config SPL_ZYNQMP_ALT_BOOTMODE_ENABLED + bool "Overwrite SPL bootmode" + depends on SPL + help + Overwrite bootmode selected via boot mode pins to tell SPL what should + be the next boot device. + +config ZYNQ_SDHCI_MAX_FREQ + default 200000000 + +config SPL_ZYNQMP_ALT_BOOTMODE + hex + default 0x0 if JTAG_MODE + default 0x1 if QSPI_MODE_24BIT + default 0x2 if QSPI_MODE_32BIT + default 0x3 if SD_MODE + default 0x4 if NAND_MODE + default 0x5 if SD_MODE1 + default 0x6 if EMMC_MODE + default 0x7 if USB_MODE + default 0xa if SW_USBHOST_MODE + default 0xb if SW_SATA_MODE + default 0xe if SD1_LSHFT_MODE + +choice + prompt "Boot mode" + depends on SPL_ZYNQMP_ALT_BOOTMODE_ENABLED + default JTAG_MODE + +config JTAG_MODE + bool "JTAG_MODE" + +config QSPI_MODE_24BIT + bool "QSPI_MODE_24BIT" + +config QSPI_MODE_32BIT + bool "QSPI_MODE_32BIT" + +config SD_MODE + bool "SD_MODE" + +config SD_MODE1 + bool "SD_MODE1" + +config NAND_MODE + bool "NAND_MODE" + +config EMMC_MODE + bool "EMMC_MODE" + +config USB_MODE + bool "USB" + +config SW_USBHOST_MODE + bool "SW USBHOST_MODE" + +config SW_SATA_MODE + bool "SW SATA_MODE" + +config SD1_LSHFT_MODE + bool "SD1_LSHFT_MODE" + +endchoice + +endif diff --git a/arch/arm/mach-zynqmp/Makefile b/arch/arm/mach-zynqmp/Makefile new file mode 100644 index 00000000000..8a3b0747244 --- /dev/null +++ b/arch/arm/mach-zynqmp/Makefile @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# (C) Copyright 2014 - 2015 Xilinx, Inc. +# Michal Simek + +obj-y += clk.o +obj-y += cpu.o +obj-$(CONFIG_MP) += mp.o +obj-$(CONFIG_SPL_BUILD) += spl.o handoff.o +obj-$(CONFIG_ZYNQMP_PSU_INIT_ENABLED) += psu_spl_init.o diff --git a/arch/arm/mach-zynqmp/clk.c b/arch/arm/mach-zynqmp/clk.c new file mode 100644 index 00000000000..0593b6310fd --- /dev/null +++ b/arch/arm/mach-zynqmp/clk.c @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2014 - 2015 Xilinx, Inc. + * Michal Simek + */ + +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; + +unsigned long zynqmp_get_system_timer_freq(void) +{ + u32 ver = zynqmp_get_silicon_version(); + + switch (ver) { + case ZYNQMP_CSU_VERSION_QEMU: + return 50000000; + } + + return 100000000; +} + +#ifdef CONFIG_CLOCKS +/** + * set_cpu_clk_info() - Initialize clock framework + * Always returns zero. + * + * This function is called from common code after relocation and sets up the + * clock framework. The framework must not be used before this function had been + * called. + */ +int set_cpu_clk_info(void) +{ + gd->cpu_clk = get_tbclk(); + + gd->bd->bi_arm_freq = gd->cpu_clk / 1000000; + + gd->bd->bi_dsp_freq = 0; + + return 0; +} +#endif diff --git a/arch/arm/mach-zynqmp/cpu.c b/arch/arm/mach-zynqmp/cpu.c new file mode 100644 index 00000000000..5ef1a52862c --- /dev/null +++ b/arch/arm/mach-zynqmp/cpu.c @@ -0,0 +1,260 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2014 - 2015 Xilinx, Inc. + * Michal Simek + */ + +#include +#include +#include +#include +#include + +#define ZYNQ_SILICON_VER_MASK 0xF000 +#define ZYNQ_SILICON_VER_SHIFT 12 + +DECLARE_GLOBAL_DATA_PTR; + +/* + * 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) +#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, + .size = 0x70000000UL, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { + .virt = 0xf8000000UL, + .phys = 0xf8000000UL, + .size = 0x07e00000UL, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { + .virt = 0x400000000UL, + .phys = 0x400000000UL, + .size = 0x400000000UL, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { + .virt = 0x1000000000UL, + .phys = 0x1000000000UL, + .size = 0xf000000000UL, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + } +}; + +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) +{ + return 0x14000; +} + +#if defined(CONFIG_SYS_MEM_RSVD_FOR_MMU) || defined(CONFIG_DEFINE_TCM_OCM_MMAP) +void tcm_init(u8 mode) +{ + puts("WARNING: Initializing TCM overwrites TCM content\n"); + initialize_tcm(mode); + memset((void *)ZYNQMP_TCM_BASE_ADDR, 0, ZYNQMP_TCM_SIZE); +} +#endif + +#ifdef CONFIG_SYS_MEM_RSVD_FOR_MMU +int reserve_mmu(void) +{ + tcm_init(TCM_LOCK); + gd->arch.tlb_size = PGTABLE_SIZE; + gd->arch.tlb_addr = ZYNQMP_TCM_BASE_ADDR; + + return 0; +} +#endif + +static unsigned int zynqmp_get_silicon_version_secure(void) +{ + u32 ver; + + ver = readl(&csu_base->version); + ver &= ZYNQMP_SILICON_VER_MASK; + ver >>= ZYNQMP_SILICON_VER_SHIFT; + + return ver; +} + +unsigned int zynqmp_get_silicon_version(void) +{ + if (current_el() == 3) + return zynqmp_get_silicon_version_secure(); + + gd->cpu_clk = get_tbclk(); + + switch (gd->cpu_clk) { + case 50000000: + return ZYNQMP_CSU_VERSION_QEMU; + } + + return ZYNQMP_CSU_VERSION_SILICON; +} + +#define ZYNQMP_MMIO_READ 0xC2000014 +#define ZYNQMP_MMIO_WRITE 0xC2000013 + +int __maybe_unused invoke_smc(u32 pm_api_id, u32 arg0, u32 arg1, u32 arg2, + u32 arg3, u32 *ret_payload) +{ + /* + * Added SIP service call Function Identifier + * Make sure to stay in x0 register + */ + struct pt_regs regs; + + regs.regs[0] = pm_api_id; + regs.regs[1] = ((u64)arg1 << 32) | arg0; + regs.regs[2] = ((u64)arg3 << 32) | arg2; + + smc_call(®s); + + if (ret_payload != NULL) { + ret_payload[0] = (u32)regs.regs[0]; + ret_payload[1] = upper_32_bits(regs.regs[0]); + ret_payload[2] = (u32)regs.regs[1]; + ret_payload[3] = upper_32_bits(regs.regs[1]); + ret_payload[4] = (u32)regs.regs[2]; + } + + return regs.regs[0]; +} + +unsigned int __maybe_unused zynqmp_pmufw_version(void) +{ + int ret; + u32 ret_payload[PAYLOAD_ARG_CNT]; + static u32 pm_api_version = ZYNQMP_PM_VERSION_INVALID; + + /* + * Get PMU version only once and later + * just return stored values instead of + * asking PMUFW again. + */ + if (pm_api_version == ZYNQMP_PM_VERSION_INVALID) { + ret = invoke_smc(ZYNQMP_SIP_SVC_GET_API_VERSION, 0, 0, 0, 0, + ret_payload); + pm_api_version = ret_payload[1]; + + if (ret) + panic("PMUFW is not found - Please load it!\n"); + } + + return pm_api_version; +} + +static int zynqmp_mmio_rawwrite(const u32 address, + const u32 mask, + const u32 value) +{ + u32 data; + u32 value_local = value; + int ret; + + ret = zynqmp_mmio_read(address, &data); + if (ret) + return ret; + + data &= ~mask; + value_local &= mask; + value_local |= data; + writel(value_local, (ulong)address); + return 0; +} + +static int zynqmp_mmio_rawread(const u32 address, u32 *value) +{ + *value = readl((ulong)address); + return 0; +} + +int zynqmp_mmio_write(const u32 address, + const u32 mask, + const u32 value) +{ + if (IS_ENABLED(CONFIG_SPL_BUILD) || current_el() == 3) + return zynqmp_mmio_rawwrite(address, mask, value); + else + return invoke_smc(ZYNQMP_MMIO_WRITE, address, mask, + value, 0, NULL); + + return -EINVAL; +} + +int zynqmp_mmio_read(const u32 address, u32 *value) +{ + u32 ret_payload[PAYLOAD_ARG_CNT]; + u32 ret; + + if (!value) + return -EINVAL; + + if (IS_ENABLED(CONFIG_SPL_BUILD) || current_el() == 3) { + ret = zynqmp_mmio_rawread(address, value); + } else { + ret = invoke_smc(ZYNQMP_MMIO_READ, address, 0, 0, + 0, ret_payload); + *value = ret_payload[1]; + } + + return ret; +} diff --git a/arch/arm/mach-zynqmp/handoff.c b/arch/arm/mach-zynqmp/handoff.c new file mode 100644 index 00000000000..f71ff7b3d25 --- /dev/null +++ b/arch/arm/mach-zynqmp/handoff.c @@ -0,0 +1,86 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2016 - 2017 Xilinx, Inc. + * + * Michal Simek + */ + +#include +#include +#include +#include + +/* + * atfhandoffparams + * Parameter bitfield encoding + * ----------------------------------------------------------------------------- + * Exec State 0 0 -> Aarch64, 1-> Aarch32 + * endianness 1 0 -> LE, 1 -> BE + * secure (TZ) 2 0 -> Non secure, 1 -> secure + * EL 3:4 00 -> EL0, 01 -> EL1, 10 -> EL2, 11 -> EL3 + * CPU# 5:6 00 -> A53_0, 01 -> A53_1, 10 -> A53_2, 11 -> A53_3 + */ + +#define FSBL_FLAGS_ESTATE_SHIFT 0 +#define FSBL_FLAGS_ESTATE_MASK (1 << FSBL_FLAGS_ESTATE_SHIFT) +#define FSBL_FLAGS_ESTATE_A64 0 +#define FSBL_FLAGS_ESTATE_A32 1 + +#define FSBL_FLAGS_ENDIAN_SHIFT 1 +#define FSBL_FLAGS_ENDIAN_MASK (1 << FSBL_FLAGS_ENDIAN_SHIFT) +#define FSBL_FLAGS_ENDIAN_LE 0 +#define FSBL_FLAGS_ENDIAN_BE 1 + +#define FSBL_FLAGS_TZ_SHIFT 2 +#define FSBL_FLAGS_TZ_MASK (1 << FSBL_FLAGS_TZ_SHIFT) +#define FSBL_FLAGS_NON_SECURE 0 +#define FSBL_FLAGS_SECURE 1 + +#define FSBL_FLAGS_EL_SHIFT 3 +#define FSBL_FLAGS_EL_MASK (3 << FSBL_FLAGS_EL_SHIFT) +#define FSBL_FLAGS_EL0 0 +#define FSBL_FLAGS_EL1 1 +#define FSBL_FLAGS_EL2 2 +#define FSBL_FLAGS_EL3 3 + +#define FSBL_FLAGS_CPU_SHIFT 5 +#define FSBL_FLAGS_CPU_MASK (3 << FSBL_FLAGS_CPU_SHIFT) +#define FSBL_FLAGS_A53_0 0 +#define FSBL_FLAGS_A53_1 1 +#define FSBL_FLAGS_A53_2 2 +#define FSBL_FLAGS_A53_3 3 + +#define FSBL_MAX_PARTITIONS 8 + +/* Structure corresponding to each partition entry */ +struct xfsbl_partition { + uint64_t entry_point; + uint64_t flags; +}; + +/* Structure for handoff parameters to ARM Trusted Firmware (ATF) */ +struct xfsbl_atf_handoff_params { + uint8_t magic[4]; + uint32_t num_entries; + struct xfsbl_partition partition[FSBL_MAX_PARTITIONS]; +}; + +#ifdef CONFIG_SPL_OS_BOOT +void handoff_setup(void) +{ + struct xfsbl_atf_handoff_params *atfhandoffparams; + + atfhandoffparams = (void *)CONFIG_SPL_TEXT_BASE; + atfhandoffparams->magic[0] = 'X'; + atfhandoffparams->magic[1] = 'L'; + atfhandoffparams->magic[2] = 'N'; + atfhandoffparams->magic[3] = 'X'; + + atfhandoffparams->num_entries = 1; + atfhandoffparams->partition[0].entry_point = CONFIG_SYS_TEXT_BASE; + atfhandoffparams->partition[0].flags = FSBL_FLAGS_EL2 << + FSBL_FLAGS_EL_SHIFT; + + writel(CONFIG_SPL_TEXT_BASE, &pmu_base->gen_storage6); +} +#endif diff --git a/arch/arm/mach-zynqmp/include/mach/clk.h b/arch/arm/mach-zynqmp/include/mach/clk.h new file mode 100644 index 00000000000..cfd44c8e0f7 --- /dev/null +++ b/arch/arm/mach-zynqmp/include/mach/clk.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * (C) Copyright 2014 - 2015 Xilinx, Inc. + * Michal Simek + */ + +#ifndef _ASM_ARCH_CLK_H_ +#define _ASM_ARCH_CLK_H_ + +unsigned long zynqmp_get_system_timer_freq(void); + +#endif /* _ASM_ARCH_CLK_H_ */ diff --git a/arch/arm/mach-zynqmp/include/mach/gpio.h b/arch/arm/mach-zynqmp/include/mach/gpio.h new file mode 100644 index 00000000000..542a5fc3e94 --- /dev/null +++ b/arch/arm/mach-zynqmp/include/mach/gpio.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright 2015 Xilinx, Inc. + */ + +#ifndef __ARCH_ZYNQMP_GPIO_H +#define __ARCH_ZYNQMP_GPIO_H + +/* Empty file - sdhci requires this. */ + +#endif diff --git a/arch/arm/mach-zynqmp/include/mach/hardware.h b/arch/arm/mach-zynqmp/include/mach/hardware.h new file mode 100644 index 00000000000..8a505edab3c --- /dev/null +++ b/arch/arm/mach-zynqmp/include/mach/hardware.h @@ -0,0 +1,159 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * (C) Copyright 2014 - 2015 Xilinx, Inc. + * Michal Simek + */ + +#ifndef _ASM_ARCH_HARDWARE_H +#define _ASM_ARCH_HARDWARE_H + +#define ZYNQ_GEM_BASEADDR0 0xFF0B0000 +#define ZYNQ_GEM_BASEADDR1 0xFF0C0000 +#define ZYNQ_GEM_BASEADDR2 0xFF0D0000 +#define ZYNQ_GEM_BASEADDR3 0xFF0E0000 + +#define ZYNQ_I2C_BASEADDR0 0xFF020000 +#define ZYNQ_I2C_BASEADDR1 0xFF030000 + +#define ARASAN_NAND_BASEADDR 0xFF100000 + +#define ZYNQMP_TCM_BASE_ADDR 0xFFE00000 +#define ZYNQMP_TCM_SIZE 0x40000 + +#define ZYNQMP_CRL_APB_BASEADDR 0xFF5E0000 +#define ZYNQMP_CRL_APB_TIMESTAMP_REF_CTRL_CLKACT 0x1000000 +#define ZYNQMP_CRL_APB_BOOT_PIN_CTRL_OUT_EN_SHIFT 0 +#define ZYNQMP_CRL_APB_BOOT_PIN_CTRL_OUT_VAL_SHIFT 8 + +#define PS_MODE0 BIT(0) +#define PS_MODE1 BIT(1) +#define PS_MODE2 BIT(2) +#define PS_MODE3 BIT(3) + +#define RESET_REASON_DEBUG_SYS BIT(6) +#define RESET_REASON_SOFT BIT(5) +#define RESET_REASON_SRST BIT(4) +#define RESET_REASON_PSONLY BIT(3) +#define RESET_REASON_PMU BIT(2) +#define RESET_REASON_INTERNAL BIT(1) +#define RESET_REASON_EXTERNAL BIT(0) + +struct crlapb_regs { + u32 reserved0[36]; + u32 cpu_r5_ctrl; /* 0x90 */ + u32 reserved1[37]; + u32 timestamp_ref_ctrl; /* 0x128 */ + u32 reserved2[53]; + u32 boot_mode; /* 0x200 */ + u32 reserved3_0[7]; + u32 reset_reason; /* 0x220 */ + u32 reserved3_1[6]; + u32 rst_lpd_top; /* 0x23C */ + u32 reserved4[4]; + u32 boot_pin_ctrl; /* 0x250 */ + u32 reserved5[21]; +}; + +#define crlapb_base ((struct crlapb_regs *)ZYNQMP_CRL_APB_BASEADDR) + +#define ZYNQMP_IOU_SCNTR_SECURE 0xFF260000 +#define ZYNQMP_IOU_SCNTR_COUNTER_CONTROL_REGISTER_EN 0x1 +#define ZYNQMP_IOU_SCNTR_COUNTER_CONTROL_REGISTER_HDBG 0x2 + +struct iou_scntr_secure { + u32 counter_control_register; + u32 reserved0[7]; + u32 base_frequency_id_register; +}; + +#define iou_scntr_secure ((struct iou_scntr_secure *)ZYNQMP_IOU_SCNTR_SECURE) + +/* Bootmode setting values */ +#define BOOT_MODES_MASK 0x0000000F +#define QSPI_MODE_24BIT 0x00000001 +#define QSPI_MODE_32BIT 0x00000002 +#define SD_MODE 0x00000003 /* sd 0 */ +#define SD_MODE1 0x00000005 /* sd 1 */ +#define NAND_MODE 0x00000004 +#define EMMC_MODE 0x00000006 +#define USB_MODE 0x00000007 +#define SD1_LSHFT_MODE 0x0000000E /* SD1 Level shifter */ +#define JTAG_MODE 0x00000000 +#define BOOT_MODE_USE_ALT 0x100 +#define BOOT_MODE_ALT_SHIFT 12 +/* SW secondary boot modes 0xa - 0xd */ +#define SW_USBHOST_MODE 0x0000000A +#define SW_SATA_MODE 0x0000000B + +#define ZYNQMP_IOU_SLCR_BASEADDR 0xFF180000 + +struct iou_slcr_regs { + u32 mio_pin[78]; + u32 reserved[442]; +}; + +#define slcr_base ((struct iou_slcr_regs *)ZYNQMP_IOU_SLCR_BASEADDR) + +#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_BASEADDR 0xFFCA0000 +#define ZYNQMP_CSU_VERSION_SILICON 0x0 +#define ZYNQMP_CSU_VERSION_QEMU 0x3 + +#define ZYNQMP_CSU_VERSION_EMPTY_SHIFT 20 + +#define ZYNQMP_SILICON_VER_MASK 0xF000 +#define ZYNQMP_SILICON_VER_SHIFT 12 + +struct csu_regs { + u32 reserved0[17]; + u32 version; +}; + +#define csu_base ((struct csu_regs *)ZYNQMP_CSU_BASEADDR) + +#define ZYNQMP_PMU_BASEADDR 0xFFD80000 + +struct pmu_regs { + u32 reserved[18]; + u32 gen_storage6; /* 0x48 */ +}; + +#define pmu_base ((struct pmu_regs *)ZYNQMP_PMU_BASEADDR) + +#define ZYNQMP_CSU_IDCODE_ADDR 0xFFCA0040 +#define ZYNQMP_CSU_VER_ADDR 0xFFCA0044 + +#endif /* _ASM_ARCH_HARDWARE_H */ diff --git a/arch/arm/mach-zynqmp/include/mach/psu_init_gpl.h b/arch/arm/mach-zynqmp/include/mach/psu_init_gpl.h new file mode 100644 index 00000000000..15e54c04938 --- /dev/null +++ b/arch/arm/mach-zynqmp/include/mach/psu_init_gpl.h @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ + +#ifndef _PSU_INIT_GPL_H_ /* prevent circular inclusions */ +#define _PSU_INIT_GPL_H_ + +#include +#include + +int mask_pollonvalue(unsigned long add, u32 mask, u32 value); + +int mask_poll(u32 add, u32 mask); + +u32 mask_read(u32 add, u32 mask); + +void mask_delay(u32 delay); + +void psu_mask_write(unsigned long offset, unsigned long mask, + unsigned long val); + +void prog_reg(unsigned long addr, unsigned long mask, + unsigned long shift, unsigned long value); + +int psu_init(void); + +#endif /* _PSU_INIT_GPL_H_ */ diff --git a/arch/arm/mach-zynqmp/include/mach/sys_proto.h b/arch/arm/mach-zynqmp/include/mach/sys_proto.h new file mode 100644 index 00000000000..385c8825f2f --- /dev/null +++ b/arch/arm/mach-zynqmp/include/mach/sys_proto.h @@ -0,0 +1,75 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * (C) Copyright 2014 - 2015 Xilinx, Inc. + * Michal Simek + */ + +#ifndef _ASM_ARCH_SYS_PROTO_H +#define _ASM_ARCH_SYS_PROTO_H + +#define PAYLOAD_ARG_CNT 5 + +#define ZYNQMP_CSU_SILICON_VER_MASK 0xF +#define ZYNQMP_SIP_SVC_PM_SECURE_IMG_LOAD 0xC200002D +#define KEY_PTR_LEN 32 + +#define ZYNQMP_FPGA_BIT_AUTH_DDR 1 +#define ZYNQMP_FPGA_BIT_AUTH_OCM 2 +#define ZYNQMP_FPGA_BIT_ENC_USR_KEY 3 +#define ZYNQMP_FPGA_BIT_ENC_DEV_KEY 4 +#define ZYNQMP_FPGA_BIT_NS 5 + +#define ZYNQMP_FPGA_AUTH_DDR 1 + +#define ZYNQMP_SIP_SVC_GET_API_VERSION 0xC2000001 + +#define ZYNQMP_PM_VERSION_MAJOR 1 +#define ZYNQMP_PM_VERSION_MINOR 0 +#define ZYNQMP_PM_VERSION_MAJOR_SHIFT 16 +#define ZYNQMP_PM_VERSION_MINOR_MASK 0xFFFF + +#define ZYNQMP_PM_VERSION \ + ((ZYNQMP_PM_VERSION_MAJOR << ZYNQMP_PM_VERSION_MAJOR_SHIFT) | \ + ZYNQMP_PM_VERSION_MINOR) + +#define ZYNQMP_PM_VERSION_INVALID ~0 + +#define PMUFW_V1_0 ((1 << ZYNQMP_PM_VERSION_MAJOR_SHIFT) | 0) + +enum { + IDCODE, + VERSION, + IDCODE2, +}; + +enum { + ZYNQMP_SILICON_V1, + ZYNQMP_SILICON_V2, + ZYNQMP_SILICON_V3, + ZYNQMP_SILICON_V4, +}; + +enum { + TCM_LOCK, + TCM_SPLIT, +}; + +int zynq_board_read_rom_ethaddr(unsigned char *ethaddr); +unsigned int zynqmp_get_silicon_version(void); + +void handoff_setup(void); + +unsigned int zynqmp_pmufw_version(void); +int zynqmp_mmio_write(const u32 address, const u32 mask, const u32 value); +int zynqmp_mmio_read(const u32 address, u32 *value); +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); +#if defined(CONFIG_SYS_MEM_RSVD_FOR_MMU) || defined(CONFIG_DEFINE_TCM_OCM_MMAP) +void tcm_init(u8 mode); +#endif + +#endif /* _ASM_ARCH_SYS_PROTO_H */ diff --git a/arch/arm/mach-zynqmp/mp.c b/arch/arm/mach-zynqmp/mp.c new file mode 100644 index 00000000000..2a71870ae7b --- /dev/null +++ b/arch/arm/mach-zynqmp/mp.c @@ -0,0 +1,297 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2014 - 2015 Xilinx, Inc. + * Michal Simek + */ + +#include +#include +#include +#include + +#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(u32 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 propagate */ + udelay(0x500); +} + +int cpu_disable(u32 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(u32 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); +} + +static void write_tcm_boot_trampoline(u32 boot_addr) +{ + if (boot_addr) { + /* + * Boot trampoline is simple ASM code below. + * + * b over; + * label: + * .word 0 + * over: ldr r0, =label + * ldr r1, [r0] + * bx r1 + */ + debug("Write boot trampoline for %x\n", boot_addr); + writel(0xea000000, ZYNQMP_TCM_START_ADDRESS); + writel(boot_addr, ZYNQMP_TCM_START_ADDRESS + 0x4); + writel(0xe59f0004, ZYNQMP_TCM_START_ADDRESS + 0x8); + writel(0xe5901000, ZYNQMP_TCM_START_ADDRESS + 0xc); + writel(0xe12fff11, ZYNQMP_TCM_START_ADDRESS + 0x10); + writel(0x00000004, ZYNQMP_TCM_START_ADDRESS + 0x14); // address for + } +} + +void initialize_tcm(bool mode) +{ + if (!mode) { + set_r5_tcm_mode(LOCK); + set_r5_halt_mode(HALT, LOCK); + enable_clock_r5(); + release_r5_reset(LOCK); + } else { + set_r5_tcm_mode(SPLIT); + set_r5_halt_mode(HALT, SPLIT); + enable_clock_r5(); + release_r5_reset(SPLIT); + } +} + +int cpu_release(u32 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(" -Start addr lockstep or split\n"); + return 1; + } + + u32 boot_addr = simple_strtoul(argv[0], NULL, 16); + u32 boot_addr_uniq = 0; + if (!(boot_addr == ZYNQMP_R5_LOVEC_ADDR || + boot_addr == ZYNQMP_R5_HIVEC_ADDR)) { + printf("Using TCM jump trampoline for address 0x%x\n", + boot_addr); + /* Save boot address for later usage */ + boot_addr_uniq = boot_addr; + /* + * R5 needs to start from LOVEC at TCM + * OCM will be probably occupied by ATF + */ + boot_addr = ZYNQMP_R5_LOVEC_ADDR; + } + + /* + * Since we don't know where the user may have loaded the image + * for an R5 we have to flush all the data cache to ensure + * the R5 sees it. + */ + flush_dcache_all(); + + if (!strncmp(argv[1], "lockstep", 8)) { + printf("R5 lockstep mode\n"); + set_r5_reset(LOCK); + set_r5_tcm_mode(LOCK); + set_r5_halt_mode(HALT, LOCK); + set_r5_start(boot_addr); + enable_clock_r5(); + release_r5_reset(LOCK); + dcache_disable(); + write_tcm_boot_trampoline(boot_addr_uniq); + dcache_enable(); + set_r5_halt_mode(RELEASE, LOCK); + } else if (!strncmp(argv[1], "split", 5)) { + printf("R5 split mode\n"); + set_r5_reset(SPLIT); + set_r5_tcm_mode(SPLIT); + set_r5_halt_mode(HALT, SPLIT); + set_r5_start(boot_addr); + enable_clock_r5(); + release_r5_reset(SPLIT); + dcache_disable(); + write_tcm_boot_trampoline(boot_addr_uniq); + dcache_enable(); + set_r5_halt_mode(RELEASE, SPLIT); + } else { + printf("Unsupported mode\n"); + return 1; + } + } + + return 0; +} diff --git a/arch/arm/mach-zynqmp/psu_spl_init.c b/arch/arm/mach-zynqmp/psu_spl_init.c new file mode 100644 index 00000000000..b357de32358 --- /dev/null +++ b/arch/arm/mach-zynqmp/psu_spl_init.c @@ -0,0 +1,79 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2018 Xilinx, Inc. + * + * Michal Simek + */ +#include +#include +#include + +#define PSU_MASK_POLL_TIME 1100000 + +int __maybe_unused mask_pollonvalue(unsigned long add, u32 mask, u32 value) +{ + int i = 0; + + while ((__raw_readl(add) & mask) != value) { + if (i == PSU_MASK_POLL_TIME) + return 0; + i++; + } + return 1; +} + +__weak int mask_poll(u32 add, u32 mask) +{ + int i = 0; + unsigned long addr = add; + + while (!(__raw_readl(addr) & mask)) { + if (i == PSU_MASK_POLL_TIME) + return 0; + i++; + } + return 1; +} + +__weak u32 mask_read(u32 add, u32 mask) +{ + unsigned long addr = add; + + return __raw_readl(addr) & mask; +} + +__weak void mask_delay(u32 delay) +{ + udelay(delay); +} + +__weak void psu_mask_write(unsigned long offset, unsigned long mask, + unsigned long val) +{ + unsigned long regval = 0; + + regval = readl(offset); + regval &= ~(mask); + regval |= (val & mask); + writel(regval, offset); +} + +__weak void prog_reg(unsigned long addr, unsigned long mask, + unsigned long shift, unsigned long value) +{ + int rdata = 0; + + rdata = readl(addr); + rdata = rdata & (~mask); + rdata = rdata | (value << shift); + writel(rdata, addr); +} + +__weak int psu_init(void) +{ + /* + * This function is overridden by the one in + * board/xilinx/zynqmp/(platform)/psu_init_gpl.c, if it exists. + */ + return -1; +} diff --git a/arch/arm/mach-zynqmp/spl.c b/arch/arm/mach-zynqmp/spl.c new file mode 100644 index 00000000000..01f31d0f0ed --- /dev/null +++ b/arch/arm/mach-zynqmp/spl.c @@ -0,0 +1,134 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2015 - 2016 Xilinx, Inc. + * + * Michal Simek + */ + +#include +#include +#include + +#include +#include +#include +#include + +void board_init_f(ulong dummy) +{ + board_early_init_f(); + board_early_init_r(); + +#ifdef CONFIG_DEBUG_UART + /* Uart debug for sure */ + debug_uart_init(); + puts("Debug uart enabled\n"); /* or printch() */ +#endif + /* Delay is required for clocks to be propagated */ + udelay(1000000); + + /* Clear the BSS */ + memset(__bss_start, 0, __bss_end - __bss_start); + + /* No need to call timer init - it is empty for ZynqMP */ + board_init_r(NULL, 0); +} + +static void ps_mode_reset(ulong mode) +{ + writel(mode << ZYNQMP_CRL_APB_BOOT_PIN_CTRL_OUT_EN_SHIFT, + &crlapb_base->boot_pin_ctrl); + udelay(5); + writel(mode << ZYNQMP_CRL_APB_BOOT_PIN_CTRL_OUT_VAL_SHIFT | + mode << ZYNQMP_CRL_APB_BOOT_PIN_CTRL_OUT_EN_SHIFT, + &crlapb_base->boot_pin_ctrl); +} + +/* + * Set default PS_MODE1 which is used for USB ULPI phy reset + * Also other resets can be connected to this certain pin + */ +#ifndef MODE_RESET +# define MODE_RESET PS_MODE1 +#endif + +#ifdef CONFIG_SPL_BOARD_INIT +void spl_board_init(void) +{ + preloader_console_init(); + ps_mode_reset(MODE_RESET); + board_init(); +} +#endif + +u32 spl_boot_device(void) +{ + u32 reg = 0; + u8 bootmode; + +#if defined(CONFIG_SPL_ZYNQMP_ALT_BOOTMODE_ENABLED) + /* Change default boot mode at run-time */ + writel(CONFIG_SPL_ZYNQMP_ALT_BOOTMODE << BOOT_MODE_ALT_SHIFT, + &crlapb_base->boot_mode); +#endif + + reg = readl(&crlapb_base->boot_mode); + if (reg >> BOOT_MODE_ALT_SHIFT) + reg >>= BOOT_MODE_ALT_SHIFT; + + bootmode = reg & BOOT_MODES_MASK; + + switch (bootmode) { + case JTAG_MODE: + return BOOT_DEVICE_RAM; +#ifdef CONFIG_SPL_MMC_SUPPORT + case SD_MODE1: + case SD1_LSHFT_MODE: /* not working on silicon v1 */ +/* if both controllers enabled, then these two are the second controller */ +#if defined(CONFIG_ZYNQ_SDHCI0) && defined(CONFIG_ZYNQ_SDHCI1) + return BOOT_DEVICE_MMC2; +/* else, fall through, the one SDHCI controller that is enabled is number 1 */ +#endif + case SD_MODE: + case EMMC_MODE: + return BOOT_DEVICE_MMC1; +#endif +#ifdef CONFIG_SPL_DFU_SUPPORT + case USB_MODE: + return BOOT_DEVICE_DFU; +#endif +#ifdef CONFIG_SPL_SATA_SUPPORT + case SW_SATA_MODE: + return BOOT_DEVICE_SATA; +#endif +#ifdef CONFIG_SPL_SPI_SUPPORT + case QSPI_MODE_24BIT: + case QSPI_MODE_32BIT: + return BOOT_DEVICE_SPI; +#endif + default: + printf("Invalid Boot Mode:0x%x\n", bootmode); + break; + } + + return 0; +} + +#ifdef CONFIG_SPL_OS_BOOT +int spl_start_uboot(void) +{ + handoff_setup(); + + return 0; +} +#endif + +#ifdef CONFIG_SPL_LOAD_FIT +int board_fit_config_name_match(const char *name) +{ + /* Just empty function now - can't decide what to choose */ + debug("%s: %s\n", __func__, name); + + return 0; +} +#endif -- cgit v1.2.3 From 5820590309dff693115e6fb0800115067a1be46e Mon Sep 17 00:00:00 2001 From: Mike Looijmans Date: Fri, 18 Jan 2019 09:02:47 +0100 Subject: topic-miamiplus: Run CPU at 800MHz for speedgrade-2 The miamiplus contains a speedgrade-2 device, which may run the CPU at 800MHz. Change the PLL setting to 800MHz, and adapt the setpoints in the devicetree. Signed-off-by: Mike Looijmans Signed-off-by: Michal Simek --- arch/arm/dts/zynq-topic-miamiplus.dts | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'arch') diff --git a/arch/arm/dts/zynq-topic-miamiplus.dts b/arch/arm/dts/zynq-topic-miamiplus.dts index c0ccea90a18..df538865296 100644 --- a/arch/arm/dts/zynq-topic-miamiplus.dts +++ b/arch/arm/dts/zynq-topic-miamiplus.dts @@ -11,6 +11,15 @@ compatible = "topic,miamiplus", "xlnx,zynq-7000"; }; +/* The miamiplus contains a speedgrade-2 device and runs at 800MHz */ +&cpu0 { + operating-points = < + /* kHz uV */ + 800000 1000000 + 400000 1000000 + >; +}; + &qspi { is-dual = <1>; }; -- cgit v1.2.3 From 8a2607020c97095d39e260372b28ea5e13bbc977 Mon Sep 17 00:00:00 2001 From: Anton Gerasimov Date: Mon, 24 Dec 2018 02:29:04 +0100 Subject: zynq: Kconfig: extend the bootstrap malloc() pool Most of the memory is being consumed by device binding code, more space needed for other data structures. Z-turn board has already hit the limit, others may follow soon. Measuring only the memory consumed in device_bind_common, I've got the following results (in decimal): root_driver: 108 mod_exp_sw: 108 amba: 120 serial@e0000000 aka uart0: 112 serial@e0001000 aka uart1: 88 spi@e000d000 aka qspi: 120 sdhci@e0100000 aka mmc0: 455 sdhci@e0100000.blk: 208 slcr@f8000000: 96 clkc@100: 72 (total) 1487 = 0x5cf of 0x600 Signed-off-by: Anton Gerasimov Signed-off-by: Michal Simek --- arch/arm/mach-zynq/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch') diff --git a/arch/arm/mach-zynq/Kconfig b/arch/arm/mach-zynq/Kconfig index a599ed63ee4..21dfebf5c0b 100644 --- a/arch/arm/mach-zynq/Kconfig +++ b/arch/arm/mach-zynq/Kconfig @@ -55,7 +55,7 @@ config SYS_CONFIG_NAME will be used for board configuration. config SYS_MALLOC_F_LEN - default 0x600 + default 0x800 config SYS_MALLOC_LEN default 0x1400000 -- cgit v1.2.3 From 73d52b066a806cebd451e09d46d73b45eb0035fd Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Tue, 22 Jan 2019 13:15:01 +0100 Subject: arm64: zynqmp: Remove unused GEM addresses With DM in place there is no need to have GEM addresses in headers. None is using them. Signed-off-by: Michal Simek --- arch/arm/mach-zynqmp/include/mach/hardware.h | 5 ----- 1 file changed, 5 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-zynqmp/include/mach/hardware.h b/arch/arm/mach-zynqmp/include/mach/hardware.h index 8a505edab3c..efb4bba4b8c 100644 --- a/arch/arm/mach-zynqmp/include/mach/hardware.h +++ b/arch/arm/mach-zynqmp/include/mach/hardware.h @@ -7,11 +7,6 @@ #ifndef _ASM_ARCH_HARDWARE_H #define _ASM_ARCH_HARDWARE_H -#define ZYNQ_GEM_BASEADDR0 0xFF0B0000 -#define ZYNQ_GEM_BASEADDR1 0xFF0C0000 -#define ZYNQ_GEM_BASEADDR2 0xFF0D0000 -#define ZYNQ_GEM_BASEADDR3 0xFF0E0000 - #define ZYNQ_I2C_BASEADDR0 0xFF020000 #define ZYNQ_I2C_BASEADDR1 0xFF030000 -- cgit v1.2.3 From 2e530511facd7b98834252a2f563421f3e626d1f Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Tue, 22 Jan 2019 13:15:46 +0100 Subject: ARM: zynq: Remove unused GEM addresses With DM in place there is no need to have GEM addresses in headers. None is using them. Signed-off-by: Michal Simek --- arch/arm/mach-zynq/include/mach/hardware.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'arch') diff --git a/arch/arm/mach-zynq/include/mach/hardware.h b/arch/arm/mach-zynq/include/mach/hardware.h index 3ff3c1073e2..58b6f95395a 100644 --- a/arch/arm/mach-zynq/include/mach/hardware.h +++ b/arch/arm/mach-zynq/include/mach/hardware.h @@ -9,8 +9,6 @@ #define ZYNQ_SYS_CTRL_BASEADDR 0xF8000000 #define ZYNQ_DEV_CFG_APB_BASEADDR 0xF8007000 #define ZYNQ_SCU_BASEADDR 0xF8F00000 -#define ZYNQ_GEM_BASEADDR0 0xE000B000 -#define ZYNQ_GEM_BASEADDR1 0xE000C000 #define ZYNQ_I2C_BASEADDR0 0xE0004000 #define ZYNQ_I2C_BASEADDR1 0xE0005000 #define ZYNQ_QSPI_BASEADDR 0xE000D000 -- cgit v1.2.3