summaryrefslogtreecommitdiffstats
path: root/src/import/chips/p9/procedures/hwp
diff options
context:
space:
mode:
authorJoe McGill <jmcgill@us.ibm.com>2018-09-05 19:29:26 -0500
committerDaniel M. Crowell <dcrowell@us.ibm.com>2018-09-22 20:41:00 -0500
commit5a2e55b7708e20d0bbb40dd776ab572542bfe695 (patch)
tree33e3d5abe121dad349d67be5003cd719ba8ce311 /src/import/chips/p9/procedures/hwp
parent5b7c6b466357df2b7dd356977dae5e0003fbebdd (diff)
downloadtalos-hostboot-5a2e55b7708e20d0bbb40dd776ab572542bfe695.tar.gz
talos-hostboot-5a2e55b7708e20d0bbb40dd776ab572542bfe695.zip
SMP ABUS -- use pattern A to detect lane failures
p9_io_obus_linktrain - Prior to engaging link training, send and observe pattern A in PHY RX capture latches - Power down any failed lanes, with sparing for single lane failures or deconfiguration for multi-lane failures to be handled by DL training in downstream HWP code - Adapt flow so HWP is directly callable in CCM retraining flow p9_io_obus_dccal - Reset attributes used by p9_io_obus_linktrain -- needed to support reconfig loop IPL and CCM retraining flow p9_fab_iovalid - Update DL state machine half link fail detection logic p9_io_obus_attributes - Create new attributes to support pattern A detection scheme ATTR_IO_OBUS_PAT_A_DETECT_RUN - flag to track per half link status, ised to enable coordinated execution on endpoints without requiring HWP interface changes ATTR_IO_OBUS_PAT_A_DETECT_RX_AMP_VALUE - RX amp bias, override only ATTR_IO_OBUS_PAT_A_CAPTURE - actual RX data pipe content, for debug ATTR_IO_OBUS_LANE_PDWN - actual per-lane powerdown decisions, for debug Change-Id: Ic418000b1c50bcd6454be996e7206fa1d1690f75 CQ: SW443349 Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/65737 Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Tested-by: HWSV CI <hwsv-ci+hostboot@us.ibm.com> Tested-by: Hostboot CI <hostboot-ci+hostboot@us.ibm.com> Reviewed-by: Thi N. Tran <thi@us.ibm.com> Reviewed-by: Christopher W. Steffen <cwsteffen@us.ibm.com> Reviewed-by: Jennifer A. Stofer <stofer@us.ibm.com> Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/65739 Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com> Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/import/chips/p9/procedures/hwp')
-rw-r--r--src/import/chips/p9/procedures/hwp/io/p9_io_obus_dccal.C39
-rw-r--r--src/import/chips/p9/procedures/hwp/io/p9_io_obus_linktrain.C658
-rw-r--r--src/import/chips/p9/procedures/hwp/io/p9_io_obus_linktrain.mk1
-rw-r--r--src/import/chips/p9/procedures/hwp/io/p9_io_regs.H14
-rw-r--r--src/import/chips/p9/procedures/hwp/nest/p9_fab_iovalid.C31
5 files changed, 648 insertions, 95 deletions
diff --git a/src/import/chips/p9/procedures/hwp/io/p9_io_obus_dccal.C b/src/import/chips/p9/procedures/hwp/io/p9_io_obus_dccal.C
index bc3ac54ff..f7b24c3e5 100644
--- a/src/import/chips/p9/procedures/hwp/io/p9_io_obus_dccal.C
+++ b/src/import/chips/p9/procedures/hwp/io/p9_io_obus_dccal.C
@@ -738,8 +738,14 @@ fapi2::ReturnCode p9_io_obus_dccal( const OBUS_TGT i_tgt, const uint32_t i_lane_
FAPI_IMP( "p9_io_obus_dccal: I/O Obus Entering" );
uint8_t dccal_flags = 0x0;
uint8_t l_run_dccal = 1;
+ const uint8_t LANES = 24;
char l_tgtStr[fapi2::MAX_ECMD_STRING_LEN];
fapi2::toString( i_tgt, l_tgtStr, fapi2::MAX_ECMD_STRING_LEN );
+ fapi2::ATTR_IO_OBUS_PAT_A_DETECT_RUN_Type l_pat_a_detect_run_clear =
+ fapi2::ENUM_ATTR_IO_OBUS_PAT_A_DETECT_RUN_FALSE;
+ fapi2::ATTR_IO_OBUS_LANE_PDWN_Type l_lane_pdwn;
+ fapi2::ATTR_IO_OBUS_PAT_A_CAPTURE_Type l_pat_a_capture;
+
FAPI_DBG( "I/O Obus Dccal %s, Lane Vector(0x%X)", l_tgtStr, i_lane_vector );
FAPI_TRY( FAPI_ATTR_GET( fapi2::ATTR_PROC_FABRIC_LINK_ACTIVE, i_tgt, l_run_dccal ) );
@@ -793,7 +799,40 @@ fapi2::ReturnCode p9_io_obus_dccal( const OBUS_TGT i_tgt, const uint32_t i_lane_
FAPI_TRY( set_obus_flywheel_off( i_tgt, i_lane_vector, 0 ) );
FAPI_TRY( set_obus_pr_edge_track_cntl( i_tgt, i_lane_vector, 0 ) );
+ // reset attributes used in subsequent link training HWP calls
+ FAPI_TRY(FAPI_ATTR_SET(fapi2::ATTR_IO_OBUS_PAT_A_DETECT_RUN,
+ i_tgt,
+ l_pat_a_detect_run_clear),
+ "Error from FAPI_ATTR_SET (ATTR_IO_OBUS_PAT_A_DETECT_RUN)");
+
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_IO_OBUS_LANE_PDWN,
+ i_tgt,
+ l_lane_pdwn),
+ "Error from FAPI_ATTR_GET (ATTR_IO_OBUS_LANE_PDWN)");
+
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_IO_OBUS_PAT_A_CAPTURE,
+ i_tgt,
+ l_pat_a_capture),
+ "Error from FAPI_ATTR_GET (ATTR_IO_OBUS_PAT_A_CAPTURE)");
+
+ for (uint8_t lane = 0; lane < LANES; lane++)
+ {
+ if (((0x1 << lane) & i_lane_vector) != 0)
+ {
+ l_lane_pdwn = l_lane_pdwn & (uint32_t) (~(0x80000000 >> lane));
+ l_pat_a_capture[lane] = 0;
+ }
+ }
+
+ FAPI_TRY(FAPI_ATTR_SET(fapi2::ATTR_IO_OBUS_LANE_PDWN,
+ i_tgt,
+ l_lane_pdwn),
+ "Error from FAPI_ATTR_SET (ATTR_IO_OBUS_LANE_PDWN)");
+ FAPI_TRY(FAPI_ATTR_SET(fapi2::ATTR_IO_OBUS_PAT_A_CAPTURE,
+ i_tgt,
+ l_pat_a_capture),
+ "Error from FAPI_ATTR_SET (ATTR_IO_OBUS_PAT_A_CAPTURE)");
fapi_try_exit:
FAPI_IMP( "p9_io_obus_dccal: I/O Obus Exiting" );
diff --git a/src/import/chips/p9/procedures/hwp/io/p9_io_obus_linktrain.C b/src/import/chips/p9/procedures/hwp/io/p9_io_obus_linktrain.C
index 1795c29b9..6a1dbf94f 100644
--- a/src/import/chips/p9/procedures/hwp/io/p9_io_obus_linktrain.C
+++ b/src/import/chips/p9/procedures/hwp/io/p9_io_obus_linktrain.C
@@ -47,15 +47,10 @@
/// @endverbatim
///----------------------------------------------------------------------------
-//------------------------------------------------------------------------------
-// Defines
-//------------------------------------------------------------------------------
-
//-----------------------------------------------------------------------------
// Includes
//-----------------------------------------------------------------------------
#include <p9_io_obus_linktrain.H>
-#include <p9_io_obus_pdwn_lanes.H>
#include <p9_io_scom.H>
#include <p9_io_regs.H>
#include <p9_io_common.H>
@@ -63,9 +58,459 @@
#include <p9_obus_scom_addresses_fld.H>
//-----------------------------------------------------------------------------
-// Definitions
+// Constant Definitions
//-----------------------------------------------------------------------------
+enum p9_io_obus_linktrain_pattern_t
+{
+ PATTERN_A,
+ PATTERN_TS1,
+ PATTERN_NONE
+};
+
+//-----------------------------------------------------------------------------
+// Function Definitions
+//-----------------------------------------------------------------------------
+
+
+/**
+ * @brief Init PHY TX FIFO logic
+ * @param[in] i_tgt Reference to OBUS endpoint target
+ * @param[in] i_even Process even half link?
+ * @param[in] i_odd Process odd half link?
+ * @retval ReturnCode
+ */
+fapi2::ReturnCode
+init_tx_fifo(const OBUS_TGT& i_tgt,
+ bool i_even,
+ bool i_odd)
+{
+ const uint32_t MAX_LANES = 24;
+ const uint8_t GRP0 = 0;
+ fapi2::buffer<uint64_t> l_data = 0;
+
+ for (uint8_t l_lane = 0; l_lane < MAX_LANES; l_lane++)
+ {
+ if ((i_even && (l_lane < (MAX_LANES / 2))) ||
+ (i_odd && (l_lane >= (MAX_LANES / 2))))
+ {
+ // - Clear TX_UNLOAD_CLK_DISABLE
+ FAPI_TRY(io::read(OPT_TX_MODE2_PL, i_tgt, GRP0, l_lane, l_data));
+ io::set(OPT_TX_UNLOAD_CLK_DISABLE, 0, l_data);
+ FAPI_TRY(io::write(OPT_TX_MODE2_PL, i_tgt, GRP0, l_lane, l_data));
+
+ // - Set TX_FIFO_INIT
+ l_data.flush<0>();
+ io::set(OPT_TX_FIFO_INIT, 1, l_data);
+ FAPI_TRY(io::write(OPT_TX_CNTL1G_PL, i_tgt, GRP0, l_lane, l_data));
+
+ // - Set TX_UNLOAD_CLK_DISABLE
+ FAPI_TRY(io::read(OPT_TX_MODE2_PL, i_tgt, GRP0, l_lane, l_data));
+ io::set(OPT_TX_UNLOAD_CLK_DISABLE, 1, l_data );
+ FAPI_TRY(io::write(OPT_TX_MODE2_PL, i_tgt, GRP0, l_lane, l_data));
+ }
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+
+/**
+ * @brief Force DL to send specified repeating pattern
+ * @param[in] i_tgt OBUS endpoint target
+ * @param[in] i_even Send on even half link?
+ * @param[in] i_odd Send on odd half link?
+ * @param[in] i_pat Pattern type to send
+ * @retval ReturnCode
+ */
+fapi2::ReturnCode
+force_dl_pattern_send(
+ const OBUS_TGT& i_tgt,
+ const bool i_even,
+ const bool i_odd,
+ const p9_io_obus_linktrain_pattern_t i_pat)
+{
+ fapi2::buffer<uint64_t> l_data = 0;
+
+ if (i_pat == PATTERN_A)
+ {
+ l_data = 0x4444444444400000ULL;
+ }
+ else if (i_pat == PATTERN_TS1)
+ {
+ l_data = 0x1111111111100000ULL;
+ }
+ else if (i_pat == PATTERN_NONE)
+ {
+ l_data = 0x0ULL;
+ }
+ else
+ {
+ FAPI_ASSERT(false,
+ fapi2::IO_OBUS_INVALID_PATTERN()
+ .set_TARGET(i_tgt)
+ .set_PATTERN(i_pat),
+ "Invalid/unsupported pattern requested");
+ }
+
+ if (i_even)
+ {
+ FAPI_TRY(fapi2::putScom(i_tgt,
+ OBUS_LL0_IOOL_LINK0_TX_LANE_CONTROL,
+ l_data),
+ "Error from putScom (OBUS_LL0_IOOL_LINK0_TX_LANE_CONTROL)");
+ }
+
+ if (i_odd)
+ {
+ FAPI_TRY(fapi2::putScom(i_tgt,
+ OBUS_LL0_IOOL_LINK1_TX_LANE_CONTROL,
+ l_data),
+ "Error from putScom (OBUS_LL0_IOOL_LINK1_TX_LANE_CONTROL)");
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+/**
+ * @brief Lock CDR in cable
+ * @param[in] i_tgt OBUS endpoint target
+ * @param[in] i_even Send on even half link?
+ * @param[in] i_odd Send on odd half link?
+ * @retval ReturnCode
+ */
+fapi2::ReturnCode
+lock_cable_cdr(
+ const OBUS_TGT& i_tgt,
+ const bool i_even,
+ const bool i_odd)
+{
+ // set TX lane control to force send of TS1 pattern
+ FAPI_TRY(force_dl_pattern_send(i_tgt,
+ i_even,
+ i_odd,
+ PATTERN_TS1),
+ "Error from force_dl_pattern_send (TS1)");
+
+ // Delay to compensate for active links
+ FAPI_TRY(fapi2::delay(100000000, 1000000),
+ "Error from A-link retimer delay");
+
+ // resset TX lane control
+ FAPI_TRY(force_dl_pattern_send(i_tgt,
+ i_even,
+ i_odd,
+ PATTERN_NONE),
+ "Error from force_dl_pattern_send (reset)");
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+/**
+ * @brief If lane is bad based on pattern A comparisons, power it down to
+ * permit downstream DL training code to recognize error
+ * @param[in] i_tgt Reference to OBUS endpoint target
+ * @param[in] i_group Group to power down
+ * @param[in] i_lane Lane to power down
+ * @retval ReturnCode
+ */
+fapi2::ReturnCode
+pdwn_bad_lane(
+ const OBUS_TGT& i_tgt,
+ const uint8_t i_group,
+ const uint8_t i_lane)
+{
+ fapi2::buffer<uint64_t> l_rx_dac_cntl2_eo_pl;
+ fapi2::buffer<uint64_t> l_offset_data;
+ uint64_t l_data = 0;
+ uint32_t l_lane_pdwn = 0;
+
+ const uint8_t TIMEOUT = 200;
+ const uint64_t DLY_1MS = 1000000;
+ const uint64_t DLY_1MIL_CYCLES = 1000000;
+
+ FAPI_DBG("Start, lane=%d", i_lane);
+
+ // skip if already powered down
+ FAPI_TRY(io::read(OPT_RX_LANE_ANA_PDWN, i_tgt, i_group, i_lane, l_data),
+ "Error reading OPT_RX_LANE_ANA_PDWN");
+
+ if (io::get(OPT_RX_LANE_ANA_PDWN, l_data) == 1)
+ {
+ FAPI_DBG("Skipping this lane, already powered down");
+ goto fapi_try_exit;
+ }
+
+ FAPI_DBG("Marking powerdown");
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_IO_OBUS_LANE_PDWN,
+ i_tgt,
+ l_lane_pdwn),
+ "Error from FAPI_ATTR_GET (ATTR_IO_OBUS_LANE_PDWN)");
+ l_lane_pdwn |= (0x80000000 >> i_lane);
+ FAPI_TRY(FAPI_ATTR_SET(fapi2::ATTR_IO_OBUS_LANE_PDWN,
+ i_tgt,
+ l_lane_pdwn),
+ "Error from FAPI_ATTR_SET (ATTR_IO_OBUS_LANE_PDWN)");
+
+ // set rx_recal_abort = 1
+ FAPI_TRY(io::rmw(OPT_RX_RECAL_ABORT, i_tgt, i_group, i_lane, 0x1),
+ "Error setting OPT_RX_RECAL_ABORT");
+
+ // poll for rx_lane_busy = 0
+ for (uint8_t l_count = 0; l_count < TIMEOUT; ++l_count)
+ {
+ FAPI_TRY(io::read(OPT_RX_LANE_BUSY, i_tgt, i_group, i_lane, l_data),
+ "Error reading OPT_RX_LANE_BUSY");
+
+ if (io::get(OPT_RX_LANE_BUSY, l_data) == 0)
+ {
+ break;
+ }
+
+ FAPI_TRY(fapi2::delay(DLY_1MS, DLY_1MIL_CYCLES));
+ }
+
+ FAPI_ASSERT((io::get(OPT_RX_LANE_BUSY, l_data) == 0),
+ fapi2::IO_OBUS_PDWN_BAD_LANE_TIMEOUT()
+ .set_TARGET(i_tgt)
+ .set_GROUP(i_group)
+ .set_LANE(i_lane),
+ "Timeout waiting for RX lane busy status");
+
+ // set rx_amp_val = max
+ FAPI_TRY(io::rmw(OPT_RX_AMP_VAL, i_tgt, i_group, i_lane, 0x7F),
+ "Error setting OPT_RX_AMP_VAL");
+ // rx_a_controls (bit 3) = 1
+ FAPI_TRY(io::read(OPT_RX_A_CONTROLS, i_tgt, i_group, i_lane, l_rx_dac_cntl2_eo_pl),
+ "Error reading OPT_RX_A_CONTROLS");
+ l_rx_dac_cntl2_eo_pl.setBit < OBUS_RX0_RXPACKS0_SLICE0_RX_DAC_CNTL2_EO_PL_A_CONTROLS + 3 > ();
+ FAPI_TRY(io::write(OPT_RX_A_CONTROLS, i_tgt, i_group, i_lane, l_rx_dac_cntl2_eo_pl),
+ "Error writing OPT_RX_A_CONTROLS");
+ // rx_bank_sel_a = 1
+ FAPI_TRY(io::rmw(OPT_RX_BANK_SEL_A, i_tgt, i_group, i_lane, 0x1),
+ "Error setting OPT_RX_BANK_SEL_A");
+ // power down lane
+ FAPI_TRY(io::rmw(OPT_RX_LANE_ANA_PDWN, i_tgt, i_group, i_lane, 0x01),
+ "Error setting OPT_RX_LANE_ANA_PDWN");
+ FAPI_TRY(io::rmw(OPT_RX_LANE_DIG_PDWN, i_tgt, i_group, i_lane, 0x01),
+ "Error setting OPT_RX_LANE_DIG_PDWN");
+ FAPI_TRY(io::rmw(OPT_RX_LANE_DISABLED, i_tgt, i_group, i_lane, 0x01),
+ "Error setting OPT_RX_LANE_DISABLED");
+ FAPI_TRY(io::rmw(OPT_RX_FORCE_INIT_DONE, i_tgt, i_group, i_lane, 0x01),
+ "Error setting OPT_RX_FORCE_INIT_DONE");
+
+fapi_try_exit:
+ FAPI_DBG("End");
+ return fapi2::FAPI2_RC_SUCCESS;
+}
+
+
+/**
+ * @brief Detect if pattern A was received in RX data pipe latches
+ * @param[in] i_data_pipe 22 bits of sampled data, left aligned
+ * @retval bool (true = pattern A detected, false = pattern A not detected)
+ */
+bool
+check_pattern_A(const uint32_t i_data_pipe)
+{
+ // Maximum and minimum run length of bits. This correponds to the number of X's
+ // e.g. Pattern A is 1111111100000000.... (8 up 8 down)
+ // and can be received as 1111000000000000.... (4 up 12 down)
+ // or 1111111111110000.... (12 up 4 down)
+ const uint8_t MAX_RUN = 12;
+ const uint8_t MIN_RUN = 4;
+ const uint8_t NUM_DATA_BITS = 22;
+
+ std::vector<bool> l_data_pipe;
+ std::vector<bool> l_values;
+ std::vector<uint8_t> l_switches;
+
+ // create vector from input data (entry per bit)
+ for (uint8_t ii = 0; ii < NUM_DATA_BITS; ii++)
+ {
+ uint32_t l_bit_val = ((i_data_pipe >> (31 - ii)) & 1);
+ l_data_pipe.push_back(l_bit_val == 1);
+ }
+
+ // create value history/switch index vectors
+ for (uint8_t ii = 0; ii < NUM_DATA_BITS; ii++)
+ {
+ if (ii == 0)
+ {
+ l_values.push_back(l_data_pipe[ii]);
+ }
+ else if (l_data_pipe[ii] != l_data_pipe[ii - 1])
+ {
+ l_values.push_back(l_data_pipe[ii]);
+ l_switches.push_back(ii);
+ }
+ }
+
+ FAPI_DBG("Value history:");
+
+ for (auto l_value : l_values)
+ {
+ FAPI_DBG(" %d", (l_value) ? (1) : (0));
+ }
+
+ FAPI_DBG("Switch indexes:");
+
+ for (auto l_switch : l_switches)
+ {
+ FAPI_DBG(" %d", l_switch);
+ }
+
+ // determine if switching history is viable given runs in transmitted pattern
+ for (uint8_t ii = 0; ii < l_switches.size(); ii++)
+ {
+ // first run of bits
+ if (ii == 0)
+ {
+ // first run of bits is too long
+ if (l_switches[ii] > MAX_RUN)
+ {
+ return false;
+ }
+ }
+ // middle or last run of bits
+ else
+ {
+ if (((l_switches[ii] - l_switches[ii - 1]) < MIN_RUN) || // middle run is too short
+ ((l_switches[ii] - l_switches[ii - 1]) > MAX_RUN) || // middle run is too long
+ ((ii == (l_switches.size() - 1)) &&
+ ((NUM_DATA_BITS - l_switches[ii]) > MAX_RUN))) // last run is too long
+ {
+ return false;
+ }
+ }
+ }
+
+ // ensure that we switched 2 or 3 times
+ if ((l_switches.size() != 2) &&
+ (l_switches.size() != 3))
+ {
+ return false;
+ }
+
+ // all checks passed
+ return true;
+}
+
+
+/**
+ * @brief Detect pattern A per lane
+ * @param[in] i_rx_tgt Receive side endpoint target
+ * @param[in] i_even Run on even sub link?
+ * @param[in] i_odd Run on odd sub link?
+ * @retval ReturnCode
+ */
+fapi2::ReturnCode
+find_pattern_A(
+ const OBUS_TGT& i_rx_tgt,
+ const bool i_even,
+ const bool i_odd)
+{
+ const uint32_t MAX_LANES = 24;
+ const uint8_t GRP0 = 0;
+ fapi2::ATTR_IO_OBUS_PAT_A_CAPTURE_Type l_pat_A_capture;
+ // set default
+ fapi2::ATTR_IO_OBUS_PAT_A_DETECT_RX_AMP_VALUE_Type l_pat_A_rx_amp_value = 0;
+
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_IO_OBUS_PAT_A_CAPTURE,
+ i_rx_tgt,
+ l_pat_A_capture),
+ "Error from FAPI_ATTR_GET (ATTR_IO_OBUS_PAT_A_CAPTURE)");
+
+ // read attribute value
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_IO_OBUS_PAT_A_DETECT_RX_AMP_VALUE,
+ i_rx_tgt,
+ l_pat_A_rx_amp_value),
+ "Error from FAPI_ATTR_GET (ATTR_IO_OBUS_PAT_A_DETECT_RX_AMP_VALUE)");
+
+ for (uint8_t l_lane = 0; l_lane < MAX_LANES; l_lane++)
+ {
+ // capture only if half link containing this lane is active, and should
+ // be physically connected
+ if ((i_even && (l_lane < (MAX_LANES / 2) - 1)) ||
+ (i_odd && (l_lane >= (MAX_LANES / 2) + 1)))
+ {
+ fapi2::buffer<uint64_t> l_data_hi, l_data_lo;
+ uint32_t l_sample = 0;
+ bool l_pat_A_detected = false;
+
+ // install pre-set values for pattern detection/sampling
+ FAPI_TRY(io::rmw(OPT_RX_PIPE_SEL, i_rx_tgt, GRP0, l_lane, 2),
+ "Error setting OPT_RX_PIPE_SEL");
+ FAPI_TRY(io::rmw(OPT_RX_BANK_SEL_A, i_rx_tgt, GRP0, l_lane, 1),
+ "Error setting OPT_RX_BANK_SEL_A");
+ FAPI_TRY(io::rmw(OPT_RX_A_CONTROLS, i_rx_tgt, GRP0, l_lane, 4),
+ "Error setting OPT_RX_A_CONTROLS");
+ FAPI_TRY(io::rmw(OPT_RX_AMP_VAL, i_rx_tgt, GRP0, l_lane, l_pat_A_rx_amp_value),
+ "Error setting OPT_RX_AMP_VAL");
+ FAPI_TRY(io::rmw(OPT_RX_CAL_LANE_SEL, i_rx_tgt, GRP0, l_lane, 1),
+ "Error from io::rmw (OPT_RX_CAL_LANE_SEL), set");
+ FAPI_TRY(io::rmw(OPT_RX_DATA_PIPE_CAPTURE, i_rx_tgt, GRP0, l_lane, 1),
+ "Error from io::rmw (OPT_RX_DATA_PIPE_CAPTURE)");
+
+ // capture sample
+ // concatenate bits 0:10 of rx_data_pipe_0_15 and rx_data_pipe_16_31
+ // to get a total of 22 bits, left aligned
+ FAPI_TRY(fapi2::delay(10000, 1000),
+ "Error from pipe capture delay");
+ FAPI_TRY(io::read(OPT_RX_DATA_PIPE_0_15, i_rx_tgt, GRP0, l_lane, l_data_hi),
+ "Error from io::rmw (OPT_RX_DATA_PIPE_0_15)");
+ l_data_hi.extract<48, 11, 0>(l_sample);
+ FAPI_TRY(io::read(OPT_RX_DATA_PIPE_16_31, i_rx_tgt, GRP0, l_lane, l_data_lo),
+ "Error from io::rmw (OPT_RX_DATA_PIPE_16_31)");
+ l_data_lo.extract<48, 11, 11>(l_sample);
+ FAPI_DBG("Data 0_15: 0x%016llX, Data 16_31: 0x%016llX, Sample: 0x%06X",
+ l_data_hi(), l_data_lo(), l_sample);
+
+ // save to attribute
+ l_pat_A_capture[l_lane] = l_sample;
+
+ // determine if pattern was received
+ FAPI_DBG("Checking pattern A for lane %d", l_lane);
+ l_pat_A_detected = check_pattern_A(l_sample);
+
+ // if not, power down this lane
+ if (!l_pat_A_detected)
+ {
+ FAPI_TRY(pdwn_bad_lane(i_rx_tgt,
+ GRP0,
+ l_lane),
+ "Error from pdwn_bad_lane");
+ }
+ else
+ {
+ // reset lane parameters to default
+ FAPI_TRY(io::rmw(OPT_RX_PIPE_SEL, i_rx_tgt, GRP0, l_lane, 1),
+ "Error setting OPT_RX_PIPE_SEL");
+ FAPI_TRY(io::rmw(OPT_RX_A_CONTROLS, i_rx_tgt, GRP0, l_lane, 32),
+ "Error setting OPT_RX_A_CONTROLS");
+ FAPI_TRY(io::rmw(OPT_RX_AMP_VAL, i_rx_tgt, GRP0, l_lane, 0),
+ "Error setting OPT_RX_AMP_VAL");
+ }
+
+ // clear lane select for next iteration
+ FAPI_TRY(io::rmw(OPT_RX_CAL_LANE_SEL, i_rx_tgt, GRP0, l_lane, 0),
+ "Error from io::rmw (OPT_RX_CAL_LANE_SEL), clear");
+ }
+ }
+
+ FAPI_TRY(FAPI_ATTR_SET(fapi2::ATTR_IO_OBUS_PAT_A_CAPTURE,
+ i_rx_tgt,
+ l_pat_A_capture),
+ "Error from FAPI_ATTR_SET (ATTR_IO_OBUS_PAT_A_CAPTURE)");
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+
/**
* @brief A HWP to perform FIFO init for ABUS(OPT)
* @param[in] i_mode Linktraining Mode
@@ -75,23 +520,24 @@
fapi2::ReturnCode p9_io_obus_linktrain(const OBUS_TGT& i_tgt)
{
FAPI_IMP("p9_io_obus_linktrain: P9 I/O OPT Abus Entering");
- const uint32_t MAX_LANES = 24;
- const uint8_t GRP0 = 0;
char l_tgt_str[fapi2::MAX_ECMD_STRING_LEN];
- fapi2::toString(i_tgt, l_tgt_str, fapi2::MAX_ECMD_STRING_LEN);
- fapi2::buffer<uint64_t> l_data = 0;
+ fapi2::toString(i_tgt, l_tgt_str, fapi2::MAX_ECMD_STRING_LEN);
+ FAPI_DBG("I/O Abus FIFO init: Target(%s)", l_tgt_str);
+
+ const uint32_t MAX_LANES = 24;
+ const uint8_t GRP0 = 0;
+
+ OBUS_TGT l_rem_tgt;
fapi2::buffer<uint64_t> l_dl_control_data;
fapi2::buffer<uint64_t> l_dl_control_mask;
+ fapi2::buffer<uint64_t> l_dl_control_rem;
fapi2::ATTR_PROC_FABRIC_LINK_ACTIVE_Type l_fbc_active;
fapi2::ATTR_LINK_TRAIN_Type l_link_train;
- fapi2::ATTR_CHIP_EC_FEATURE_HW419022_Type l_hw419022 = 0;
- fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP> i_chip_target =
- i_tgt.getParent<fapi2::TARGET_TYPE_PROC_CHIP>();
+ fapi2::ATTR_CHIP_EC_FEATURE_HW419022_Type l_hw419022;
+ fapi2::ATTR_IO_OBUS_PAT_A_DETECT_RUN_Type l_pat_a_detect_run;
bool l_even = true;
bool l_odd = true;
- FAPI_DBG("I/O Abus FIFO init: Target(%s)", l_tgt_str);
-
FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_PROC_FABRIC_LINK_ACTIVE,
i_tgt,
l_fbc_active),
@@ -103,115 +549,153 @@ fapi2::ReturnCode p9_io_obus_linktrain(const OBUS_TGT& i_tgt)
goto fapi_try_exit;
}
- // PHY initialization sequence:
- // - clear TX_UNLOAD_CLK_DISABLE
- // - set TX_FIFO_INIT
- // - set TX_UNLOAD_CLK_DISABLE
- // - set RX_AC_COUPLED
-
- // Clear TX_UNLOAD_CLK_DISABLE
- for (uint32_t lane = 0; lane < MAX_LANES; ++lane)
- {
- FAPI_TRY(io::read(OPT_TX_MODE2_PL, i_tgt, GRP0, lane, l_data));
- io::set(OPT_TX_UNLOAD_CLK_DISABLE, 0, l_data);
- FAPI_TRY(io::write(OPT_TX_MODE2_PL, i_tgt, GRP0, lane, l_data));
- }
-
- // Set TX_FIFO_INIT
- l_data.flush<0>();
- io::set(OPT_TX_FIFO_INIT, 1, l_data);
-
- for (uint32_t lane = 0; lane < MAX_LANES; ++lane)
- {
- FAPI_TRY(io::write(OPT_TX_CNTL1G_PL, i_tgt, GRP0, lane, l_data));
- }
+ // find connected endpoint target
+ FAPI_TRY(i_tgt.getOtherEnd(l_rem_tgt),
+ "Error from getOtherEnd");
- // Set TX_UNLOAD_CLK_DISABLE
- for (uint32_t lane = 0; lane < MAX_LANES; ++lane)
- {
- FAPI_TRY(io::read(OPT_TX_MODE2_PL, i_tgt, GRP0, lane, l_data));
- io::set(OPT_TX_UNLOAD_CLK_DISABLE, 1, l_data );
- FAPI_TRY(io::write(OPT_TX_MODE2_PL, i_tgt, GRP0, lane, l_data));
- }
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_IO_OBUS_PAT_A_DETECT_RUN,
+ i_tgt,
+ l_pat_a_detect_run),
+ "Error from FAPI_ATTR_GET (ATTR_IO_OBUS_PAT_A_DETECT_RUN)");
FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CHIP_EC_FEATURE_HW419022,
- i_chip_target,
+ i_tgt.getParent<fapi2::TARGET_TYPE_PROC_CHIP>(),
l_hw419022),
"Error from FAPI_ATTR_GET (fapi2::ATTR_CHIP_EC_FEATURE_HW419022)");
- // Cable CDR lock
- // determine link train capabilities (half/full)
FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_LINK_TRAIN,
i_tgt,
l_link_train),
"Error from FAPI_ATTR_GET (ATTR_LINK_TRAIN)");
+ // determine link train capabilities (half/full)
l_even = (l_link_train == fapi2::ENUM_ATTR_LINK_TRAIN_BOTH) ||
(l_link_train == fapi2::ENUM_ATTR_LINK_TRAIN_EVEN_ONLY);
l_odd = (l_link_train == fapi2::ENUM_ATTR_LINK_TRAIN_BOTH) ||
(l_link_train == fapi2::ENUM_ATTR_LINK_TRAIN_ODD_ONLY);
- // set TX lane control to force send of TS1 pattern
- if (l_even)
- {
- FAPI_TRY(fapi2::putScom(i_tgt,
- OBUS_LL0_IOOL_LINK0_TX_LANE_CONTROL,
- 0x1111111111100000ULL),
- "Error from putScom (OBUS_LL0_IOOL_LINK0_TX_LANE_CONTROL)");
- }
- else
+ // run PHY init sequence + pattern A detection sequence
+ // on both connected endpoints if not yet run
+ if (l_pat_a_detect_run == fapi2::ENUM_ATTR_IO_OBUS_PAT_A_DETECT_RUN_FALSE)
{
- const uint32_t EVEN_LANES = 0x000007FF;
- FAPI_TRY(p9_io_obus_pdwn_lanes(i_tgt, EVEN_LANES),
- "Error from p9_io_obus_pdwn_lanes");
- }
+ FAPI_TRY(init_tx_fifo(i_tgt,
+ l_even,
+ l_odd),
+ "Error from init_tx_fifo, local end");
+ FAPI_TRY(init_tx_fifo(l_rem_tgt,
+ l_even,
+ l_odd),
+ "Error from init_tx_fifo, remote end");
- if (l_odd)
- {
- FAPI_TRY(fapi2::putScom(i_tgt,
- OBUS_LL0_IOOL_LINK1_TX_LANE_CONTROL,
- 0x1111111111100000ULL),
- "Error from putScom (OBUS_LL0_IOOL_LINK1_TX_LANE_CONTROL)");
- }
- else
- {
- const uint32_t ODD_LANES = 0x00FFE000;
- FAPI_TRY(p9_io_obus_pdwn_lanes(i_tgt, ODD_LANES),
- "Error from p9_io_obus_pdwn_lanes");
+ // send TS1 for Cable CDR lock
+ FAPI_TRY(lock_cable_cdr(i_tgt,
+ l_even,
+ l_odd),
+ "Error from lock_cable_cdr, local end, pre pattern A");
+
+ FAPI_TRY(lock_cable_cdr(l_rem_tgt,
+ l_even,
+ l_odd),
+ "Error from lock_cable_cdr, remote end, pre pattern A");
+
+ // execute sequence to send pattern A and check receipt of pattern
+ // in PHY RX data pipe logic on connected endpoint -- lanes which
+ // do not see expected pattern will be powered down (sparing for
+ // single lane faults, or training failure for multi lane faults
+ // will be handled in p9_smp_link_layer)
+ FAPI_TRY(force_dl_pattern_send(i_tgt,
+ l_even,
+ l_odd,
+ PATTERN_A),
+ "Error from force_dl_pattern_send, pattern A, local end");
+ FAPI_TRY(force_dl_pattern_send(l_rem_tgt,
+ l_even,
+ l_odd,
+ PATTERN_A),
+ "Error from force_dl_pattern_send, pattern A, remote end");
+
+ // power down any unneeded lanes (not physically connected or
+ // unused half-link)
+ for (uint8_t ii = 0; ii < MAX_LANES; ii++)
+ {
+ if (((ii >= ((MAX_LANES / 2) - 1)) && (ii <= (MAX_LANES / 2))) || // unused lanes, always pdwn
+ (!l_even && (ii < ((MAX_LANES / 2) - 1))) || // even link is unused
+ (!l_odd && (ii >= ((MAX_LANES / 2) + 1)))) // odd link is unused
+ {
+ FAPI_TRY(pdwn_bad_lane(i_tgt,
+ GRP0,
+ ii),
+ "Error from pdwn_bad_lane, even, local end, lane: %d",
+ ii);
+ FAPI_TRY(pdwn_bad_lane(l_rem_tgt,
+ GRP0,
+ ii),
+ "Error from pdwn_bad_lane, even, remote end, lane: %d",
+ ii);
+ }
+ }
+
+ // Delay to compensate for pattern
+ FAPI_TRY(fapi2::delay(100000000, 1000000),
+ "Error from pattern A delay");
+
+ // detect pattern on RX side
+ FAPI_TRY(find_pattern_A(l_rem_tgt,
+ l_even,
+ l_odd),
+ "Error from find_pattern_A, local TX, remote RX");
+
+ FAPI_TRY(find_pattern_A(i_tgt,
+ l_even,
+ l_odd),
+ "Error from find_pattern_A, remote TX, local RX");
+
+ // switch off pattern A
+ FAPI_TRY(force_dl_pattern_send(i_tgt,
+ l_even,
+ l_odd,
+ PATTERN_NONE),
+ "Error from force_dl_pattern_send, idle, local end");
+ FAPI_TRY(force_dl_pattern_send(l_rem_tgt,
+ l_even,
+ l_odd,
+ PATTERN_NONE),
+ "Error from force_dl_pattern_send, idle, remote end");
+
+ // mark both endpoints as run
+ l_pat_a_detect_run = fapi2::ENUM_ATTR_IO_OBUS_PAT_A_DETECT_RUN_TRUE;
+ FAPI_TRY(FAPI_ATTR_SET(fapi2::ATTR_IO_OBUS_PAT_A_DETECT_RUN,
+ i_tgt,
+ l_pat_a_detect_run),
+ "Error from FAPI_ATTR_SET (ATTR_IO_OBUS_PAT_A_DETECT_RUN), local end");
+ FAPI_TRY(FAPI_ATTR_SET(fapi2::ATTR_IO_OBUS_PAT_A_DETECT_RUN,
+ l_rem_tgt,
+ l_pat_a_detect_run),
+ "Error from FAPI_ATTR_SET (ATTR_IO_OBUS_PAT_A_DETECT_RUN), remote end");
}
- // Delay to compensate for active links
- FAPI_TRY(fapi2::delay(100000000, 1000000),
- "Error from A-link retimer delay");
+ // resend TS1 for Cable CDR lock and start phy training
+ FAPI_TRY(lock_cable_cdr(i_tgt,
+ l_even,
+ l_odd),
+ "Error from lock_cable_cdr, local end, post pattern A");
// DD1.1+ HW Start training sequence
if(!l_hw419022)
{
- // clear TX lane control overrides
if (l_even)
{
l_dl_control_data.setBit<OBUS_LL0_IOOL_CONTROL_LINK0_PHY_TRAINING>();
l_dl_control_mask.setBit<OBUS_LL0_IOOL_CONTROL_LINK0_PHY_TRAINING>();
-
- FAPI_TRY(fapi2::putScom(i_tgt,
- OBUS_LL0_IOOL_LINK0_TX_LANE_CONTROL,
- 0x0000000000000000ULL),
- "Error from putScom (OBUS_LL0_IOOL_LINK0_TX_LANE_CONTROL)");
}
if (l_odd)
{
l_dl_control_data.setBit<OBUS_LL0_IOOL_CONTROL_LINK1_PHY_TRAINING>();
l_dl_control_mask.setBit<OBUS_LL0_IOOL_CONTROL_LINK1_PHY_TRAINING>();
-
- FAPI_TRY(fapi2::putScom(i_tgt,
- OBUS_LL0_IOOL_LINK1_TX_LANE_CONTROL,
- 0x0000000000000000ULL),
- "Error from putScom (OBUS_LL0_IOOL_LINK1_TX_LANE_CONTROL)");
}
- // Start phy training
FAPI_TRY(fapi2::putScomUnderMask(i_tgt,
OBUS_LL0_IOOL_CONTROL,
l_dl_control_data,
diff --git a/src/import/chips/p9/procedures/hwp/io/p9_io_obus_linktrain.mk b/src/import/chips/p9/procedures/hwp/io/p9_io_obus_linktrain.mk
index 6c500c8d8..03e3311f9 100644
--- a/src/import/chips/p9/procedures/hwp/io/p9_io_obus_linktrain.mk
+++ b/src/import/chips/p9/procedures/hwp/io/p9_io_obus_linktrain.mk
@@ -24,5 +24,4 @@
# IBM_PROLOG_END_TAG
PROCEDURE=p9_io_obus_linktrain
OBJS+=p9_io_common.o
-OBJS+=p9_io_obus_pdwn_lanes.o
$(call BUILD_PROCEDURE)
diff --git a/src/import/chips/p9/procedures/hwp/io/p9_io_regs.H b/src/import/chips/p9/procedures/hwp/io/p9_io_regs.H
index 3b0156d6b..1c913135c 100644
--- a/src/import/chips/p9/procedures/hwp/io/p9_io_regs.H
+++ b/src/import/chips/p9/procedures/hwp/io/p9_io_regs.H
@@ -515,7 +515,9 @@
#define OPT_RX_PRBS_TEST_DATA 0x800008000000003f, 55, 3 // prbs test data
#define OPT_RX_B_BANK_CONTROLS 0x800008000000003f, 58, 6 // power down pins, 0=cml2cmos, 1=ctle, 2=dac, 3=deserializer, 4=integrator, 5=phase rotator
#define OPT_RX_DAC_CNTL1_EO_PL 0x800008000000003f, 48, 16 // register -- description
+*/
#define OPT_RX_A_CONTROLS 0x800010000000003f, 48, 6 // bit0 dfe h1 speculation mux select override enables speculation\r\n\tbit1 dfe h1 speculation mux select override\r\n\tbit2 when set, put this lanes front end into offset cancellation mode. also needed for common mode calibration.\r\n\tbit3 enables the amp dac for measurements in this bank/nbit4 enables fence for initloff\r\n\tbit5 disables all the h-dacs when a 1\r\n\tcpg
+/*
#define OPT_RX_CM_CNTL 0x800010000000003f, 54, 3 // bit0 enables integrator common mode cal, used in conjunction with integrator cal enable\r\n\tbit1 is the polarity bit\r\n\tbit 2 is common mode even when 1, odd when 0 /ncpg
#define OPT_RX_DAC_CNTL2_EO_PL 0x800010000000003f, 48, 16 // register -- description
#define OPT_RX_A_OFFSET_E0 0x800018000000003f, 48, 7 // this is the vertical offset of the even low threshold sampling latch.
@@ -534,7 +536,9 @@
#define OPT_RX_A_H1E_VAL 0x800038000000003f, 48, 7 // dfe h1 value for even samplers
#define OPT_RX_A_H1O_VAL 0x800038000000003f, 56, 7 // dfe h1 value for odd samplers
#define OPT_RX_DAC_CNTL7_EO_PL 0x800038000000003f, 48, 16 // register -- description
+*/
#define OPT_RX_AMP_VAL 0x800040000000003f, 48, 8 // rx ampdac value stored as sign magnitude
+/*
#define OPT_RX_DAC_CNTL8_EO_PL 0x800040000000003f, 48, 16 // register -- description
#define OPT_RX_B_CONTROLS 0x800080000000003f, 48, 5 // bit0 dfe h1 speculation mux select override enables speculation\r\n\tbit1 dfe h1 speculation mux select override\r\n\tbit2 when set, put this lanes front end into offset cancellation mode. also needed for common mode calibration.\r\n\tbit3 enables the amp dac for measurements in this bank/nbit4 enables fence for initloff\r\n\tcpg
#define OPT_RX_DAC_CNTL1_O_PL 0x800080000000003f, 48, 16 // register -- description
@@ -615,9 +619,11 @@
#define OPT_RX_PR_PHASE_STEP_COARSE 0x800238000000003f, 53, 4 // phase step in coarse mode. see rx_pr_phase_step for a description.
#define OPT_RX_PR_COARSE_MODE_TIMER_SEL 0x800238000000003f, 57, 2 // selects how long to remain in coarse mode; the timer is always reset on an invalid lock. 00: ~1.3us, 01: ~2.6us, 10: ~5.2us, 11: ~10.5us
#define OPT_RX_BIT_MODE4_EO_PL 0x800238000000003f, 48, 16 // register -- description
+*/
#define OPT_RX_CAL_LANE_SEL 0x800240000000003f, 48, 1 // selects which lane to recalibrate.
#define OPT_RX_PIPE_SEL 0x800240000000003f, 49, 2 // selects what to mux onto the data pipe bus going to the calibration logic. \r\n\t00: first half main data, second half alt data \r\n\t01: first half main data, second half edge data \r\n\t10: double width deserialized main data \r\n\t11: reserved
#define OPT_RX_BANK_SEL_A 0x800240000000003f, 51, 1 // selects which data bank to select for main data samples and alt data samples. \r\n\t0:(datab) data bank b is selected for main data, and data bank a is selected for alt data \r\n\t1:(dataa) data bank a is selected for main data, and data bank b is selected for alt data.
+/*
#define OPT_RX_PIPE_MARGIN 0x800240000000003f, 52, 1 // adds extra cycles of padding on the async data pipe handshake
#define OPT_RX_SCOPE_MODE 0x800240000000003f, 53, 2 // adds extra cycles in the asyc crossing for scope mode
#define OPT_RX_BIST_PIPE_DATA_SHIFT 0x800240000000003f, 57, 1 // selects what to mux onto the data pipe bus going to the rx_bist engine to get upper order lanes on edge and alt only \r\n\t0: no shift \r\n\t1: shift data
@@ -682,9 +688,11 @@
#define OPT_RX_RUN_LANE 0x800320000000003f, 48, 1 // run training and subsequent recalibration on given lane
#define OPT_RX_RUN_DCCAL 0x800320000000003f, 49, 1 // run on-die dc training on given lane
#define OPT_RX_RECAL_REQ 0x800320000000003f, 50, 1 // request recalibration on given lane
+*/
#define OPT_RX_RECAL_ABORT 0x800320000000003f, 51, 1 // stop recalibration on given lane
#define OPT_RX_LANE_DISABLED 0x800320000000003f, 52, 1 // used to set the given lane to be ignored by training logic. this does not affect powerdown.
#define OPT_RX_FORCE_INIT_DONE 0x800320000000003f, 53, 1 // force init_done output port for this lane to one.
+/*
#define OPT_RX_FORCE_RECAL_DONE 0x800320000000003f, 54, 1 // force recal_done output port for this lane to one.
#define OPT_RX_GLBSM_PL_CNTL1_O_PL 0x800320000000003f, 48, 16 // register -- description
#define OPT_RX_INIT_DONE 0x800328000000003f, 48, 1 // initial training complete on given lane
@@ -1052,7 +1060,9 @@
#define OPT_RX_BER_COUNT_CLR 0x800b88000000003f, 49, 1 // diag ber error counter clear pulse. when written to a 1 the per-lane error counters are cleared to all zeroes. writing both this bit and the timer clear bit to a 1 will clear both and allow a new set of measurements to be run.
#define OPT_RX_BER_TIMER_CLR 0x800b88000000003f, 50, 1 // diag ber timer clear pulse. when written to a 1 the timers are cleared to all zeroes. writing both this bit and the error counter clear bit to a 1 will clear both and allow a new set of measurements to be run.
#define OPT_RX_SCOPE_CAPTURE 0x800b88000000003f, 51, 1 // when written to a 1 it will cause the scope capture register to copy the current main input
+*/
#define OPT_RX_DATA_PIPE_CAPTURE 0x800b88000000003f, 52, 1 // data pipe capture clear pulse. when written to a 1 it will capture and freeze new data pipe data.
+/*
#define OPT_RX_RESET_SERVO_STATUS 0x800b88000000003f, 53, 1 // data pipe capture clear pulse. when written to a 1 it will capture and freeze new data pipe data.
#define OPT_RX_BER_RESET 0x800b88000000003f, 54, 1 // diag ber reset pulse. when written to a 1 it will clear both the error counter and timer.
#define OPT_RX_DATASM_CNTLX1_EO_PG 0x800b88000000003f, 48, 16 // register -- description
@@ -1066,9 +1076,13 @@
#define OPT_RX_DATASM_STAT2_EO_PG 0x800b98000000003f, 48, 16 // register -- description
#define OPT_RX_BER_TIMER_VALUE_16_31 0x800ba0000000003f, 48, 16 // pl diag ber timer value, bits 16-31.
#define OPT_RX_DATASM_STAT3_EO_PG 0x800ba0000000003f, 48, 16 // register -- description
+*/
#define OPT_RX_DATA_PIPE_0_15 0x800ba8000000003f, 48, 16 // data pipe captured output bits 0-15.
+/*
#define OPT_RX_DATASM_STAT4_EO_PG 0x800ba8000000003f, 48, 16 // register -- description
+*/
#define OPT_RX_DATA_PIPE_16_31 0x800bb0000000003f, 48, 16 // data pipe captured output bits 16-31.
+/*
#define OPT_RX_DATASM_STAT5_EO_PG 0x800bb0000000003f, 48, 16 // register -- description
#define OPT_RX_SERVO_STATUS 0x800bb8000000003f, 48, 16 // per group servo status. , bits 0-10 are the servo op captured, bits 11-15 are the lane captured. no error if bits 0 to 10 are all zeroes
#define OPT_RX_DATASM_STAT6_EO_PG 0x800bb8000000003f, 48, 16 // register -- description
diff --git a/src/import/chips/p9/procedures/hwp/nest/p9_fab_iovalid.C b/src/import/chips/p9/procedures/hwp/nest/p9_fab_iovalid.C
index a94372225..9f1a45f6b 100644
--- a/src/import/chips/p9/procedures/hwp/nest/p9_fab_iovalid.C
+++ b/src/import/chips/p9/procedures/hwp/nest/p9_fab_iovalid.C
@@ -598,9 +598,9 @@ fapi2::ReturnCode p9_fab_iovalid_link_validate(
fapi2::ATTR_LINK_TRAIN_Type l_loc_link_train;
fapi2::ATTR_LINK_TRAIN_Type l_loc_link_train_next;
bool l_dl_trained = false;
- uint8_t l_dl_status_even = 0;
+ uint8_t l_dl_status_even = 0, l_dl_prior_status_even = 0;
bool l_dl_fail_even = false;
- uint8_t l_dl_status_odd = 0;
+ uint8_t l_dl_status_odd = 0, l_dl_prior_status_odd = 0;
bool l_dl_fail_odd = false;
uint8_t l_tl_trained = 0;
uint32_t l_poll_loops = DL_MAX_POLL_LOOPS;
@@ -637,10 +637,18 @@ fapi2::ReturnCode p9_fab_iovalid_link_validate(
XBUS_LL0_IOEL_DLL_STATUS_LINK0_CURRENT_STATE_LEN>
(l_dl_status_even);
+ l_dl_status_reg.extractToRight<XBUS_LL0_IOEL_DLL_STATUS_LINK0_PRIOR_STATE,
+ XBUS_LL0_IOEL_DLL_STATUS_LINK0_PRIOR_STATE_LEN>
+ (l_dl_prior_status_even);
+
l_dl_status_reg.extractToRight<XBUS_LL0_IOEL_DLL_STATUS_LINK1_CURRENT_STATE,
XBUS_LL0_IOEL_DLL_STATUS_LINK1_CURRENT_STATE_LEN>
(l_dl_status_odd);
+ l_dl_status_reg.extractToRight<XBUS_LL0_IOEL_DLL_STATUS_LINK1_PRIOR_STATE,
+ XBUS_LL0_IOEL_DLL_STATUS_LINK1_PRIOR_STATE_LEN>
+ (l_dl_prior_status_odd);
+
if (l_loc_link_train == fapi2::ENUM_ATTR_LINK_TRAIN_BOTH)
{
l_dl_trained = l_dl_fir_reg.getBit<DL_FIR_LINK0_TRAINED_BIT>() &&
@@ -648,11 +656,20 @@ fapi2::ReturnCode p9_fab_iovalid_link_validate(
if (!l_dl_trained)
{
- l_dl_fail_even = !(((l_dl_status_even == 0x8) && ((l_dl_status_odd >= 0xB) && (l_dl_status_odd <= 0xE))) ||
- ((l_dl_status_even == 0x2) && ((l_dl_status_odd >= 0x8) && (l_dl_status_odd <= 0x9))));
- l_dl_fail_odd = !(((l_dl_status_odd == 0x8) && ((l_dl_status_even >= 0xB) && (l_dl_status_even <= 0xE))) ||
- ((l_dl_status_odd == 0x2) && ((l_dl_status_even >= 0x8) && (l_dl_status_even <= 0x9))));
+ l_dl_fail_even = !((((l_dl_status_even == 0x8) || (l_dl_prior_status_even == 0x8) || (l_dl_status_even == 0x9)
+ || (l_dl_prior_status_even == 0x9)) &&
+ ((l_dl_status_odd >= 0xB) && (l_dl_status_odd <= 0xE))) ||
+ ((l_dl_status_even == 0x2) && ((l_dl_status_odd >= 0x8) && (l_dl_status_odd <= 0xC))));
+ l_dl_fail_odd = !((((l_dl_status_odd == 0x8) || (l_dl_prior_status_odd == 0x8) || (l_dl_status_odd == 0x9)
+ || (l_dl_prior_status_odd == 0x9)) &&
+ ((l_dl_status_even >= 0xB) && (l_dl_status_even <= 0xE))) ||
+ ((l_dl_status_odd == 0x2) && ((l_dl_status_even >= 0x8) && (l_dl_status_even <= 0xC))));
}
+
+ FAPI_DBG("even -- fail: %d, status_even: %X, prior_status_even: %X", l_dl_fail_even ? (1) : (0), l_dl_status_even,
+ l_dl_prior_status_even);
+ FAPI_DBG("odd -- fail: %d, status_odd: %X, prior_status_odd: %X", l_dl_fail_odd ? (1) : (0), l_dl_status_odd,
+ l_dl_prior_status_odd);
}
else if (l_loc_link_train == fapi2::ENUM_ATTR_LINK_TRAIN_EVEN_ONLY)
{
@@ -721,7 +738,7 @@ fapi2::ReturnCode p9_fab_iovalid_link_validate(
}
else
{
- FAPI_DBG("XBUS - Skipping check for DL lane failures");
+ FAPI_DBG("Skipping check for DL lane failures");
}
// control reconfig loop behavior
OpenPOWER on IntegriCloud