diff options
author | Tom Rini <trini@konsulko.com> | 2021-12-20 17:12:04 -0500 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2021-12-20 17:12:04 -0500 |
commit | 4afab30caea3211032710c4298a8839d3254e7f7 (patch) | |
tree | 8318afb8810966aca9fe356dde316c155b7a33ce /arch/arm/mach-socfpga/misc_arria10.c | |
parent | e9d7888da845638f135046d53c25492a8c54e664 (diff) | |
parent | 734ad933766f0dbbeafe1b27211686940a5e6d16 (diff) |
Merge tag 'v2022.01-rc4' into next
Prepare v2022.01-rc4
Diffstat (limited to 'arch/arm/mach-socfpga/misc_arria10.c')
-rw-r--r-- | arch/arm/mach-socfpga/misc_arria10.c | 126 |
1 files changed, 125 insertions, 1 deletions
diff --git a/arch/arm/mach-socfpga/misc_arria10.c b/arch/arm/mach-socfpga/misc_arria10.c index bf978053ca..0ed2adfd84 100644 --- a/arch/arm/mach-socfpga/misc_arria10.c +++ b/arch/arm/mach-socfpga/misc_arria10.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 /* - * Copyright (C) 2016-2017 Intel Corporation + * Copyright (C) 2016-2021 Intel Corporation */ #include <altera.h> @@ -11,6 +11,7 @@ #include <miiphy.h> #include <netdev.h> #include <ns16550.h> +#include <spi_flash.h> #include <watchdog.h> #include <asm/arch/misc.h> #include <asm/arch/pinmux.h> @@ -21,6 +22,7 @@ #include <asm/arch/nic301.h> #include <asm/io.h> #include <asm/pl310.h> +#include <linux/sizes.h> #define PINMUX_UART0_TX_SHARED_IO_OFFSET_Q1_3 0x08 #define PINMUX_UART0_TX_SHARED_IO_OFFSET_Q2_11 0x58 @@ -29,6 +31,13 @@ #define PINMUX_UART1_TX_SHARED_IO_OFFSET_Q3_7 0x78 #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 +#define QSPI_NO_SOFT_RESET 0x00000000 + /* * FPGA programming support for SoC FPGA Arria 10 */ @@ -122,3 +131,118 @@ void do_bridge_reset(int enable, unsigned int mask) else 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 + * This magic number is part of boot progress tracking + * and it's required for warm reset workaround on MPFE hang issue. + */ +void set_regular_boot(unsigned int status) +{ + if (status) + writel(REGULAR_BOOT_MAGIC, 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 + * magic number "0xd15ea5e". + */ +bool is_regular_boot_valid(void) +{ + unsigned int status; + + status = readl(socfpga_get_sysmgr_addr() + + SYSMGR_A10_ISW_HANDOFF_BASE + SYSMGR_A10_ISW_HANDOFF_7); + + if (status == REGULAR_BOOT_MAGIC) + return true; + else + return false; +} + +#if IS_ENABLED(CONFIG_CADENCE_QSPI) +/* This function is used to trigger software reset + * to the QSPI flash. On some boards, the QSPI flash reset may + * not be connected to the HPS warm reset. + */ +int qspi_flash_software_reset(void) +{ + struct udevice *flash; + int ret; + + /* Get the flash info */ + ret = spi_flash_probe_bus_cs(CONFIG_SF_DEFAULT_BUS, + CONFIG_SF_DEFAULT_CS, + CONFIG_SF_DEFAULT_SPEED, + CONFIG_SF_DEFAULT_MODE, + &flash); + + if (ret) { + debug("Failed to initialize SPI flash at "); + debug("%u:%u (error %d)\n", CONFIG_SF_DEFAULT_BUS, + CONFIG_SF_DEFAULT_CS, ret); + return -ENODEV; + } + + if (!flash) + return -EINVAL; + + /* + * QSPI flash software reset command, for the case where + * no HPS reset connected to QSPI flash reset + */ + if (!memcmp(flash->name, "N25", SZ_1 + SZ_2)) + writel(QSPI_N25_SOFT_RESET_COMMAND, socfpga_get_sysmgr_addr() + + SYSMGR_A10_ROMCODE_QSPIRESETCOMMAND); + else if (!memcmp(flash->name, "S25FL", SZ_1 + SZ_4)) + writel(QSPI_S25FL_SOFT_RESET_COMMAND, + socfpga_get_sysmgr_addr() + + SYSMGR_A10_ROMCODE_QSPIRESETCOMMAND); + else /* No software reset */ + writel(QSPI_NO_SOFT_RESET, socfpga_get_sysmgr_addr() + + SYSMGR_A10_ROMCODE_QSPIRESETCOMMAND); + + return 0; +} +#endif |