From: Michal Simek Date: Thu, 17 Jan 2019 07:22:43 +0000 (+0100) Subject: arm64: zynqmp: Move SoC sources to mach-zynqmp X-Git-Tag: v2019.04-rc1~28^2~10 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=274ccb5b1175e1d87a5b2eaf2f82826b079382b5;p=oweals%2Fu-boot.git 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 --- diff --git a/MAINTAINERS b/MAINTAINERS index 1cb092e539..ecac867950 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -362,7 +362,7 @@ ARM ZYNQMP M: Michal Simek S: Maintained T: git git://git.denx.de/u-boot-microblaze.git -F: arch/arm/cpu/armv8/zynqmp/ +F: arch/arm/mach-zynqmp/ F: drivers/clk/clk_zynqmp.c F: drivers/fpga/zynqpl.c F: drivers/gpio/zynq_gpio.c diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index a65e0c5211..2298e6e7d7 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 87d9d4b9f7..817302523a 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 52c8daa049..4c4b13c9e7 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 8a311e1c89..0000000000 --- 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 8a3b074724..0000000000 --- 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 0593b6310f..0000000000 --- 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 5ef1a52862..0000000000 --- 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 f71ff7b3d2..0000000000 --- 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 2a71870ae7..0000000000 --- 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 b357de3235..0000000000 --- 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 01f31d0f0e..0000000000 --- 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 cfd44c8e0f..0000000000 --- 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 542a5fc3e9..0000000000 --- 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 8a505edab3..0000000000 --- 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 15e54c0493..0000000000 --- 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 385c8825f2..0000000000 --- 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 f8b93fe458..a75ba1ffdb 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 702fde1dea..d45b1faaa2 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 0000000000..8a311e1c89 --- /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 0000000000..8a3b074724 --- /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 0000000000..0593b6310f --- /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 0000000000..5ef1a52862 --- /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 0000000000..f71ff7b3d2 --- /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 0000000000..cfd44c8e0f --- /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 0000000000..542a5fc3e9 --- /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 0000000000..8a505edab3 --- /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 0000000000..15e54c0493 --- /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 0000000000..385c8825f2 --- /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 0000000000..2a71870ae7 --- /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 0000000000..b357de3235 --- /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 0000000000..01f31d0f0e --- /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