From 3b4ee40f20eb7bb687a4429546fd3cd3073b90d2 Mon Sep 17 00:00:00 2001 From: Tien Fong Chee Date: Sun, 7 Nov 2021 23:08:55 +0800 Subject: arm: socfpga: arria10: Reset MPFE NoC after program periph / combined RBF This patch triggers warm reset to recover the MPFE NoC from corruption due to high frequency transient clock output from HPS EMIF IOPLL at VCO startup after peripheral RBF is programmed. Signed-off-by: Tien Fong Chee Signed-off-by: Sin Hui Kho Reviewed-by: Tien Fong Chee --- arch/arm/mach-socfpga/include/mach/misc.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'arch/arm/mach-socfpga/include/mach/misc.h') diff --git a/arch/arm/mach-socfpga/include/mach/misc.h b/arch/arm/mach-socfpga/include/mach/misc.h index 649d2f6ce2..74e8e2590f 100644 --- a/arch/arm/mach-socfpga/include/mach/misc.h +++ b/arch/arm/mach-socfpga/include/mach/misc.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0 */ /* - * Copyright (C) 2016-2017 Intel Corporation + * Copyright (C) 2016-2021 Intel Corporation */ #ifndef _SOCFPGA_MISC_H_ @@ -45,7 +45,10 @@ int is_fpga_config_ready(void); #endif void do_bridge_reset(int enable, unsigned int mask); +bool is_regular_boot_valid(void); +void set_regular_boot(unsigned int status); void socfpga_pl310_clear(void); void socfpga_get_managers_addr(void); +int qspi_flash_software_reset(void); #endif /* _SOCFPGA_MISC_H_ */ -- cgit v1.2.3 From 4720b83d2c711062cfb55f03591b8f12c897d7cb Mon Sep 17 00:00:00 2001 From: Tien Fong Chee Date: Sun, 7 Nov 2021 23:08:56 +0800 Subject: arm: socfpga: arria10: Enable double peripheral RBF configuration Double peripheral RBF configuration are needed on some devices or boards to stabilize the IO configuration system. Signed-off-by: Tien Fong Chee Signed-off-by: Sin Hui Kho Reviewed-by: Tien Fong Chee --- arch/arm/mach-socfpga/include/mach/misc.h | 2 ++ arch/arm/mach-socfpga/misc_arria10.c | 36 +++++++++++++++++++++++++++++++ arch/arm/mach-socfpga/spl_a10.c | 14 ++++++++++++ drivers/fpga/socfpga_arria10.c | 3 ++- 4 files changed, 54 insertions(+), 1 deletion(-) (limited to 'arch/arm/mach-socfpga/include/mach/misc.h') diff --git a/arch/arm/mach-socfpga/include/mach/misc.h b/arch/arm/mach-socfpga/include/mach/misc.h index 74e8e2590f..8460acb00d 100644 --- a/arch/arm/mach-socfpga/include/mach/misc.h +++ b/arch/arm/mach-socfpga/include/mach/misc.h @@ -45,7 +45,9 @@ int is_fpga_config_ready(void); #endif void do_bridge_reset(int enable, unsigned int mask); +void force_periph_program(unsigned int status); bool is_regular_boot_valid(void); +bool is_periph_program_force(void); void set_regular_boot(unsigned int status); void socfpga_pl310_clear(void); void socfpga_get_managers_addr(void); diff --git a/arch/arm/mach-socfpga/misc_arria10.c b/arch/arm/mach-socfpga/misc_arria10.c index 634e63ed42..0ed2adfd84 100644 --- a/arch/arm/mach-socfpga/misc_arria10.c +++ b/arch/arm/mach-socfpga/misc_arria10.c @@ -32,6 +32,7 @@ #define PINMUX_UART1_TX_SHARED_IO_OFFSET_Q4_3 0x98 #define REGULAR_BOOT_MAGIC 0xd15ea5e +#define PERIPH_RBF_PROG_FORCE 0x50455249 #define QSPI_S25FL_SOFT_RESET_COMMAND 0x00f0ff82 #define QSPI_N25_SOFT_RESET_COMMAND 0x00000001 @@ -131,6 +132,41 @@ void do_bridge_reset(int enable, unsigned int mask) socfpga_bridges_reset(); } +/* + * This function set/unset flag with number "0x50455249" to + * handoff register isw_handoff[7] - 0xffd0624c + * This flag is used to force periph RBF program regardless FPGA status + * and double periph RBF config are needed on some devices or boards to + * stabilize the IO config system. + */ +void force_periph_program(unsigned int status) +{ + if (status) + writel(PERIPH_RBF_PROG_FORCE, socfpga_get_sysmgr_addr() + + SYSMGR_A10_ISW_HANDOFF_BASE + SYSMGR_A10_ISW_HANDOFF_7); + else + writel(0, socfpga_get_sysmgr_addr() + + SYSMGR_A10_ISW_HANDOFF_BASE + SYSMGR_A10_ISW_HANDOFF_7); +} + +/* + * This function is used to check whether + * handoff register isw_handoff[7] contains + * flag for forcing the periph RBF program "0x50455249". + */ +bool is_periph_program_force(void) +{ + unsigned int status; + + status = readl(socfpga_get_sysmgr_addr() + + SYSMGR_A10_ISW_HANDOFF_BASE + SYSMGR_A10_ISW_HANDOFF_7); + + if (status == PERIPH_RBF_PROG_FORCE) + return true; + else + return false; +} + /* * This function set/unset magic number "0xd15ea5e" to * handoff register isw_handoff[7] - 0xffd0624c diff --git a/arch/arm/mach-socfpga/spl_a10.c b/arch/arm/mach-socfpga/spl_a10.c index 6450f75058..d2f454cd24 100644 --- a/arch/arm/mach-socfpga/spl_a10.c +++ b/arch/arm/mach-socfpga/spl_a10.c @@ -133,6 +133,20 @@ void spl_board_init(void) } else if (!is_fpgamgr_early_user_mode()) { /* Program IOSSM(early IO release) or full FPGA */ fpgamgr_program(buf, FPGA_BUFSIZ, 0); + + /* Skipping double program for combined RBF */ + if (!is_fpgamgr_user_mode()) { + /* + * Expect FPGA entered early user mode, so + * the flag is set to re-program IOSSM + */ + force_periph_program(true); + + /* Re-program IOSSM to stabilize IO system */ + fpgamgr_program(buf, FPGA_BUFSIZ, 0); + + force_periph_program(false); + } } /* If the IOSSM/full FPGA is already loaded, start DDR */ diff --git a/drivers/fpga/socfpga_arria10.c b/drivers/fpga/socfpga_arria10.c index b992e6f080..798e3a3f90 100644 --- a/drivers/fpga/socfpga_arria10.c +++ b/drivers/fpga/socfpga_arria10.c @@ -604,7 +604,8 @@ static int first_loading_rbf_to_buffer(struct udevice *dev, if (strstr(uname, "fpga-periph") && (!is_fpgamgr_early_user_mode() || - is_fpgamgr_user_mode())) { + is_fpgamgr_user_mode() || + is_periph_program_force())) { fpga_node_name = uname; printf("FPGA: Start to program "); printf("peripheral/full bitstream ...\n"); -- cgit v1.2.3