diff options
author | Ley Foon Tan <ley.foon.tan@intel.com> | 2021-01-26 10:05:19 +0800 |
---|---|---|
committer | Ley Foon Tan <ley.foon.tan@intel.com> | 2021-02-25 10:21:23 +0800 |
commit | 65cad744f3c2e12103ed9c5b8d870b77b4f09128 (patch) | |
tree | 228cc332a02408f43e67daa1173873fee2b55dcf | |
parent | e7e8a122dea488b185d5aa84bd75ac8722f197e5 (diff) | |
download | u-boot-socfpga-65cad744f3c2e12103ed9c5b8d870b77b4f09128.tar.gz |
HSD #1508586908-5: arm: socfpga: soc64: Add f2s bridge support
Add F2H and F2SDRAM bridges disable/enable support, based on software
programming flow in HW documentation.
Signed-off-by: Ley Foon Tan <ley.foon.tan@intel.com>
---
v3:
- Remove reset timeout to 300.
- Rename timeout to timeout_ms to avoid same name in marcos.
v2: Change constant 300 to "timeout".
-rw-r--r-- | arch/arm/mach-socfpga/reset_manager_s10.c | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/arch/arm/mach-socfpga/reset_manager_s10.c b/arch/arm/mach-socfpga/reset_manager_s10.c index e48185345d..b5792ad754 100644 --- a/arch/arm/mach-socfpga/reset_manager_s10.c +++ b/arch/arm/mach-socfpga/reset_manager_s10.c @@ -18,6 +18,35 @@ 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); \ @@ -29,6 +58,17 @@ DECLARE_GLOBAL_DATA_PTR; } \ } +#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) { @@ -69,6 +109,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) { @@ -122,12 +230,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); } /* |