diff options
author | Tien Fong Chee <tien.fong.chee@intel.com> | 2023-03-02 18:15:11 +0800 |
---|---|---|
committer | tienfong <tien.fong.chee@gmail.com> | 2023-03-20 11:03:15 +0800 |
commit | 1dda7c081ee51d6c4b52d2ef773464b745fb9ec0 (patch) | |
tree | e22edd54e53cabd80178b4d96398be864d548037 | |
parent | 66f3f251b2d5767c2c4abd85e01df415e6c5bfe7 (diff) | |
download | u-boot-socfpga-1dda7c081ee51d6c4b52d2ef773464b745fb9ec0.tar.gz |
HSD #15012954777-5: arm: socfpga: soc64: Restructure F2S disable function
Restructure the flow to avoid the bridges being reset twice and with
cleaner wait_for_bit status check function. This flow is verified with
a lot stress test to ensure validity and reliability in result.
Signed-off-by: Tien Fong Chee <tien.fong.chee@intel.com>
-rw-r--r-- | arch/arm/mach-socfpga/reset_manager_s10.c | 54 |
1 files changed, 30 insertions, 24 deletions
diff --git a/arch/arm/mach-socfpga/reset_manager_s10.c b/arch/arm/mach-socfpga/reset_manager_s10.c index c8e5ddceab..4a4d48abf6 100644 --- a/arch/arm/mach-socfpga/reset_manager_s10.c +++ b/arch/arm/mach-socfpga/reset_manager_s10.c @@ -95,8 +95,7 @@ void socfpga_per_reset_all(void) static __always_inline void socfpga_f2s_bridges_reset(int enable, unsigned int mask) { - int timeout_ms = TIMEOUT_300MS; - u32 empty; + int ret; u32 brg_mask; u32 flagout_idlereq = 0; u32 flagoutset_fdrain = 0; @@ -170,6 +169,12 @@ static __always_inline void socfpga_f2s_bridges_reset(int enable, __socfpga_udelay(1); /* wait 1us */ } else { + if (readl((socfpga_get_rstmgr_addr() + + RSTMGR_SOC64_BRGMODRST) & brg_mask)) { + /* Bridge cannot be reset twice */ + return; + } + setbits_le32(socfpga_get_rstmgr_addr() + RSTMGR_SOC64_HDSKEN, RSTMGR_HDSKEN_FPGAHSEN); setbits_le32(socfpga_get_rstmgr_addr() + RSTMGR_SOC64_HDSKREQ, @@ -182,31 +187,32 @@ static __always_inline void socfpga_f2s_bridges_reset(int enable, setbits_le32(SOCFPGA_F2SDRAM_MGR_ADDRESS + F2SDRAM_SIDEBAND_FLAGOUTCLR0, flagoutset_en); + __socfpga_udelay(1); + + /* Requests MPFE NoC to idle */ setbits_le32(SOCFPGA_F2SDRAM_MGR_ADDRESS + - F2SDRAM_SIDEBAND_FLAGOUTSET0, - flagoutset_fdrain); - __socfpga_udelay(1); + F2SDRAM_SIDEBAND_FLAGOUTSET0, flagout_idlereq); - do { - /* - * Read response queue status twice to ensure it is - * empty. - */ - empty = readl(SOCFPGA_F2SDRAM_MGR_ADDRESS + - F2SDRAM_SIDEBAND_FLAGINSTATUS0) & - flaginstatus_respempty; - if (empty) { - empty = readl(SOCFPGA_F2SDRAM_MGR_ADDRESS + - F2SDRAM_SIDEBAND_FLAGINSTATUS0) & - flaginstatus_respempty; - if (empty) - break; - } - - timeout_ms--; - __socfpga_udelay(1000); - } while (timeout_ms); + + /* Force F2S bridge to drain */ + setbits_le32(SOCFPGA_F2SDRAM_MGR_ADDRESS + + F2SDRAM_SIDEBAND_FLAGOUTSET0, flagoutset_fdrain); + + + /* Wait for respond queue empty status to 1 (resp idle) */ + ret = wait_for_bit((u32 *)(SOCFPGA_F2SDRAM_MGR_ADDRESS + + F2SDRAM_SIDEBAND_FLAGINSTATUS0), + flaginstatus_respempty, true, + TIMEOUT_300MS); + + /* Confirm again */ + if (!ret) + ret = wait_for_bit((u32 *) + (SOCFPGA_F2SDRAM_MGR_ADDRESS + + F2SDRAM_SIDEBAND_FLAGINSTATUS0), + flaginstatus_respempty, true, + TIMEOUT_300MS); setbits_le32(socfpga_get_rstmgr_addr() + RSTMGR_SOC64_BRGMODRST, brg_mask & ~RSTMGR_BRGMODRST_FPGA2SOC_MASK); |