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(¶ms, &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 +#include #include #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 #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 #include #include +#include #include #include #include + #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; +}