diff options
Diffstat (limited to 'arch/arm/mach-zynqmp')
-rw-r--r-- | arch/arm/mach-zynqmp/Kconfig | 35 | ||||
-rw-r--r-- | arch/arm/mach-zynqmp/Makefile | 1 | ||||
-rw-r--r-- | arch/arm/mach-zynqmp/ecc_spl_init.c | 163 | ||||
-rw-r--r-- | arch/arm/mach-zynqmp/handoff.c | 19 | ||||
-rw-r--r-- | arch/arm/mach-zynqmp/include/mach/ecc_spl_init.h | 13 | ||||
-rw-r--r-- | arch/arm/mach-zynqmp/include/mach/hardware.h | 2 | ||||
-rwxr-xr-x | arch/arm/mach-zynqmp/mkimage_fit_atf.sh | 59 | ||||
-rw-r--r-- | arch/arm/mach-zynqmp/mp.c | 70 | ||||
-rw-r--r-- | arch/arm/mach-zynqmp/spl.c | 4 |
9 files changed, 324 insertions, 42 deletions
diff --git a/arch/arm/mach-zynqmp/Kconfig b/arch/arm/mach-zynqmp/Kconfig index f1301f6661a..39144d654e3 100644 --- a/arch/arm/mach-zynqmp/Kconfig +++ b/arch/arm/mach-zynqmp/Kconfig @@ -92,6 +92,41 @@ config ZYNQMP_NO_DDR This option configures MMU with no DDR to avoid speculative access to DDR memory where DDR is not present. +config SPL_ZYNQMP_DRAM_ECC_INIT + bool "Initialize DRAM ECC" + depends on SPL + help + This option initializes all memory to 0xdeadbeef. Must be set if your + memory is of ECC type. + +config SPL_ZYNQMP_DRAM_BANK1_BASE + depends on SPL_ZYNQMP_DRAM_ECC_INIT + hex "DRAM Bank1 address" + default 0x00000000 + help + Start address of DRAM ECC bank1 + +config SPL_ZYNQMP_DRAM_BANK1_LEN + depends on SPL_ZYNQMP_DRAM_ECC_INIT + hex "DRAM Bank1 size" + default 0x80000000 + help + Size in bytes of the DRAM ECC bank1 + +config SPL_ZYNQMP_DRAM_BANK2_BASE + depends on SPL_ZYNQMP_DRAM_ECC_INIT + hex "DRAM Bank2 address" + default 0x800000000 + help + Start address of DRAM ECC bank2 + +config SPL_ZYNQMP_DRAM_BANK2_LEN + depends on SPL_ZYNQMP_DRAM_ECC_INIT + hex "DRAM Bank2 size" + default 0x0 + help + Size in bytes of the DRAM ECC bank2. A null size takes no action. + config SYS_MALLOC_F_LEN default 0x600 diff --git a/arch/arm/mach-zynqmp/Makefile b/arch/arm/mach-zynqmp/Makefile index 8a3b0747244..eb6c5112b37 100644 --- a/arch/arm/mach-zynqmp/Makefile +++ b/arch/arm/mach-zynqmp/Makefile @@ -7,4 +7,5 @@ obj-y += clk.o obj-y += cpu.o obj-$(CONFIG_MP) += mp.o obj-$(CONFIG_SPL_BUILD) += spl.o handoff.o +obj-$(CONFIG_SPL_ZYNQMP_DRAM_ECC_INIT) += ecc_spl_init.o obj-$(CONFIG_ZYNQMP_PSU_INIT_ENABLED) += psu_spl_init.o diff --git a/arch/arm/mach-zynqmp/ecc_spl_init.c b/arch/arm/mach-zynqmp/ecc_spl_init.c new file mode 100644 index 00000000000..f547d8e3a5b --- /dev/null +++ b/arch/arm/mach-zynqmp/ecc_spl_init.c @@ -0,0 +1,163 @@ +// SPDX-License-Identifier: MIT +/* + * Copyright(c) 2015 - 2020 Xilinx, Inc. + * + * Jorge Ramirez-Ortiz <jorge@foundries.io> + */ + +#include <common.h> +#include <cpu_func.h> +#include <asm/arch/hardware.h> +#include <asm/arch/ecc_spl_init.h> +#include <asm/io.h> +#include <linux/delay.h> + +#define ZDMA_TRANSFER_MAX_LEN (0x3FFFFFFFU - 7U) +#define ZDMA_CH_STATUS ((ADMA_CH0_BASEADDR) + 0x0000011CU) +#define ZDMA_CH_STATUS_STATE_MASK 0x00000003U +#define ZDMA_CH_STATUS_STATE_DONE 0x00000000U +#define ZDMA_CH_STATUS_STATE_ERR 0x00000003U +#define ZDMA_CH_CTRL0 ((ADMA_CH0_BASEADDR) + 0x00000110U) +#define ZDMA_CH_CTRL0_POINT_TYPE_MASK (u32)0x00000040U +#define ZDMA_CH_CTRL0_POINT_TYPE_NORMAL (u32)0x00000000U +#define ZDMA_CH_CTRL0_MODE_MASK (u32)0x00000030U +#define ZDMA_CH_CTRL0_MODE_WR_ONLY (u32)0x00000010U +#define ZDMA_CH_CTRL0_TOTAL_BYTE_COUNT ((ADMA_CH0_BASEADDR) + 0x00000188U) +#define ZDMA_CH_WR_ONLY_WORD0 ((ADMA_CH0_BASEADDR) + 0x00000148U) +#define ZDMA_CH_WR_ONLY_WORD1 ((ADMA_CH0_BASEADDR) + 0x0000014CU) +#define ZDMA_CH_WR_ONLY_WORD2 ((ADMA_CH0_BASEADDR) + 0x00000150U) +#define ZDMA_CH_WR_ONLY_WORD3 ((ADMA_CH0_BASEADDR) + 0x00000154U) +#define ZDMA_CH_DST_DSCR_WORD0 ((ADMA_CH0_BASEADDR) + 0x00000138U) +#define ZDMA_CH_DST_DSCR_WORD0_LSB_MASK 0xFFFFFFFFU +#define ZDMA_CH_DST_DSCR_WORD1 ((ADMA_CH0_BASEADDR) + 0x0000013CU) +#define ZDMA_CH_DST_DSCR_WORD1_MSB_MASK 0x0001FFFFU +#define ZDMA_CH_SRC_DSCR_WORD2 ((ADMA_CH0_BASEADDR) + 0x00000130U) +#define ZDMA_CH_DST_DSCR_WORD2 ((ADMA_CH0_BASEADDR) + 0x00000140U) +#define ZDMA_CH_CTRL2 ((ADMA_CH0_BASEADDR) + 0x00000200U) +#define ZDMA_CH_CTRL2_EN_MASK 0x00000001U +#define ZDMA_CH_ISR ((ADMA_CH0_BASEADDR) + 0x00000100U) +#define ZDMA_CH_ISR_DMA_DONE_MASK 0x00000400U +#define ECC_INIT_VAL_WORD 0xDEADBEEFU + +#define ZDMA_IDLE_TIMEOUT_USEC 1000000 +#define ZDMA_DONE_TIMEOUT_USEC 5000000 + +static void ecc_zdma_restore(void) +{ + /* Restore reset values for the DMA registers used */ + writel(ZDMA_CH_CTRL0, 0x00000080U); + writel(ZDMA_CH_WR_ONLY_WORD0, 0x00000000U); + writel(ZDMA_CH_WR_ONLY_WORD1, 0x00000000U); + writel(ZDMA_CH_WR_ONLY_WORD2, 0x00000000U); + writel(ZDMA_CH_WR_ONLY_WORD3, 0x00000000U); + writel(ZDMA_CH_DST_DSCR_WORD0, 0x00000000U); + writel(ZDMA_CH_DST_DSCR_WORD1, 0x00000000U); + writel(ZDMA_CH_SRC_DSCR_WORD2, 0x00000000U); + writel(ZDMA_CH_DST_DSCR_WORD2, 0x00000000U); + writel(ZDMA_CH_CTRL0_TOTAL_BYTE_COUNT, 0x00000000U); +} + +static void ecc_dram_bank_init(u64 addr, u64 len) +{ + bool retry = true; + u32 timeout; + u64 bytes; + u32 size; + u64 src; + u32 reg; + + if (!len) + return; +retry: + bytes = len; + src = addr; + ecc_zdma_restore(); + while (bytes > 0) { + size = bytes > ZDMA_TRANSFER_MAX_LEN ? + ZDMA_TRANSFER_MAX_LEN : (u32)bytes; + + /* Wait until the DMA is in idle state */ + timeout = ZDMA_IDLE_TIMEOUT_USEC; + do { + udelay(1); + reg = readl(ZDMA_CH_STATUS); + reg &= ZDMA_CH_STATUS_STATE_MASK; + if (!timeout--) { + puts("error, ECC DMA failed to idle\n"); + goto done; + } + + } while ((reg != ZDMA_CH_STATUS_STATE_DONE) && + (reg != ZDMA_CH_STATUS_STATE_ERR)); + + /* Enable Simple (Write Only) Mode */ + reg = readl(ZDMA_CH_CTRL0); + reg &= (ZDMA_CH_CTRL0_POINT_TYPE_MASK | + ZDMA_CH_CTRL0_MODE_MASK); + reg |= (ZDMA_CH_CTRL0_POINT_TYPE_NORMAL | + ZDMA_CH_CTRL0_MODE_WR_ONLY); + writel(reg, ZDMA_CH_CTRL0); + + /* Fill in the data to be written */ + writel(ECC_INIT_VAL_WORD, ZDMA_CH_WR_ONLY_WORD0); + writel(ECC_INIT_VAL_WORD, ZDMA_CH_WR_ONLY_WORD1); + writel(ECC_INIT_VAL_WORD, ZDMA_CH_WR_ONLY_WORD2); + writel(ECC_INIT_VAL_WORD, ZDMA_CH_WR_ONLY_WORD3); + + /* Write Destination Address */ + writel((u32)(src & ZDMA_CH_DST_DSCR_WORD0_LSB_MASK), + ZDMA_CH_DST_DSCR_WORD0); + writel((u32)((src >> 32) & ZDMA_CH_DST_DSCR_WORD1_MSB_MASK), + ZDMA_CH_DST_DSCR_WORD1); + + /* Size to be Transferred. Recommended to set both src and dest sizes */ + writel(size, ZDMA_CH_SRC_DSCR_WORD2); + writel(size, ZDMA_CH_DST_DSCR_WORD2); + + /* DMA Enable */ + reg = readl(ZDMA_CH_CTRL2); + reg |= ZDMA_CH_CTRL2_EN_MASK; + writel(reg, ZDMA_CH_CTRL2); + + /* Check the status of the transfer by polling on DMA Done */ + timeout = ZDMA_DONE_TIMEOUT_USEC; + do { + udelay(1); + reg = readl(ZDMA_CH_ISR); + reg &= ZDMA_CH_ISR_DMA_DONE_MASK; + if (!timeout--) { + puts("error, ECC DMA timeout\n"); + goto done; + } + } while (reg != ZDMA_CH_ISR_DMA_DONE_MASK); + + /* Clear DMA status */ + reg = readl(ZDMA_CH_ISR); + reg |= ZDMA_CH_ISR_DMA_DONE_MASK; + writel(ZDMA_CH_ISR_DMA_DONE_MASK, ZDMA_CH_ISR); + + /* Read the channel status for errors */ + reg = readl(ZDMA_CH_STATUS); + if (reg == ZDMA_CH_STATUS_STATE_ERR) { + if (retry) { + retry = false; + goto retry; + } + puts("error, ECC DMA error\n"); + break; + } + + bytes -= size; + src += size; + } +done: + ecc_zdma_restore(); +} + +void zynqmp_ecc_init(void) +{ + ecc_dram_bank_init(CONFIG_SPL_ZYNQMP_DRAM_BANK1_BASE, + CONFIG_SPL_ZYNQMP_DRAM_BANK1_LEN); + ecc_dram_bank_init(CONFIG_SPL_ZYNQMP_DRAM_BANK2_BASE, + CONFIG_SPL_ZYNQMP_DRAM_BANK2_LEN); +} diff --git a/arch/arm/mach-zynqmp/handoff.c b/arch/arm/mach-zynqmp/handoff.c index 7d7ab9da6ec..31346d9b2e2 100644 --- a/arch/arm/mach-zynqmp/handoff.c +++ b/arch/arm/mach-zynqmp/handoff.c @@ -71,6 +71,7 @@ struct bl31_params *bl2_plat_get_bl31_params(uintptr_t bl32_entry, uintptr_t fdt_addr) { struct xfsbl_atf_handoff_params *atfhandoffparams; + u32 index = 0; atfhandoffparams = (void *)CONFIG_SPL_TEXT_BASE; atfhandoffparams->magic[0] = 'X'; @@ -78,14 +79,22 @@ struct bl31_params *bl2_plat_get_bl31_params(uintptr_t bl32_entry, atfhandoffparams->magic[2] = 'N'; atfhandoffparams->magic[3] = 'X'; - atfhandoffparams->num_entries = 0; + if (bl32_entry) { + atfhandoffparams->partition[index].entry_point = bl32_entry; + atfhandoffparams->partition[index].flags = FSBL_FLAGS_EL1 << FSBL_FLAGS_EL_SHIFT | + FSBL_FLAGS_SECURE << FSBL_FLAGS_TZ_SHIFT; + index++; + } + if (bl33_entry) { - atfhandoffparams->partition[0].entry_point = bl33_entry; - atfhandoffparams->partition[0].flags = FSBL_FLAGS_EL2 << - FSBL_FLAGS_EL_SHIFT; - atfhandoffparams->num_entries++; + atfhandoffparams->partition[index].entry_point = bl33_entry; + atfhandoffparams->partition[index].flags = FSBL_FLAGS_EL2 << + FSBL_FLAGS_EL_SHIFT; + index++; } + atfhandoffparams->num_entries = index; + writel(CONFIG_SPL_TEXT_BASE, &pmu_base->gen_storage6); return NULL; diff --git a/arch/arm/mach-zynqmp/include/mach/ecc_spl_init.h b/arch/arm/mach-zynqmp/include/mach/ecc_spl_init.h new file mode 100644 index 00000000000..b4b6fcf53bc --- /dev/null +++ b/arch/arm/mach-zynqmp/include/mach/ecc_spl_init.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright(c) 2015 - 2020 Xilinx, Inc. + * + * Jorge Ramirez-Ortiz <jorge@foundries.io> + */ + +#ifndef __ARCH_ZYNQMP_ECC_INIT_H +#define __ARCH_ZYNQMP_ECC_INIT_H + +void zynqmp_ecc_init(void); + +#endif diff --git a/arch/arm/mach-zynqmp/include/mach/hardware.h b/arch/arm/mach-zynqmp/include/mach/hardware.h index a798aa0eb99..37764990707 100644 --- a/arch/arm/mach-zynqmp/include/mach/hardware.h +++ b/arch/arm/mach-zynqmp/include/mach/hardware.h @@ -24,6 +24,8 @@ + 0x00000114) #define ZYNQMP_PS_SYSMON_ANALOG_BUS_VAL 0x00003210 +#define ADMA_CH0_BASEADDR 0xFFA80000 + #define PS_MODE0 BIT(0) #define PS_MODE1 BIT(1) #define PS_MODE2 BIT(2) diff --git a/arch/arm/mach-zynqmp/mkimage_fit_atf.sh b/arch/arm/mach-zynqmp/mkimage_fit_atf.sh index 92e31849f88..592be7f6706 100755 --- a/arch/arm/mach-zynqmp/mkimage_fit_atf.sh +++ b/arch/arm/mach-zynqmp/mkimage_fit_atf.sh @@ -8,16 +8,34 @@ BL33="u-boot-nodtb.bin" [ -z "$BL31" ] && BL31="bl31.bin" -# Can be also done as ${CROSS_COMPILE}readelf -l bl31.elf | awk '/Entry point/ { print $3 }' +BL31_ELF="${BL31%.*}.elf" +[ -f ${BL31_ELF} ] && ATF_LOAD_ADDR=`${CROSS_COMPILE}readelf -l "${BL31_ELF}" | \ +awk '/Entry point/ { print $3 }'` + [ -z "$ATF_LOAD_ADDR" ] && ATF_LOAD_ADDR="0xfffea000" +ATF_LOAD_ADDR_LOW=`printf 0x%x $((ATF_LOAD_ADDR & 0xffffffff))` +ATF_LOAD_ADDR_HIGH=`printf 0x%x $((ATF_LOAD_ADDR >> 32))` + +[ -z "$BL32" ] && BL32="tee.bin" +BL32_ELF="${BL32%.*}.elf" +[ -f ${BL32_ELF} ] && TEE_LOAD_ADDR=`${CROSS_COMPILE}readelf -l "${BL32_ELF}" | \ +awk '/Entry point/ { print $3 }'` + +[ -z "$TEE_LOAD_ADDR" ] && TEE_LOAD_ADDR="0x60000000" +TEE_LOAD_ADDR_LOW=`printf 0x%x $((TEE_LOAD_ADDR & 0xffffffff))` +TEE_LOAD_ADDR_HIGH=`printf 0x%x $((TEE_LOAD_ADDR >> 32))` if [ -z "$BL33_LOAD_ADDR" ];then BL33_LOAD_ADDR=`awk '/CONFIG_SYS_TEXT_BASE/ { print $3 }' include/generated/autoconf.h` fi +BL33_LOAD_ADDR_LOW=`printf 0x%x $((BL33_LOAD_ADDR & 0xffffffff))` +BL33_LOAD_ADDR_HIGH=`printf 0x%x $((BL33_LOAD_ADDR >> 32))` DTB_LOAD_ADDR=`awk '/CONFIG_XILINX_OF_BOARD_DTB_ADDR/ { print $3 }' include/generated/autoconf.h` if [ ! -z "$DTB_LOAD_ADDR" ]; then - DTB_LOAD="load = <$DTB_LOAD_ADDR>;" + DTB_LOAD_ADDR_LOW=`printf 0x%x $((DTB_LOAD_ADDR & 0xffffffff))` + DTB_LOAD_ADDR_HIGH=`printf 0x%x $((DTB_LOAD_ADDR >> 32))` + DTB_LOAD="load = <$DTB_LOAD_ADDR_HIGH $DTB_LOAD_ADDR_LOW>;" else DTB_LOAD="" fi @@ -49,8 +67,8 @@ cat << __HEADER_EOF os = "u-boot"; arch = "arm64"; compression = "none"; - load = <$BL33_LOAD_ADDR>; - entry = <$BL33_LOAD_ADDR>; + load = <$BL33_LOAD_ADDR_HIGH $BL33_LOAD_ADDR_LOW>; + entry = <$BL33_LOAD_ADDR_HIGH $BL33_LOAD_ADDR_LOW>; hash { algo = "md5"; }; @@ -66,8 +84,8 @@ cat << __ATF os = "arm-trusted-firmware"; arch = "arm64"; compression = "none"; - load = <$ATF_LOAD_ADDR>; - entry = <$ATF_LOAD_ADDR>; + load = <$ATF_LOAD_ADDR_HIGH $ATF_LOAD_ADDR_LOW>; + entry = <$ATF_LOAD_ADDR_HIGH $ATF_LOAD_ADDR_LOW>; hash { algo = "md5"; }; @@ -75,6 +93,24 @@ cat << __ATF __ATF fi +if [ -f $BL32 ]; then +cat << __TEE + tee { + description = "TEE firmware"; + data = /incbin/("$BL32"); + type = "firmware"; + os = "tee"; + arch = "arm64"; + compression = "none"; + load = <$TEE_LOAD_ADDR_HIGH $TEE_LOAD_ADDR_LOW>; + entry = <$TEE_LOAD_ADDR_HIGH $TEE_LOAD_ADDR_LOW>; + hash { + algo = "md5"; + }; + }; +__TEE +fi + DEFAULT=1 cnt=1 for dtname in $DT @@ -117,6 +153,16 @@ cat << __CONF_SECTION1_EOF }; __CONF_SECTION1_EOF else +if [ -f $BL32 ]; then +cat << __CONF_SECTION1_EOF + config_$cnt { + description = "$(basename $dtname .dtb)"; + firmware = "atf"; + loadables = "uboot", "tee"; + fdt = "fdt_$cnt"; + }; +__CONF_SECTION1_EOF +else cat << __CONF_SECTION1_EOF config_$cnt { description = "$(basename $dtname .dtb)"; @@ -126,6 +172,7 @@ cat << __CONF_SECTION1_EOF }; __CONF_SECTION1_EOF fi +fi cnt=$((cnt+1)) done diff --git a/arch/arm/mach-zynqmp/mp.c b/arch/arm/mach-zynqmp/mp.c index 656678a1551..74783ae5a78 100644 --- a/arch/arm/mach-zynqmp/mp.c +++ b/arch/arm/mach-zynqmp/mp.c @@ -37,6 +37,8 @@ #define ZYNQMP_CORE_APU0 0 #define ZYNQMP_CORE_APU3 3 +#define ZYNQMP_CORE_RPU0 4 +#define ZYNQMP_CORE_RPU1 5 #define ZYNQMP_MAX_CORES 6 @@ -54,18 +56,20 @@ int cpu_reset(u32 nr) return 0; } -static void set_r5_halt_mode(u8 halt, u8 mode) +static void set_r5_halt_mode(u32 nr, 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 || nr == ZYNQMP_CORE_RPU0) { + 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) { + if (mode == LOCK || nr == ZYNQMP_CORE_RPU1) { tmp = readl(&rpu_base->rpu1_cfg); if (halt == HALT) tmp &= ~ZYNQMP_RPU_CFG_CPU_HALT_MASK; @@ -93,30 +97,34 @@ static void set_r5_tcm_mode(u8 mode) writel(tmp, &rpu_base->rpu_glbl_ctrl); } -static void set_r5_reset(u8 mode) +static void set_r5_reset(u32 nr, 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 || nr == ZYNQMP_CORE_RPU0) + 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; + if (mode == LOCK || nr == ZYNQMP_CORE_RPU1) + tmp |= (ZYNQMP_CRLAPB_RST_LPD_AMBA_RST_MASK | + ZYNQMP_CRLAPB_RST_LPD_R51_RST_MASK); writel(tmp, &crlapb_base->rst_lpd_top); } -static void release_r5_reset(u8 mode) +static void release_r5_reset(u32 nr, 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 || nr == ZYNQMP_CORE_RPU0) + 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; + if (mode == LOCK || nr == ZYNQMP_CORE_RPU1) + tmp &= ~(ZYNQMP_CRLAPB_RST_LPD_AMBA_RST_MASK | + ZYNQMP_CRLAPB_RST_LPD_R51_RST_MASK); writel(tmp, &crlapb_base->rst_lpd_top); } @@ -141,7 +149,7 @@ int cpu_disable(u32 nr) val |= 1 << nr; writel(val, &crfapb_base->rst_fpd_apu); } else { - set_r5_reset(LOCK); + set_r5_reset(nr, SPLIT); } return 0; @@ -212,14 +220,14 @@ void initialize_tcm(bool mode) { if (!mode) { set_r5_tcm_mode(LOCK); - set_r5_halt_mode(HALT, LOCK); + set_r5_halt_mode(ZYNQMP_CORE_RPU0, HALT, LOCK); enable_clock_r5(); - release_r5_reset(LOCK); + release_r5_reset(ZYNQMP_CORE_RPU0, LOCK); } else { set_r5_tcm_mode(SPLIT); - set_r5_halt_mode(HALT, SPLIT); + set_r5_halt_mode(ZYNQMP_CORE_RPU1, HALT, SPLIT); enable_clock_r5(); - release_r5_reset(SPLIT); + release_r5_reset(ZYNQMP_CORE_RPU1, SPLIT); } } @@ -268,28 +276,28 @@ int cpu_release(u32 nr, int argc, char *const argv[]) if (!strncmp(argv[1], "lockstep", 8)) { printf("R5 lockstep mode\n"); - set_r5_reset(LOCK); + set_r5_reset(nr, LOCK); set_r5_tcm_mode(LOCK); - set_r5_halt_mode(HALT, LOCK); + set_r5_halt_mode(nr, HALT, LOCK); set_r5_start(boot_addr); enable_clock_r5(); - release_r5_reset(LOCK); + release_r5_reset(nr, LOCK); dcache_disable(); write_tcm_boot_trampoline(boot_addr_uniq); dcache_enable(); - set_r5_halt_mode(RELEASE, LOCK); + set_r5_halt_mode(nr, RELEASE, LOCK); } else if (!strncmp(argv[1], "split", 5)) { printf("R5 split mode\n"); - set_r5_reset(SPLIT); + set_r5_reset(nr, SPLIT); set_r5_tcm_mode(SPLIT); - set_r5_halt_mode(HALT, SPLIT); + set_r5_halt_mode(nr, HALT, SPLIT); set_r5_start(boot_addr); enable_clock_r5(); - release_r5_reset(SPLIT); + release_r5_reset(nr, SPLIT); dcache_disable(); write_tcm_boot_trampoline(boot_addr_uniq); dcache_enable(); - set_r5_halt_mode(RELEASE, SPLIT); + set_r5_halt_mode(nr, RELEASE, SPLIT); } else { printf("Unsupported mode\n"); return 1; diff --git a/arch/arm/mach-zynqmp/spl.c b/arch/arm/mach-zynqmp/spl.c index 88386b23e5d..8fcae2c6a66 100644 --- a/arch/arm/mach-zynqmp/spl.c +++ b/arch/arm/mach-zynqmp/spl.c @@ -15,6 +15,7 @@ #include <asm/io.h> #include <asm/spl.h> #include <asm/arch/hardware.h> +#include <asm/arch/ecc_spl_init.h> #include <asm/arch/psu_init_gpl.h> #include <asm/arch/sys_proto.h> @@ -22,6 +23,9 @@ void board_init_f(ulong dummy) { board_early_init_f(); board_early_init_r(); +#ifdef CONFIG_SPL_ZYNQMP_DRAM_ECC_INIT + zynqmp_ecc_init(); +#endif } static void ps_mode_reset(ulong mode) |