intel: Enable bridge access in Intel platform

Add bridge enablement features for each platform.
The bridge access will be enabled automatically for FPGA 1st
configuration only.

Signed-off-by: Hadi Asyrafi <muhammad.hadi.asyrafi.abdul.halim@intel.com>
Change-Id: I264757b257a209e1c3c4206660f21c5d67af0d2f
diff --git a/plat/intel/soc/agilex/bl2_plat_setup.c b/plat/intel/soc/agilex/bl2_plat_setup.c
index 0366f50..d160279 100644
--- a/plat/intel/soc/agilex/bl2_plat_setup.c
+++ b/plat/intel/soc/agilex/bl2_plat_setup.c
@@ -74,6 +74,8 @@
 	socfpga_delay_timer_init();
 	init_ncore_ccu();
 	init_hard_memory_controller();
+	mailbox_init();
+	socfpga_bridges_enable();
 }
 
 
@@ -106,8 +108,6 @@
 	info.mmc_dev_type = MMC_IS_SD;
 	info.ocr_voltage = OCR_3_3_3_4 | OCR_3_2_3_3;
 
-	mailbox_init();
-
 	switch (boot_source) {
 	case BOOT_SOURCE_SDMMC:
 		dw_mmc_init(&params, &info);
diff --git a/plat/intel/soc/agilex/include/agilex_memory_controller.h b/plat/intel/soc/agilex/include/agilex_memory_controller.h
index 419bd2e..3746d92 100644
--- a/plat/intel/soc/agilex/include/agilex_memory_controller.h
+++ b/plat/intel/soc/agilex/include/agilex_memory_controller.h
@@ -24,9 +24,6 @@
 #define AGX_MPFE_IOHMC_CTRLCFG1_CFG_ADDR_ORDER(value)	\
 						(((value) & 0x00000060) >> 5)
 
-#define AGX_RSTMGR_BRGMODRST				0xffd1102c
-#define AGX_RSTMGR_BRGMODRST_DDRSCH			0x00000040
-
 #define AGX_MPFE_HMC_ADP_ECCCTRL1			0xf8011100
 #define AGX_MPFE_HMC_ADP_ECCCTRL2			0xf8011104
 #define AGX_MPFE_HMC_ADP_RSTHANDSHAKESTAT		0xf8011218
diff --git a/plat/intel/soc/agilex/include/agilex_reset_manager.h b/plat/intel/soc/agilex/include/agilex_reset_manager.h
index a1b6297..9c9c884 100644
--- a/plat/intel/soc/agilex/include/agilex_reset_manager.h
+++ b/plat/intel/soc/agilex/include/agilex_reset_manager.h
@@ -74,6 +74,8 @@
 
 void deassert_peripheral_reset(void);
 void config_hps_hs_before_warm_reset(void);
+int socfpga_bridges_enable(void);
+int socfpga_bridges_disable(void);
 
 #endif
 
diff --git a/plat/intel/soc/agilex/include/agilex_system_manager.h b/plat/intel/soc/agilex/include/agilex_system_manager.h
index 65ab9f9..ab47c45 100644
--- a/plat/intel/soc/agilex/include/agilex_system_manager.h
+++ b/plat/intel/soc/agilex/include/agilex_system_manager.h
@@ -67,6 +67,17 @@
 
 #define AGX_SYSMGR_CORE(x)                      (0xffd12000 + (x))
 
+#define SYSMGR_NOC_TIMEOUT			0xc0
+#define SYSMGR_NOC_IDLEREQ_SET			0xc4
+#define SYSMGR_NOC_IDLEREQ_CLR			0xc8
+#define SYSMGR_NOC_IDLEREQ_VAL			0xcc
+#define SYSMGR_NOC_IDLEACK			0xd0
+#define SYSMGR_NOC_IDLESTATUS			0xd4
+
+#define IDLE_DATA_LWSOC2FPGA			BIT(0)
+#define IDLE_DATA_SOC2FPGA			BIT(4)
+#define IDLE_DATA_MASK	(IDLE_DATA_LWSOC2FPGA | IDLE_DATA_SOC2FPGA)
+
 #define SYSMGR_BOOT_SCRATCH_COLD_0		0x200
 #define SYSMGR_BOOT_SCRATCH_COLD_1		0x204
 #define SYSMGR_BOOT_SCRATCH_COLD_2		0x208
diff --git a/plat/intel/soc/agilex/soc/agilex_reset_manager.c b/plat/intel/soc/agilex/soc/agilex_reset_manager.c
index 65d2029..1224a90 100644
--- a/plat/intel/soc/agilex/soc/agilex_reset_manager.c
+++ b/plat/intel/soc/agilex/soc/agilex_reset_manager.c
@@ -4,9 +4,13 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include <common/debug.h>
+#include <errno.h>
 #include <lib/mmio.h>
 
 #include "agilex_reset_manager.h"
+#include "agilex_system_manager.h"
+#include "socfpga_mailbox.h"
 
 void deassert_peripheral_reset(void)
 {
@@ -80,3 +84,65 @@
 	mmio_setbits_32(AGX_RSTMGR_HDSKEN, or_mask);
 }
 
+static int poll_idle_status(uint32_t addr, uint32_t mask, uint32_t match)
+{
+	int time_out = 1000;
+
+	while (time_out--) {
+		if ((mmio_read_32(addr) & mask) == match) {
+			return 0;
+		}
+	}
+	return -ETIMEDOUT;
+}
+
+int socfpga_bridges_enable(void)
+{
+	uint32_t status, poll_addr;
+
+	status = intel_mailbox_get_config_status(MBOX_CONFIG_STATUS);
+
+	if (!status) {
+		/* Clear idle request */
+		mmio_setbits_32(AGX_SYSMGR_CORE(SYSMGR_NOC_IDLEREQ_CLR), ~0);
+
+		/* De-assert all bridges */
+		mmio_clrbits_32(AGX_RSTMGR_BRGMODRST, ~0);
+
+		/* Wait until idle ack becomes 0 */
+		poll_addr = AGX_SYSMGR_CORE(SYSMGR_NOC_IDLEACK);
+
+		return poll_idle_status(poll_addr, IDLE_DATA_MASK, 0);
+	}
+	return status;
+}
+
+int socfpga_bridges_disable(void)
+{
+	uint32_t poll_addr;
+
+	/* Set idle request */
+	mmio_write_32(AGX_SYSMGR_CORE(SYSMGR_NOC_IDLEREQ_SET), ~0);
+
+	/* Enable NOC timeout */
+	mmio_setbits_32(SYSMGR_NOC_TIMEOUT, 1);
+
+	/* Wait until each idle ack bit toggle to 1 */
+	poll_addr = AGX_SYSMGR_CORE(SYSMGR_NOC_IDLEACK);
+	if (poll_idle_status(poll_addr, IDLE_DATA_MASK, IDLE_DATA_MASK))
+		return -ETIMEDOUT;
+
+	/* Wait until each idle status bit toggle to 1 */
+	poll_addr = AGX_SYSMGR_CORE(SYSMGR_NOC_IDLESTATUS);
+	if (poll_idle_status(poll_addr, IDLE_DATA_MASK, IDLE_DATA_MASK))
+		return -ETIMEDOUT;
+
+	/* Assert all bridges */
+	mmio_setbits_32(AGX_RSTMGR_BRGMODRST,
+		~(AGX_RSTMGR_BRGMODRST_MPFE | AGX_RSTMGR_BRGMODRST_FPGA2SOC));
+
+	/* Disable NOC timeout */
+	mmio_clrbits_32(AGX_SYSMGR_CORE(SYSMGR_NOC_TIMEOUT), 1);
+
+	return 0;
+}
diff --git a/plat/intel/soc/stratix10/bl2_plat_setup.c b/plat/intel/soc/stratix10/bl2_plat_setup.c
index 85a60d6..e53d7ec 100644
--- a/plat/intel/soc/stratix10/bl2_plat_setup.c
+++ b/plat/intel/soc/stratix10/bl2_plat_setup.c
@@ -72,6 +72,8 @@
 
 	socfpga_delay_timer_init();
 	init_hard_memory_controller();
+	mailbox_init();
+	socfpga_bridges_enable();
 }
 
 
diff --git a/plat/intel/soc/stratix10/include/s10_memory_controller.h b/plat/intel/soc/stratix10/include/s10_memory_controller.h
index ad7cb9d..155b279 100644
--- a/plat/intel/soc/stratix10/include/s10_memory_controller.h
+++ b/plat/intel/soc/stratix10/include/s10_memory_controller.h
@@ -22,8 +22,6 @@
 #define S10_MPFE_IOHMC_CTRLCFG1_CFG_ADDR_ORDER(value)	\
 						(((value) & 0x00000060) >> 5)
 
-#define S10_RSTMGR_BRGMODRST				0xffd1102c
-#define S10_RSTMGR_BRGMODRST_DDRSCH			0x00000040
 
 #define S10_MPFE_HMC_ADP_ECCCTRL1			0xf8011100
 #define S10_MPFE_HMC_ADP_ECCCTRL2			0xf8011104
diff --git a/plat/intel/soc/stratix10/include/s10_reset_manager.h b/plat/intel/soc/stratix10/include/s10_reset_manager.h
index 731a8dd..40e7bac 100644
--- a/plat/intel/soc/stratix10/include/s10_reset_manager.h
+++ b/plat/intel/soc/stratix10/include/s10_reset_manager.h
@@ -9,7 +9,9 @@
 
 #define S10_RSTMGR_PER0MODRST				0xffd11024
 #define S10_RSTMGR_PER1MODRST				0xffd11028
-#define S10_RSTMGR_HDSKEN					0xffd11010
+#define S10_RSTMGR_HDSKEN				0xffd11010
+#define S10_RSTMGR_BRGMODRST                            0xffd1102c
+
 
 #define S10_RSTMGR_PER0MODRST_EMAC0			0x00000001
 #define S10_RSTMGR_PER0MODRST_EMAC1			0x00000002
@@ -80,8 +82,18 @@
 #define S10_RSTMGR_PER0MODRST_DMAIF6		0x40000000
 #define S10_RSTMGR_PER0MODRST_DMAIF7		0x80000000
 
+#define BRGMODRST_DDRSCH_MASK			0x40
+#define BRGMODRST_F2SSDRAM2_MASK		0x20
+#define BRGMODRST_F2SSDRAM1_MASK		0x10
+#define BRGMODRST_F2SSDRAM_MASK			0x08
+#define BRGMODRST_FPGA2SOC_MASK			0x04
+#define BRGMODRST_LWHPS2FPGA_MASK		0x02
+#define BRGMODRST_SOC2FPGA_MASK			0x01
+
 void deassert_peripheral_reset(void);
 void config_hps_hs_before_warm_reset(void);
+int socfpga_bridges_enable(void);
+int socfpga_bridges_disable(void);
 
 #endif
 
diff --git a/plat/intel/soc/stratix10/include/s10_system_manager.h b/plat/intel/soc/stratix10/include/s10_system_manager.h
index 8c51181..c34fcf7 100644
--- a/plat/intel/soc/stratix10/include/s10_system_manager.h
+++ b/plat/intel/soc/stratix10/include/s10_system_manager.h
@@ -69,6 +69,17 @@
 #define SYSMGR_MMC				0x28
 #define SYSMGR_MMC_DRVSEL(x)			(((x) & 0x7) << 0)
 
+#define SYSMGR_NOC_TIMEOUT			0xc0
+#define SYSMGR_NOC_IDLEREQ_SET			0xc4
+#define SYSMGR_NOC_IDLEREQ_CLR			0xc8
+#define SYSMGR_NOC_IDLEREQ_VAL			0xcc
+#define SYSMGR_NOC_IDLEACK			0xd0
+#define SYSMGR_NOC_IDLESTATUS			0xd4
+
+#define IDLE_DATA_LWSOC2FPGA			BIT(0)
+#define IDLE_DATA_SOC2FPGA			BIT(4)
+#define IDLE_DATA_MASK	(IDLE_DATA_LWSOC2FPGA | IDLE_DATA_SOC2FPGA)
+
 #define SYSMGR_BOOT_SCRATCH_COLD_0		0x200
 #define SYSMGR_BOOT_SCRATCH_COLD_1		0x204
 #define SYSMGR_BOOT_SCRATCH_COLD_2		0x208
diff --git a/plat/intel/soc/stratix10/soc/s10_memory_controller.c b/plat/intel/soc/stratix10/soc/s10_memory_controller.c
index cb45251..a0dafe1 100644
--- a/plat/intel/soc/stratix10/soc/s10_memory_controller.c
+++ b/plat/intel/soc/stratix10/soc/s10_memory_controller.c
@@ -15,6 +15,7 @@
 #include <string.h>
 
 #include "s10_memory_controller.h"
+#include "s10_reset_manager.h"
 
 #define ALT_CCU_NOC_DI_SET_MSK 0x10
 
@@ -184,7 +185,7 @@
 		return status;
 	}
 
-	mmio_clrbits_32(S10_RSTMGR_BRGMODRST, S10_RSTMGR_BRGMODRST_DDRSCH);
+	mmio_clrbits_32(S10_RSTMGR_BRGMODRST, BRGMODRST_DDRSCH_MASK);
 
 	status = mem_calibration();
 	if (status) {
diff --git a/plat/intel/soc/stratix10/soc/s10_reset_manager.c b/plat/intel/soc/stratix10/soc/s10_reset_manager.c
index 8b7420b..5030e4f 100644
--- a/plat/intel/soc/stratix10/soc/s10_reset_manager.c
+++ b/plat/intel/soc/stratix10/soc/s10_reset_manager.c
@@ -11,10 +11,14 @@
 #include <common/debug.h>
 #include <drivers/arm/gicv2.h>
 #include <drivers/console.h>
+#include <errno.h>
 #include <lib/mmio.h>
 #include <plat/common/platform.h>
 #include <platform_def.h>
+
 #include "s10_reset_manager.h"
+#include "s10_system_manager.h"
+#include "socfpga_mailbox.h"
 
 void deassert_peripheral_reset(void)
 {
@@ -86,3 +90,65 @@
 	mmio_setbits_32(S10_RSTMGR_HDSKEN, or_mask);
 }
 
+static int poll_idle_status(uint32_t addr, uint32_t mask, uint32_t match)
+{
+	int time_out = 1000;
+
+	while (time_out--) {
+		if ((mmio_read_32(addr) & mask) == match) {
+			return 0;
+		}
+	}
+	return -ETIMEDOUT;
+}
+
+int socfpga_bridges_enable(void)
+{
+	uint32_t status, poll_addr;
+
+	status = intel_mailbox_get_config_status(MBOX_CONFIG_STATUS);
+
+	if (!status) {
+		/* Clear idle request */
+		mmio_setbits_32(S10_SYSMGR_CORE(SYSMGR_NOC_IDLEREQ_CLR), ~0);
+
+		/* De-assert all bridges */
+		mmio_clrbits_32(S10_RSTMGR_BRGMODRST, ~0);
+
+		/* Wait until idle ack becomes 0 */
+		poll_addr = S10_SYSMGR_CORE(SYSMGR_NOC_IDLEACK);
+
+		return poll_idle_status(poll_addr, IDLE_DATA_MASK, 0);
+	}
+	return status;
+}
+
+int socfpga_bridges_disable(void)
+{
+	uint32_t poll_addr;
+
+	/* Set idle request */
+	mmio_write_32(S10_SYSMGR_CORE(SYSMGR_NOC_IDLEREQ_SET), ~0);
+
+	/* Enable NOC timeout */
+	mmio_setbits_32(SYSMGR_NOC_TIMEOUT, 1);
+
+	/* Wait until each idle ack bit toggle to 1 */
+	poll_addr = S10_SYSMGR_CORE(SYSMGR_NOC_IDLEACK);
+	if (poll_idle_status(poll_addr, IDLE_DATA_MASK, IDLE_DATA_MASK))
+		return -ETIMEDOUT;
+
+	/* Wait until each idle status bit toggle to 1 */
+	poll_addr = S10_SYSMGR_CORE(SYSMGR_NOC_IDLESTATUS);
+	if (poll_idle_status(poll_addr, IDLE_DATA_MASK, IDLE_DATA_MASK))
+		return -ETIMEDOUT;
+
+	/* Assert all bridges */
+	mmio_setbits_32(S10_RSTMGR_BRGMODRST,
+		~(BRGMODRST_DDRSCH_MASK | BRGMODRST_FPGA2SOC_MASK));
+
+	/* Disable NOC timeout */
+	mmio_clrbits_32(S10_SYSMGR_CORE(SYSMGR_NOC_TIMEOUT), 1);
+
+	return 0;
+}