From 97a72bc28613733572b9632a51ab9c8680d45406 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Wed, 20 Nov 2019 22:34:31 +0100 Subject: ARM: socfpga: Purge pending transactions upon enabling bridges on Gen5 On Gen5, when the FPGA is loaded and there was some prior interaction between the HPS and the FPGA via bridges (e.g. Linux was running and using some of the IPs in the FPGA) followed by warm reset, it has been observed that there might be outstanding unfinished transactions. This leads to an obscure misbehavior of the bridge. When the bridge is enabled again in U-Boot and there are outstanding transactions, a read from within the bridge address range would return a result of the previous read instead. Example: => bridge enable ; md 0xff200000 1 ff200000: 1234abcd => bridge enable ; md 0xff200010 1 ff200010: 5678dcba <------- this is in fact a value which is stored in a memory at 0xff200000 => bridge enable ; md 0xff200000 1 ff200000: 90effe09 <------- this is in fact a value which is stored in a memory at 0xff200010 and so it continues. Issuing a write does lock the system up completely. This patch opens the FPGA bridges in 'bridge enable' command, the tears them down again, and then opens them again. This allows these outstanding transactions to complete and makes this misbehavior go away. However, it is not entirely clear whether this is the correct solution. Signed-off-by: Marek Vasut Cc: Chin Liang See Cc: Dalon Westergreen Cc: Dinh Nguyen Cc: Ley Foon Tan Cc: Simon Goldschmidt Cc: Tien Fong Chee Reviewed-by: Ley Foon Tan --- arch/arm/mach-socfpga/misc_gen5.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'arch') diff --git a/arch/arm/mach-socfpga/misc_gen5.c b/arch/arm/mach-socfpga/misc_gen5.c index 36f00aee31..65d3485bc5 100644 --- a/arch/arm/mach-socfpga/misc_gen5.c +++ b/arch/arm/mach-socfpga/misc_gen5.c @@ -228,6 +228,9 @@ void do_bridge_reset(int enable, unsigned int mask) writel(iswgrp_handoff[3], &sdr_ctrl->fpgaport_rst); writel(iswgrp_handoff[0], &reset_manager_base->brg_mod_reset); writel(iswgrp_handoff[1], &nic301_regs->remap); + + writel(0x7, &reset_manager_base->brg_mod_reset); + writel(iswgrp_handoff[0], &reset_manager_base->brg_mod_reset); } else { writel(0, &sysmgr_regs->fpgaintfgrp_module); writel(0, &sdr_ctrl->fpgaport_rst); -- cgit v1.2.3