From: Ley Foon Tan <[email protected]>

HSD #1508586908-5: Add F2H and F2SDRAM bridges disable/enable support, based on 
software
programming flow in HW documentation.

Signed-off-by: Ley Foon Tan <[email protected]>
Signed-off-by: Jit Loon Lim <[email protected]>
---
 arch/arm/mach-socfpga/reset_manager_s10.c | 122 +++++++++++++++++++++-
 1 file changed, 121 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mach-socfpga/reset_manager_s10.c 
b/arch/arm/mach-socfpga/reset_manager_s10.c
index 20ab374881..690cfb2b20 100644
--- a/arch/arm/mach-socfpga/reset_manager_s10.c
+++ b/arch/arm/mach-socfpga/reset_manager_s10.c
@@ -17,6 +17,57 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
+/* F2S manager registers */
+#define F2SDRAM_SIDEBAND_FLAGINSTATUS0 0x14
+#define F2SDRAM_SIDEBAND_FLAGOUTSET0   0x50
+#define F2SDRAM_SIDEBAND_FLAGOUTCLR0   0x54
+
+#ifdef CONFIG_TARGET_SOCFPGA_STRATIX10
+#define FLAGINSTATUS0_MPFE_NOC_IDLE    (BIT(0) | BIT(4) | BIT(8))
+#define FLAGINSTATUS0_MPFE_NOC_IDLEACK (BIT(1) | BIT(5) | BIT(9))
+#define FLAGINSTATUS0_F2S_CMD_EMPTY    (BIT(2) | BIT(6) | BIT(10))
+#define FLAGINSTATUS0_F2S_RESP_EMPTY   (BIT(3) | BIT(7) | BIT(11))
+
+#define FLGAOUTSET0_MPFE_NOC_IDLEREQ   (BIT(0) | BIT(3) | BIT(6))
+#define FLGAOUTSET0_F2S_EN             (BIT(1) | BIT(4) | BIT(7))
+#define FLGAOUTSET0_F2S_FORCE_DRAIN    (BIT(2) | BIT(5) | BIT(8))
+
+#define FLGAOUTCLR0_F2S_IDLEREQ                (BIT(0) | BIT(3) | BIT(6))
+#else
+#define FLAGINSTATUS0_MPFE_NOC_IDLE    BIT(0)
+#define FLAGINSTATUS0_MPFE_NOC_IDLEACK BIT(1)
+#define FLAGINSTATUS0_F2S_CMD_EMPTY    BIT(2)
+#define FLAGINSTATUS0_F2S_RESP_EMPTY   BIT(3)
+
+#define FLGAOUTSET0_MPFE_NOC_IDLEREQ   BIT(0)
+#define FLGAOUTSET0_F2S_EN             BIT(1)
+#define FLGAOUTSET0_F2S_FORCE_DRAIN    BIT(2)
+
+#define FLGAOUTCLR0_F2S_IDLEREQ                BIT(0)
+#endif
+
+#define POLL_FOR_ZERO(expr, timeout_ms)                \
+       {                                       \
+               int timeout = (timeout_ms);     \
+               while ((expr)) {                \
+                       if (!timeout)           \
+                               break;          \
+                       timeout--;              \
+                       __socfpga_udelay(1000); \
+               }                               \
+       }
+
+#define POLL_FOR_SET(expr, timeout_ms)         \
+       {                                       \
+               int timeout = (timeout_ms);     \
+               while (!(expr)) {               \
+                       if (!timeout)           \
+                               break;          \
+                       timeout--;              \
+                       __socfpga_udelay(1000); \
+               }                               \
+       }
+
 /* Assert or de-assert SoCFPGA reset manager reset. */
 void socfpga_per_reset(u32 reset, int set)
 {
@@ -57,6 +108,74 @@ void socfpga_per_reset_all(void)
        writel(0xffffffff, socfpga_get_rstmgr_addr() + RSTMGR_SOC64_PER1MODRST);
 }
 
+static __always_inline void socfpga_f2s_bridges_reset(int enable)
+{
+       int timeout_ms = 300;
+       u32 empty;
+
+       if (enable) {
+               clrbits_le32(socfpga_get_rstmgr_addr() + RSTMGR_SOC64_BRGMODRST,
+                            BRGMODRST_FPGA2SOC_BRIDGES);
+               clrbits_le32(SOCFPGA_F2SDRAM_MGR_ADDRESS +
+                            F2SDRAM_SIDEBAND_FLAGOUTSET0,
+                            FLGAOUTSET0_MPFE_NOC_IDLEREQ);
+
+               POLL_FOR_ZERO((readl(SOCFPGA_F2SDRAM_MGR_ADDRESS +
+                             F2SDRAM_SIDEBAND_FLAGINSTATUS0) &
+                             FLAGINSTATUS0_MPFE_NOC_IDLEACK), timeout_ms);
+               clrbits_le32(SOCFPGA_F2SDRAM_MGR_ADDRESS +
+                            F2SDRAM_SIDEBAND_FLAGOUTSET0,
+                            FLGAOUTSET0_F2S_FORCE_DRAIN);
+               setbits_le32(SOCFPGA_F2SDRAM_MGR_ADDRESS +
+                            F2SDRAM_SIDEBAND_FLAGOUTSET0, FLGAOUTSET0_F2S_EN);
+
+               __socfpga_udelay(1); /* wait 1us */
+       } else {
+               setbits_le32(socfpga_get_rstmgr_addr() + RSTMGR_SOC64_HDSKEN,
+                            RSTMGR_HDSKEN_FPGAHSEN);
+               setbits_le32(socfpga_get_rstmgr_addr() + RSTMGR_SOC64_HDSKREQ,
+                            RSTMGR_HDSKREQ_FPGAHSREQ);
+               POLL_FOR_SET(readl(socfpga_get_rstmgr_addr() +
+                            RSTMGR_SOC64_HDSKACK), timeout_ms);
+               clrbits_le32(SOCFPGA_F2SDRAM_MGR_ADDRESS +
+                            F2SDRAM_SIDEBAND_FLAGOUTSET0, FLGAOUTSET0_F2S_EN);
+               __socfpga_udelay(1);
+               setbits_le32(SOCFPGA_F2SDRAM_MGR_ADDRESS +
+                            F2SDRAM_SIDEBAND_FLAGOUTSET0,
+                            FLGAOUTSET0_F2S_FORCE_DRAIN);
+               __socfpga_udelay(1);
+
+               do {
+                       /*
+                        * Read response queue status twice to ensure it is
+                        * empty.
+                        */
+                       empty = readl(SOCFPGA_F2SDRAM_MGR_ADDRESS +
+                                     F2SDRAM_SIDEBAND_FLAGINSTATUS0) &
+                                     FLAGINSTATUS0_F2S_RESP_EMPTY;
+                       if (empty) {
+                               empty = readl(SOCFPGA_F2SDRAM_MGR_ADDRESS +
+                                             F2SDRAM_SIDEBAND_FLAGINSTATUS0) &
+                                             FLAGINSTATUS0_F2S_RESP_EMPTY;
+                               if (empty)
+                                       break;
+                       }
+
+                       timeout_ms--;
+                       __socfpga_udelay(1000);
+               } while (timeout_ms);
+
+               setbits_le32(socfpga_get_rstmgr_addr() + RSTMGR_SOC64_BRGMODRST,
+                            BRGMODRST_FPGA2SOC_BRIDGES &
+                            ~RSTMGR_BRGMODRST_FPGA2SOC_MASK);
+               clrbits_le32(socfpga_get_rstmgr_addr() + RSTMGR_SOC64_HDSKREQ,
+                            RSTMGR_HDSKREQ_FPGAHSREQ);
+               setbits_le32(SOCFPGA_F2SDRAM_MGR_ADDRESS +
+                            F2SDRAM_SIDEBAND_FLAGOUTCLR0,
+                            FLGAOUTCLR0_F2S_IDLEREQ);
+       }
+}
+
 static __always_inline void socfpga_s2f_bridges_reset(int enable)
 {
        if (enable) {
@@ -109,13 +228,14 @@ void socfpga_bridges_reset(int enable)
                        hang();
        } else {
                socfpga_s2f_bridges_reset(enable);
-
+               socfpga_f2s_bridges_reset(enable);
        }
 }
 
 void __secure socfpga_bridges_reset_psci(int enable)
 {
        socfpga_s2f_bridges_reset(enable);
+       socfpga_f2s_bridges_reset(enable);
 }
 
 /*
-- 
2.26.2

Reply via email to