summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTien Fong Chee <tien.fong.chee@intel.com>2023-03-02 18:15:11 +0800
committertienfong <tien.fong.chee@gmail.com>2023-03-20 11:03:15 +0800
commit1dda7c081ee51d6c4b52d2ef773464b745fb9ec0 (patch)
treee22edd54e53cabd80178b4d96398be864d548037
parent66f3f251b2d5767c2c4abd85e01df415e6c5bfe7 (diff)
downloadu-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.c54
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);