]> git.baikalelectronics.ru Git - arm-tf.git/commitdiff
feat(intel): fix bridge disable and reset
authorAng Tien Sung <tien.sung.ang@intel.com>
Mon, 13 Mar 2023 01:32:40 +0000 (09:32 +0800)
committerSieu Mun Tang <sieu.mun.tang@intel.com>
Mon, 10 Apr 2023 16:17:00 +0000 (00:17 +0800)
Fix bridge sideband manager register clear and set incorrect
implementation. To support non-graceful full bridge disable
and enable.

Signed-off-by: Ang Tien Sung <tien.sung.ang@intel.com>
Signed-off-by: Jit Loon Lim <jit.loon.lim@intel.com>
Change-Id: I651f3ec163d954e8efb0542ec33bce96e51992db

plat/intel/soc/common/include/socfpga_f2sdram_manager.h
plat/intel/soc/common/soc/socfpga_reset_manager.c

index 82bb6cbe1185ee0907136ee6ad1e0897f5cd7c12..b30a11e56f6f80b84fe3eebb087847534eeef311 100644 (file)
 #define FLAGOUTSETCLR_F2SDRAM0_IDLEREQ         (BIT(0))
 #define FLAGOUTSETCLR_F2SDRAM1_IDLEREQ         (BIT(3))
 #define FLAGOUTSETCLR_F2SDRAM2_IDLEREQ         (BIT(6))
-#define FLAGINTSTATUS_F2SDRAM0_IDLEACK         (BIT(1))
-#define FLAGINTSTATUS_F2SDRAM1_IDLEACK         (BIT(5))
-#define FLAGINTSTATUS_F2SDRAM2_IDLEACK         (BIT(9))
+#define FLAGINSTATUS_F2SDRAM0_IDLEACK          (BIT(1))
+#define FLAGINSTATUS_F2SDRAM1_IDLEACK          (BIT(5))
+#define FLAGINSTATUS_F2SDRAM2_IDLEACK          (BIT(9))
+#define FLAGINSTATUS_F2SDRAM0_CMDIDLE          (BIT(2))
+#define FLAGINSTATUS_F2SDRAM1_CMDIDLE          (BIT(6))
+#define FLAGINSTATUS_F2SDRAM2_CMDIDLE          (BIT(10))
+#define FLAGINSTATUS_F2SDRAM0_NOCIDLE          (BIT(0))
+#define FLAGINSTATUS_F2SDRAM1_NOCIDLE          (BIT(4))
+#define FLAGINSTATUS_F2SDRAM2_NOCIDLE          (BIT(8))
+
 #define FLAGOUTSETCLR_F2SDRAM0_FORCE_DRAIN     (BIT(2))
 #define FLAGOUTSETCLR_F2SDRAM1_FORCE_DRAIN     (BIT(5))
 #define FLAGOUTSETCLR_F2SDRAM2_FORCE_DRAIN     (BIT(8))
 
-#define FLAGINTSTATUS_F2SOC_RESPEMPTY          (BIT(3))
-#define FLAGINTSTATUS_F2SDRAM0_RESPEMPTY       (BIT(3))
-#define FLAGINTSTATUS_F2SDRAM1_RESPEMPTY       (BIT(7))
-#define FLAGINTSTATUS_F2SDRAM2_RESPEMPTY       (BIT(11))
+#define FLAGINSTATUS_F2SOC_RESPEMPTY           (BIT(3))
+#define FLAGINSTATUS_F2SDRAM0_RESPEMPTY                (BIT(3))
+#define FLAGINSTATUS_F2SDRAM1_RESPEMPTY                (BIT(7))
+#define FLAGINSTATUS_F2SDRAM2_RESPEMPTY                (BIT(11))
+#define FLAGINSTATUS_F2S_FM_TRACKERIDLE                (BIT(4))
 
 #define SOCFPGA_F2SDRAMMGR(_reg)       (SOCFPGA_F2SDRAMMGR_REG_BASE \
                                                + (SOCFPGA_F2SDRAMMGR_##_reg))
index bb4efab9339d8e42db3eeb00e670e7030146f235..77d9a7370067e2f06d2b3d1f05459b03ec4a8de1 100644 (file)
@@ -14,7 +14,6 @@
 #include "socfpga_reset_manager.h"
 #include "socfpga_system_manager.h"
 
-
 void deassert_peripheral_reset(void)
 {
        mmio_clrbits_32(SOCFPGA_RSTMGR(PER1MODRST),
@@ -89,11 +88,12 @@ void config_hps_hs_before_warm_reset(void)
        mmio_setbits_32(SOCFPGA_RSTMGR(HDSKEN), or_mask);
 }
 
-static int poll_idle_status(uint32_t addr, uint32_t mask, uint32_t match)
+static int poll_idle_status(uint32_t addr, uint32_t mask, uint32_t match, uint32_t delay_ms)
 {
-       int time_out = 300;
+       int time_out = delay_ms;
+
+       while (time_out-- > 0) {
 
-       while (time_out--) {
                if ((mmio_read_32(addr) & mask) == match) {
                        return 0;
                }
@@ -102,9 +102,24 @@ static int poll_idle_status(uint32_t addr, uint32_t mask, uint32_t match)
        return -ETIMEDOUT;
 }
 
+static int poll_idle_status_by_clkcycles(uint32_t addr, uint32_t mask,
+                                        uint32_t match, uint32_t delay_clk_cycles)
+{
+       int time_out = delay_clk_cycles;
+
+       while (time_out-- > 0) {
+
+               if ((mmio_read_32(addr) & mask) == match) {
+                       return 0;
+               }
+               udelay(1);
+       }
+       return -ETIMEDOUT;
+}
+
 static void socfpga_s2f_bridge_mask(uint32_t mask,
-                               uint32_t *brg_mask,
-                               uint32_t *noc_mask)
+                                   uint32_t *brg_mask,
+                                   uint32_t *noc_mask)
 {
        *brg_mask = 0;
        *noc_mask = 0;
@@ -121,12 +136,13 @@ static void socfpga_s2f_bridge_mask(uint32_t mask,
 }
 
 static void socfpga_f2s_bridge_mask(uint32_t mask,
-                               uint32_t *brg_mask,
-                               uint32_t *f2s_idlereq,
-                               uint32_t *f2s_force_drain,
-                               uint32_t *f2s_en,
-                               uint32_t *f2s_idleack,
-                               uint32_t *f2s_respempty)
+                                   uint32_t *brg_mask,
+                                   uint32_t *f2s_idlereq,
+                                   uint32_t *f2s_force_drain,
+                                   uint32_t *f2s_en,
+                                   uint32_t *f2s_idleack,
+                                   uint32_t *f2s_respempty,
+                                   uint32_t *f2s_cmdidle)
 {
        *brg_mask = 0;
        *f2s_idlereq = 0;
@@ -134,6 +150,7 @@ static void socfpga_f2s_bridge_mask(uint32_t mask,
        *f2s_en = 0;
        *f2s_idleack = 0;
        *f2s_respempty = 0;
+       *f2s_cmdidle = 0;
 
 #if PLATFORM_MODEL == PLAT_SOCFPGA_STRATIX10
        if ((mask & FPGA2SOC_MASK) != 0U) {
@@ -144,24 +161,27 @@ static void socfpga_f2s_bridge_mask(uint32_t mask,
                *f2s_idlereq |= FLAGOUTSETCLR_F2SDRAM0_IDLEREQ;
                *f2s_force_drain |= FLAGOUTSETCLR_F2SDRAM0_FORCE_DRAIN;
                *f2s_en |= FLAGOUTSETCLR_F2SDRAM0_ENABLE;
-               *f2s_idleack |= FLAGINTSTATUS_F2SDRAM0_IDLEACK;
-               *f2s_respempty |= FLAGINTSTATUS_F2SDRAM0_RESPEMPTY;
+               *f2s_idleack |= FLAGINSTATUS_F2SDRAM0_IDLEACK;
+               *f2s_respempty |= FLAGINSTATUS_F2SDRAM0_RESPEMPTY;
+               *f2s_cmdidle |= FLAGINSTATUS_F2SDRAM0_CMDIDLE;
        }
        if ((mask & F2SDRAM1_MASK) != 0U) {
                *brg_mask |= RSTMGR_FIELD(BRG, F2SSDRAM1);
                *f2s_idlereq |= FLAGOUTSETCLR_F2SDRAM1_IDLEREQ;
                *f2s_force_drain |= FLAGOUTSETCLR_F2SDRAM1_FORCE_DRAIN;
                *f2s_en |= FLAGOUTSETCLR_F2SDRAM1_ENABLE;
-               *f2s_idleack |= FLAGINTSTATUS_F2SDRAM1_IDLEACK;
-               *f2s_respempty |= FLAGINTSTATUS_F2SDRAM1_RESPEMPTY;
+               *f2s_idleack |= FLAGINSTATUS_F2SDRAM1_IDLEACK;
+               *f2s_respempty |= FLAGINSTATUS_F2SDRAM1_RESPEMPTY;
+               *f2s_cmdidle |= FLAGINSTATUS_F2SDRAM1_CMDIDLE;
        }
        if ((mask & F2SDRAM2_MASK) != 0U) {
                *brg_mask |= RSTMGR_FIELD(BRG, F2SSDRAM2);
                *f2s_idlereq |= FLAGOUTSETCLR_F2SDRAM2_IDLEREQ;
                *f2s_force_drain |= FLAGOUTSETCLR_F2SDRAM2_FORCE_DRAIN;
                *f2s_en |= FLAGOUTSETCLR_F2SDRAM2_ENABLE;
-               *f2s_idleack |= FLAGINTSTATUS_F2SDRAM2_IDLEACK;
-               *f2s_respempty |= FLAGINTSTATUS_F2SDRAM2_RESPEMPTY;
+               *f2s_idleack |= FLAGINSTATUS_F2SDRAM2_IDLEACK;
+               *f2s_respempty |= FLAGINSTATUS_F2SDRAM2_RESPEMPTY;
+               *f2s_cmdidle |= FLAGINSTATUS_F2SDRAM2_CMDIDLE;
        }
 #else
        if ((mask & FPGA2SOC_MASK) != 0U) {
@@ -169,8 +189,9 @@ static void socfpga_f2s_bridge_mask(uint32_t mask,
                *f2s_idlereq |= FLAGOUTSETCLR_F2SDRAM0_IDLEREQ;
                *f2s_force_drain |= FLAGOUTSETCLR_F2SDRAM0_FORCE_DRAIN;
                *f2s_en |= FLAGOUTSETCLR_F2SDRAM0_ENABLE;
-               *f2s_idleack |= FLAGINTSTATUS_F2SDRAM0_IDLEACK;
-               *f2s_respempty |= FLAGINTSTATUS_F2SDRAM0_RESPEMPTY;
+               *f2s_idleack |= FLAGINSTATUS_F2SDRAM0_IDLEACK;
+               *f2s_respempty |= FLAGINSTATUS_F2SDRAM0_RESPEMPTY;
+               *f2s_cmdidle |= FLAGINSTATUS_F2SDRAM0_CMDIDLE;
        }
 #endif
 }
@@ -185,6 +206,7 @@ int socfpga_bridges_enable(uint32_t mask)
        uint32_t f2s_en = 0;
        uint32_t f2s_idleack = 0;
        uint32_t f2s_respempty = 0;
+       uint32_t f2s_cmdidle = 0;
 
        /* Enable s2f bridge */
        socfpga_s2f_bridge_mask(mask, &brg_mask, &noc_mask);
@@ -198,7 +220,7 @@ int socfpga_bridges_enable(uint32_t mask)
 
                /* Wait until idle ack becomes 0 */
                ret = poll_idle_status(SOCFPGA_SYSMGR(NOC_IDLEACK),
-                                               noc_mask, 0);
+                                      noc_mask, 0, 300);
                if (ret < 0) {
                        ERROR("S2F bridge enable: "
                                        "Timeout waiting for idle ack\n");
@@ -207,37 +229,84 @@ int socfpga_bridges_enable(uint32_t mask)
 
        /* Enable f2s bridge */
        socfpga_f2s_bridge_mask(mask, &brg_mask, &f2s_idlereq,
-                                               &f2s_force_drain, &f2s_en,
-                                               &f2s_idleack, &f2s_respempty);
+                               &f2s_force_drain, &f2s_en,
+                               &f2s_idleack, &f2s_respempty, &f2s_cmdidle);
        if (brg_mask != 0U) {
                mmio_clrbits_32(SOCFPGA_RSTMGR(BRGMODRST), brg_mask);
 
-               mmio_clrbits_32(SOCFPGA_F2SDRAMMGR(SIDEBANDMGR_FLAGOUTSET0),
-                       f2s_idlereq);
+               mmio_setbits_32(SOCFPGA_F2SDRAMMGR(SIDEBANDMGR_FLAGOUTCLR0),
+                               f2s_idlereq);
+
+               ret = poll_idle_status(SOCFPGA_F2SDRAMMGR(SIDEBANDMGR_FLAGINSTATUS0),
+                                      f2s_idleack, 0, 300);
 
-               ret = poll_idle_status(SOCFPGA_F2SDRAMMGR(
-                       SIDEBANDMGR_FLAGINSTATUS0), f2s_idleack, 0);
                if (ret < 0) {
                        ERROR("F2S bridge enable: "
-                                       "Timeout waiting for idle ack");
+                             "Timeout waiting for idle ack");
                }
 
-               mmio_clrbits_32(SOCFPGA_F2SDRAMMGR(SIDEBANDMGR_FLAGOUTSET0),
-                       f2s_force_drain);
+               /* Clear the force drain */
+               mmio_setbits_32(SOCFPGA_F2SDRAMMGR(SIDEBANDMGR_FLAGOUTCLR0),
+                               f2s_force_drain);
                udelay(5);
 
                mmio_setbits_32(SOCFPGA_F2SDRAMMGR(SIDEBANDMGR_FLAGOUTSET0),
-                       f2s_en);
+                               f2s_en);
                udelay(5);
        }
 
        return ret;
 }
 
+int socfpga_bridge_nongraceful_disable(uint32_t mask)
+{
+       int ret = 0;
+       int timeout = 1000;
+       uint32_t brg_mask = 0;
+       uint32_t f2s_idlereq = 0;
+       uint32_t f2s_force_drain = 0;
+       uint32_t f2s_en = 0;
+       uint32_t f2s_idleack = 0;
+       uint32_t f2s_respempty = 0;
+       uint32_t f2s_cmdidle = 0;
+
+       socfpga_f2s_bridge_mask(mask, &brg_mask, &f2s_idlereq,
+                               &f2s_force_drain, &f2s_en,
+                               &f2s_idleack, &f2s_respempty, &f2s_cmdidle);
+
+       mmio_setbits_32(SOCFPGA_F2SDRAMMGR(SIDEBANDMGR_FLAGOUTSET0),
+                       f2s_idlereq);
+
+       /* Time out Error - Bus is still active */
+       /* Performing a non-graceful shutdown with Force drain */
+       mmio_setbits_32(SOCFPGA_F2SDRAMMGR(SIDEBANDMGR_FLAGOUTSET0),
+                       f2s_force_drain);
+
+       ret = -ETIMEDOUT;
+       do {
+               /* Read response queue status to ensure it is empty */
+               uint32_t idle_status;
+
+               idle_status = mmio_read_32(SOCFPGA_F2SDRAMMGR(SIDEBANDMGR_FLAGINSTATUS0));
+               if ((idle_status & f2s_respempty) != 0U) {
+                       idle_status = mmio_read_32(SOCFPGA_F2SDRAMMGR(SIDEBANDMGR_FLAGINSTATUS0));
+                       if ((idle_status & f2s_respempty) != 0U) {
+                               /* No time-out we are good! */
+                               ret = 0;
+                               break;
+                       }
+               }
+
+               asm("nop");
+
+       } while (timeout-- > 0);
+
+       return ret;
+}
+
 int socfpga_bridges_disable(uint32_t mask)
 {
        int ret = 0;
-       int timeout = 300;
        uint32_t brg_mask = 0;
        uint32_t noc_mask = 0;
        uint32_t f2s_idlereq = 0;
@@ -245,6 +314,7 @@ int socfpga_bridges_disable(uint32_t mask)
        uint32_t f2s_en = 0;
        uint32_t f2s_idleack = 0;
        uint32_t f2s_respempty = 0;
+       uint32_t f2s_cmdidle = 0;
 
        /* Disable s2f bridge */
        socfpga_s2f_bridge_mask(mask, &brg_mask, &noc_mask);
@@ -255,17 +325,17 @@ int socfpga_bridges_disable(uint32_t mask)
                mmio_write_32(SOCFPGA_SYSMGR(NOC_TIMEOUT), 1);
 
                ret = poll_idle_status(SOCFPGA_SYSMGR(NOC_IDLEACK),
-                                               noc_mask, noc_mask);
+                                      noc_mask, noc_mask, 300);
                if (ret < 0) {
                        ERROR("S2F Bridge disable: "
-                                       "Timeout waiting for idle ack\n");
+                             "Timeout waiting for idle ack\n");
                }
 
                ret = poll_idle_status(SOCFPGA_SYSMGR(NOC_IDLESTATUS),
-                                               noc_mask, noc_mask);
+                                      noc_mask, noc_mask, 300);
                if (ret < 0) {
                        ERROR("S2F Bridge disable: "
-                                       "Timeout waiting for idle status\n");
+                             "Timeout waiting for idle status\n");
                }
 
                mmio_setbits_32(SOCFPGA_RSTMGR(BRGMODRST), brg_mask);
@@ -275,43 +345,35 @@ int socfpga_bridges_disable(uint32_t mask)
 
        /* Disable f2s bridge */
        socfpga_f2s_bridge_mask(mask, &brg_mask, &f2s_idlereq,
-                                               &f2s_force_drain, &f2s_en,
-                                               &f2s_idleack, &f2s_respempty);
+                               &f2s_force_drain, &f2s_en,
+                               &f2s_idleack, &f2s_respempty, &f2s_cmdidle);
        if (brg_mask != 0U) {
+
+               if (mmio_read_32(SOCFPGA_RSTMGR(BRGMODRST)) & brg_mask) {
+                       /* Bridge cannot be reset twice */
+                       return 0;
+               }
+
+               /* Starts the fence and drain traffic from F2SDRAM to MPFE */
                mmio_setbits_32(SOCFPGA_RSTMGR(HDSKEN),
                                RSTMGR_HDSKEN_FPGAHSEN);
-
+               udelay(5);
+               /* Ignoring FPGA ACK as it will time-out */
                mmio_setbits_32(SOCFPGA_RSTMGR(HDSKREQ),
                                RSTMGR_HDSKREQ_FPGAHSREQ);
 
-               poll_idle_status(SOCFPGA_RSTMGR(HDSKACK),
-                               RSTMGR_HDSKACK_FPGAHSACK_MASK,
-                               RSTMGR_HDSKACK_FPGAHSACK_MASK);
+               ret = poll_idle_status_by_clkcycles(SOCFPGA_RSTMGR(HDSKACK),
+                                                   RSTMGR_HDSKACK_FPGAHSACK_MASK,
+                                                   RSTMGR_HDSKACK_FPGAHSACK_MASK, 1000);
 
-               mmio_clrbits_32(SOCFPGA_F2SDRAMMGR(SIDEBANDMGR_FLAGOUTSET0),
+               /* DISABLE F2S Bridge */
+               mmio_setbits_32(SOCFPGA_F2SDRAMMGR(SIDEBANDMGR_FLAGOUTCLR0),
                                f2s_en);
                udelay(5);
 
-               mmio_setbits_32(SOCFPGA_F2SDRAMMGR(SIDEBANDMGR_FLAGOUTSET0),
-                               f2s_force_drain);
-               udelay(5);
-
-               do {
-                       /* Read response queue status to ensure it is empty */
-                       uint32_t idle_status;
-
-                       idle_status = mmio_read_32(SOCFPGA_F2SDRAMMGR(
-                               SIDEBANDMGR_FLAGINSTATUS0));
-                       if ((idle_status & f2s_respempty) != 0U) {
-                               idle_status = mmio_read_32(SOCFPGA_F2SDRAMMGR(
-                                       SIDEBANDMGR_FLAGINSTATUS0));
-                               if ((idle_status & f2s_respempty) != 0U) {
-                                       break;
-                               }
-                       }
-                       udelay(1000);
-               } while (timeout-- > 0);
+               ret = socfpga_bridge_nongraceful_disable(mask);
 
+               /* Bridge reset */
 #if PLATFORM_MODEL == PLAT_SOCFPGA_STRATIX10
                /* Software must never write a 0x1 to FPGA2SOC_MASK bit */
                mmio_setbits_32(SOCFPGA_RSTMGR(BRGMODRST),
@@ -320,8 +382,9 @@ int socfpga_bridges_disable(uint32_t mask)
                mmio_setbits_32(SOCFPGA_RSTMGR(BRGMODRST),
                                brg_mask);
 #endif
+               /* Re-enable traffic to SDRAM*/
                mmio_clrbits_32(SOCFPGA_RSTMGR(HDSKREQ),
-                               RSTMGR_HDSKEQ_FPGAHSREQ);
+                               RSTMGR_HDSKREQ_FPGAHSREQ);
 
                mmio_setbits_32(SOCFPGA_F2SDRAMMGR(SIDEBANDMGR_FLAGOUTCLR0),
                                f2s_idlereq);