summaryrefslogtreecommitdiffstats
path: root/src/import/chips/p9/procedures
diff options
context:
space:
mode:
authorBrian Silver <bsilver@us.ibm.com>2016-06-28 13:11:09 -0500
committerDaniel M. Crowell <dcrowell@us.ibm.com>2016-07-21 17:15:48 -0400
commita0fe75642c8e289f48153d8cb093d6776d1bd10d (patch)
tree29196194bb314c3aac203d2cbc0fb907f8ef992c /src/import/chips/p9/procedures
parent872cf1dfc799619ae44b6c3561a1e9cbb5708eda (diff)
downloadtalos-hostboot-a0fe75642c8e289f48153d8cb093d6776d1bd10d.tar.gz
talos-hostboot-a0fe75642c8e289f48153d8cb093d6776d1bd10d.zip
Add flush, init io to phy reset
Change-Id: I592762b492eb8da0542121262ecc9a2af9e2ff3b RTC: 156940 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/26632 Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Tested-by: Hostboot CI <hostboot-ci+hostboot@us.ibm.com> Reviewed-by: ANDRE A. MARIN <aamarin@us.ibm.com> Reviewed-by: STEPHEN GLANCY <sglancy@us.ibm.com> Reviewed-by: Jennifer A. Stofer <stofer@us.ibm.com> Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/26639 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')
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/phy/adr32s.C7
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/phy/adr32s.H74
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/phy/ddr_phy.C83
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/phy/ddr_phy.H24
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/phy/dp16.C12
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/phy/dp16.H83
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/p9_mss_ddr_phy_reset.C11
7 files changed, 244 insertions, 50 deletions
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/phy/adr32s.C b/src/import/chips/p9/procedures/hwp/memory/lib/phy/adr32s.C
index ed7a10b07..039eee50e 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/phy/adr32s.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/phy/adr32s.C
@@ -40,5 +40,12 @@ const std::vector<uint64_t> adr32sTraits<fapi2::TARGET_TYPE_MCA>::DLL_CNFG_REG =
MCA_DDRPHY_ADR_DLL_CNTL_P0_ADR32S1
};
+// Definition of the ADR32S output driver registers
+const std::vector<uint64_t> adr32sTraits<fapi2::TARGET_TYPE_MCA>::OUTPUT_DRIVER_REG =
+{
+ MCA_DDRPHY_ADR_OUTPUT_DRIVER_FORCE_VALUE0_P0_ADR32S0,
+ MCA_DDRPHY_ADR_OUTPUT_DRIVER_FORCE_VALUE0_P0_ADR32S1
+};
+
}
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/phy/adr32s.H b/src/import/chips/p9/procedures/hwp/memory/lib/phy/adr32s.H
index 2294db408..6d3ccb0d3 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/phy/adr32s.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/phy/adr32s.H
@@ -74,6 +74,7 @@ class adr32sTraits<fapi2::TARGET_TYPE_MCA>
// MCA ADR32S control registers all come in pairs.
static const std::vector<uint64_t> DLL_CNFG_REG;
+ static const std::vector<uint64_t> OUTPUT_DRIVER_REG;
enum
{
@@ -93,6 +94,9 @@ class adr32sTraits<fapi2::TARGET_TYPE_MCA>
DLL_CNTL_CAL_ERROR = MCA_DDRPHY_ADR_DLL_CNTL_P0_ADR32S0_ADR0_CAL_ERROR,
DLL_CNTL_CAL_ERROR_FINE = MCA_DDRPHY_ADR_DLL_CNTL_P0_ADR32S0_ADR0_CAL_ERROR_FINE,
+ FLUSH = MCA_DDRPHY_ADR_OUTPUT_FORCE_ATEST_CNTL_P0_ADR32S0_ADR0_FLUSH,
+ INIT_IO = MCA_DDRPHY_ADR_OUTPUT_FORCE_ATEST_CNTL_P0_ADR32S0_ADR0_INIT_IO,
+
};
};
@@ -144,7 +148,7 @@ fapi_try_exit:
///
/// @brief Set the DLL cal reset (begins DLL cal operations)
-/// @tparam T fapi2 Target Type - derived
+/// @tparam T fapi2 Target Type - defaults to TARGET_TYPE_MCA
/// @tparam TT traits type defaults to adr32sTraits<T>
/// @param[in] o_data the value of the register
/// @param[in] i_state mss::LOW or mss::HIGH representing the state of the bit
@@ -157,6 +161,74 @@ inline void set_dll_cal_reset( fapi2::buffer<uint64_t>& o_data, const states i_s
o_data.writeBit<TT::DLL_CNTL_INIT_RXDLL_CAL_RESET>(i_state);
}
+///
+/// @brief Read OUTPUT_DRVIER register
+/// @tparam I ADR32S instance e.g., 0 or 1 for a 64 bit implementation of the PHY
+/// @tparam T fapi2 Target Type - derived
+/// @tparam TT traits type defaults to adr32sTraits<T>
+/// @param[in] i_target the fapi2 target of the port
+/// @param[out] o_data the value of the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< uint64_t I, fapi2::TargetType T, typename TT = adr32sTraits<T> >
+inline fapi2::ReturnCode read_output_driver( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
+{
+ static_assert( I < TT::ADR32S_COUNT, "adr32s instance out of range");
+ FAPI_TRY( mss::getScom(i_target, TT::OUTPUT_DRIVER_REG[I], o_data) );
+ FAPI_INF("output_driver adrs32%d: 0x%016lx", I, o_data);
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Write OUTPUT_DRIVER
+/// @tparam I ADR32S instance e.g., 0 or 1 for a 64 bit implementation of the PHY
+/// @tparam T fapi2 Target Type - derived
+/// @tparam TT traits type defaults to adr32sTraits<T>
+/// @param[in] i_target the fapi2 target of the port
+/// @param[in] i_data the value of the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< uint64_t I, fapi2::TargetType T, typename TT = adr32sTraits<T> >
+inline fapi2::ReturnCode write_output_driver( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
+{
+ static_assert( I < TT::ADR32S_COUNT, "adr32s instance out of range");
+ FAPI_INF("output_driver adr32s%d: 0x%016lx", I, i_data);
+ FAPI_TRY( mss::putScom(i_target, TT::OUTPUT_DRIVER_REG[I], i_data) );
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Set the output flush
+/// @tparam T fapi2 Target Type - defaults to TARGET_TYPE_MCA
+/// @tparam TT traits type defaults to adr32sTraits<T>
+/// @param[in] o_data the value of the register
+/// @param[in] i_state mss::LOW or mss::HIGH representing the state of the bit
+/// @note Default state is 'low' as writing a 0 forces the cal to begin.
+///
+template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCA, typename TT = adr32sTraits<T> >
+inline void set_output_flush( fapi2::buffer<uint64_t>& o_data, const states i_state )
+{
+ FAPI_INF("set_output_flush %s", (i_state == mss::LOW ? "low" : "high"));
+ o_data.writeBit<TT::FLUSH>(i_state);
+}
+
+///
+/// @brief Set the init io state
+/// @tparam T fapi2 Target Type - defaults to TARGET_TYPE_MCA
+/// @tparam TT traits type defaults to adr32sTraits<T>
+/// @param[in] o_data the value of the register
+/// @param[in] i_state mss::LOW or mss::HIGH representing the state of the bit
+/// @note Default state is 'low' as writing a 0 forces the cal to begin.
+///
+template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCA, typename TT = adr32sTraits<T> >
+inline void set_init_io( fapi2::buffer<uint64_t>& o_data, const states i_state )
+{
+ FAPI_INF("set_init_io %s", (i_state == mss::LOW ? "low" : "high"));
+ o_data.writeBit<TT::INIT_IO>(i_state);
+}
+
} // close namespace adr
} // close namespace mss
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/phy/ddr_phy.C b/src/import/chips/p9/procedures/hwp/memory/lib/phy/ddr_phy.C
index cc13bb9d5..ca8207327 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/phy/ddr_phy.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/phy/ddr_phy.C
@@ -306,43 +306,6 @@ fapi_try_exit:
}
///
-/// @brief Flush the DDR PHY
-/// @param[in] i_target the mcbist target
-/// @return FAPI2_RC_SUCCES iff ok
-///
-fapi2::ReturnCode ddr_phy_flush( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target )
-{
- fapi2::buffer<uint64_t> l_data;
- fapi2::buffer<uint64_t> l_mask;
-
- FAPI_INF( "Performing mss_ddr_phy_flush routine" );
-
- FAPI_INF("ADR/DP18 FLUSH: 1) set PC_POWERDOWN_1 register, powerdown enable(48), flush bit(58)");
- // set MASTER_PD_CNTL bit set WR_FIFO_STAB bit
- l_data.setBit<48>().setBit<58>();
- l_mask.setBit<48>().setBit<58>();
-
- const auto l_ports = mss::find_targets<TARGET_TYPE_MCA>(i_target);
-
- for (const auto& p : l_ports)
- {
- FAPI_TRY(mss::putScomUnderMask(p, MCA_DDRPHY_PC_POWERDOWN_1_P0, l_data, l_mask) );
- }
-
- fapi2::delay(DELAY_100NS, cycles_to_simcycles(ns_to_cycles(i_target, 100)));
-
- FAPI_INF("ADR/DP18 FLUSH: 2) clear PC_POWERDOWN_1 register, powerdown enable(48), flush bit(58)");
-
- for (const auto& p : l_ports)
- {
- FAPI_TRY(mss::putScomUnderMask(p, MCA_DDRPHY_PC_POWERDOWN_1_P0, 0, l_mask) );
- }
-
-fapi_try_exit:
- return fapi2::current_err;
-}
-
-///
/// @brief Return the DIMM target for the primary rank in the specificed rank pair
/// @param[in] i_target the MCA target
/// @param[in] i_rp the rank pair
@@ -1105,5 +1068,51 @@ fapi_try_exit:
return fapi2::current_err;
}
+///
+/// @brief Flush the output drivers
+/// @param[in] i_target the target associated with the phy reset sequence
+/// @return FAPI2_RC_SUCCESS iff setup was successful
+///
+template<>
+fapi2::ReturnCode flush_output_drivers( const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_target )
+{
+ fapi2::buffer<uint64_t> l_adr_data;
+ fapi2::buffer<uint64_t> l_dp16_data;
+
+ const auto l_ports = mss::find_targets<TARGET_TYPE_MCA>(i_target);
+ const auto& l_force_atest_reg = adr32sTraits<TARGET_TYPE_MCA>::OUTPUT_DRIVER_REG;
+ const auto& l_data_dir_reg = dp16Traits<TARGET_TYPE_MCA>::DATA_BIT_DIR1;
+
+ // 8. Set FLUSH=1 and INIT_IO=1 in the DDRPHY_ADR_OUTPUT_FORCE_ATEST_CNTL and DDRPHY_DP16_DATA_BIT_DIR1 register
+ {
+ mss::adr32s::set_output_flush( l_adr_data, mss::HIGH );
+ mss::adr32s::set_init_io( l_adr_data, mss::HIGH);
+ FAPI_TRY( mss::scom_blastah(l_ports, l_force_atest_reg, l_adr_data) );
+
+ mss::dp16::set_output_flush( l_dp16_data, mss::HIGH );
+ mss::dp16::set_init_io( l_dp16_data, mss::HIGH);
+ FAPI_TRY( mss::scom_blastah(l_ports, l_data_dir_reg, l_adr_data) );
+ }
+
+ // 9. Wait at least 32 dphy_gckn clock cycles.
+ fapi2::delay(mss::cycles_to_ns(i_target, 32), mss::cycles_to_simcycles(1024));
+
+ // 10. Set FLUSH=0 and INIT_IO=0 in the DDRPHY_ADR_OUTPUT_FORCE_ATEST_CNTL register and
+ // DDRPHY_DP16_DATA_BIT_DIR1 register
+ {
+ mss::adr32s::set_output_flush( l_adr_data, mss::LOW );
+ mss::adr32s::set_init_io( l_adr_data, mss::LOW);
+ FAPI_TRY( mss::scom_blastah(l_ports, l_force_atest_reg, l_adr_data) );
+
+ mss::dp16::set_output_flush( l_dp16_data, mss::LOW );
+ mss::dp16::set_init_io( l_dp16_data, mss::LOW);
+ FAPI_TRY( mss::scom_blastah(l_ports, l_data_dir_reg, l_adr_data) );
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
}
+} // ns mss
+
+
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/phy/ddr_phy.H b/src/import/chips/p9/procedures/hwp/memory/lib/phy/ddr_phy.H
index 1d7cff95b..95765ba03 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/phy/ddr_phy.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/phy/ddr_phy.H
@@ -90,13 +90,6 @@ fapi2::ReturnCode setup_phase_rotator_control_registers( const fapi2::Target<fap
fapi2::ReturnCode deassert_sysclk_reset( const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_target );
///
-/// @brief Flush the DDR PHY
-/// @param[in] i_target the mcbist target
-/// @return FAPI2_RC_SUCCES iff ok
-///
-fapi2::ReturnCode ddr_phy_flush( const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_target );
-
-///
/// @brief Reset the training delay configureation
/// @param[in] i_target the mcbist target
/// @return FAPI2_RC_SUCCES iff ok
@@ -221,6 +214,23 @@ template<>
fapi2::ReturnCode dll_calibration( const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_target );
///
+/// @brief Flush the output drivers
+/// @tparam T the target type of the MCBIST
+/// @param[in] i_target the target associated with the phy reset sequence
+/// @return FAPI2_RC_SUCCESS iff setup was successful
+///
+template< fapi2::TargetType T >
+fapi2::ReturnCode flush_output_drivers( const fapi2::Target<T>& i_target );
+
+///
+/// @brief Flush the output drivers
+/// @param[in] i_target the target associated with the phy reset sequence
+/// @return FAPI2_RC_SUCCESS iff setup was successful
+///
+template<>
+fapi2::ReturnCode flush_output_drivers( const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_target );
+
+///
/// @brief Setup seq_rd_wr_data
/// @param[in] i_target the MCA target associated with this cal setup
/// @return FAPI2_RC_SUCCESS iff setup was successful
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/phy/dp16.C b/src/import/chips/p9/procedures/hwp/memory/lib/phy/dp16.C
index 803e9bdea..f0e098583 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/phy/dp16.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/phy/dp16.C
@@ -52,7 +52,7 @@ namespace mss
// Definition of the DP16 DLL Config registers
// DP16 DLL registers all come in pairs - DLL per 8 bits
// 5 DLL per MCA gives us 10 DLL Config Registers.
-// All-caps (as opposed to the others) as it's really in the dp16Traits class which is app caps <shrug>)
+// All-caps (as opposed to the others) as it's really in the dp16Traits class which is all caps <shrug>)
const std::vector< std::pair<uint64_t, uint64_t> > dp16Traits<TARGET_TYPE_MCA>::DLL_CNFG_REG =
{
{ MCA_DDRPHY_DP16_DLL_CNTL0_P0_0, MCA_DDRPHY_DP16_DLL_CNTL1_P0_0 },
@@ -62,6 +62,16 @@ const std::vector< std::pair<uint64_t, uint64_t> > dp16Traits<TARGET_TYPE_MCA>::
{ MCA_DDRPHY_DP16_DLL_CNTL0_P0_4, MCA_DDRPHY_DP16_DLL_CNTL1_P0_4 },
};
+// Definition of the DP16 Data Bit Dir1 registers
+// All-caps (as opposed to the others) as it's really in the dp16Traits class which is all caps <shrug>)
+const std::vector< uint64_t > dp16Traits<TARGET_TYPE_MCA>::DATA_BIT_DIR1 =
+{
+ MCA_DDRPHY_DP16_DATA_BIT_DIR1_P0_0,
+ MCA_DDRPHY_DP16_DATA_BIT_DIR1_P0_1,
+ MCA_DDRPHY_DP16_DATA_BIT_DIR1_P0_2,
+ MCA_DDRPHY_DP16_DATA_BIT_DIR1_P0_3,
+ MCA_DDRPHY_DP16_DATA_BIT_DIR1_P0_4,
+};
namespace dp16
{
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/phy/dp16.H b/src/import/chips/p9/procedures/hwp/memory/lib/phy/dp16.H
index 04ccb0a38..9dba08828 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/phy/dp16.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/phy/dp16.H
@@ -117,12 +117,15 @@ class dp16Traits<fapi2::TARGET_TYPE_MCA>
// any of this for some time.
static constexpr uint64_t DLL_PER_DP16 = 2;
- // Vector of the DLL configuration registers. The pair represents the two DLL in per DP16
+ // Vectors of DP16 registers. The pair represents the two DLL in per DP16
static const std::vector< std::pair<uint64_t, uint64_t> > DLL_CNFG_REG;
+ static const std::vector< uint64_t > DATA_BIT_DIR1;
enum
{
DLL_CNTL_INIT_RXDLL_CAL_RESET = MCA_DDRPHY_DP16_DLL_CNTL0_P0_0_01_INIT_RXDLL_CAL_RESET,
+ FLUSH = MCA_DDRPHY_DP16_DATA_BIT_DIR1_P0_0_01_FLUSH,
+ INIT_IO = MCA_DDRPHY_DP16_DATA_BIT_DIR1_P0_0_01_INIT_IO,
};
};
@@ -189,7 +192,7 @@ fapi_try_exit:
///
/// @brief Set the DLL cal reset (begins DLL cal operations)
-/// @tparam T fapi2 Target Type - derived
+/// @tparam T fapi2 Target Type - defaults to TARGET_TYPE_MCA
/// @tparam TT traits type defaults to dp16Traits<T>
/// @param[in] o_data the value of the register
/// @param[in] i_state mss::LOW or mss::HIGH representing the state of the bit
@@ -204,6 +207,82 @@ inline void set_dll_cal_reset( fapi2::buffer<uint64_t>& o_data, const states i_s
///
+/// @brief Read DATA_BIT_DIR1
+/// @tparam I DP16 instance
+/// @tparam T fapi2 Target Type - derived
+/// @tparam TT traits type defaults to dp16Traits<T>
+/// @param[in] i_target the fapi2 target of the port
+/// @param[out] o_data the value of the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< uint64_t I, fapi2::TargetType T, typename TT = dp16Traits<T> >
+inline fapi2::ReturnCode read_data_bit_dir1( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& o_data )
+{
+ static_assert( I < TT::DP_COUNT, "dp16 instance out of range");
+
+ FAPI_TRY( mss::getScom(i_target, TT::DATA_BIT_DIR1[I], o_data) );
+ FAPI_INF("data_bit_dir1 dp16%d: 0x%016lx", I, o_data);
+
+fapi_try_exit:
+ return fapi2::current_err;
+
+}
+
+///
+/// @brief Write DATA_BIT_DIR1
+/// @tparam I DP16 instance
+/// @tparam T fapi2 Target Type - derived
+/// @tparam TT traits type defaults to dp16Traits<T>
+/// @param[in] i_target the fapi2 target of the port
+/// @param[in] i_data the value of the register
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+template< uint64_t I, fapi2::TargetType T, typename TT = dp16Traits<T> >
+inline fapi2::ReturnCode write_data_bit_dir1( const fapi2::Target<T>& i_target, const fapi2::buffer<uint64_t>& i_data )
+{
+ static_assert( I < TT::DP_COUNT, "dp16 instance out of range");
+
+ FAPI_INF("data_bit_dir1 dp16%d: 0x%016lx", I, i_data);
+ FAPI_TRY( mss::putScom(i_target, TT::DATA_BIT_DIR1[I], i_data) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+
+}
+
+///
+/// @brief Set the output flush
+/// @tparam T fapi2 Target Type - defaults to TARGET_TYPE_MCA
+/// @tparam TT traits type defaults to dp16Traits<T>
+/// @param[in] o_data the value of the register
+/// @param[in] i_state mss::LOW or mss::HIGH representing the state of the bit
+/// @note Default state is 'low' as writing a 0 forces the cal to begin.
+///
+template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCA, typename TT = dp16Traits<T> >
+inline void set_output_flush( fapi2::buffer<uint64_t>& o_data, const states i_state )
+{
+ FAPI_INF("set_output_flush %s", (i_state == mss::LOW ? "low" : "high"));
+ o_data.writeBit<TT::FLUSH>(i_state);
+}
+
+///
+/// @brief Set the init io state
+/// @tparam T fapi2 Target Type - defaults to TARGET_TYPE_MCA
+/// @tparam TT traits type defaults to dp16Traits<T>
+/// @param[in] o_data the value of the register
+/// @param[in] i_state mss::LOW or mss::HIGH representing the state of the bit
+/// @note Default state is 'low' as writing a 0 forces the cal to begin.
+///
+template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCA, typename TT = dp16Traits<T> >
+inline void set_init_io( fapi2::buffer<uint64_t>& o_data, const states i_state )
+{
+ FAPI_INF("set_init_io %s", (i_state == mss::LOW ? "low" : "high"));
+ o_data.writeBit<TT::INIT_IO>(i_state);
+}
+
+
+
+///
/// @brief Configure the DP16 sysclk
/// @tparam T the fapi2 target type
/// @tparam TT the target traits
diff --git a/src/import/chips/p9/procedures/hwp/memory/p9_mss_ddr_phy_reset.C b/src/import/chips/p9/procedures/hwp/memory/p9_mss_ddr_phy_reset.C
index e3d47546c..a7609b3c1 100644
--- a/src/import/chips/p9/procedures/hwp/memory/p9_mss_ddr_phy_reset.C
+++ b/src/import/chips/p9/procedures/hwp/memory/p9_mss_ddr_phy_reset.C
@@ -79,6 +79,15 @@ extern "C"
FAPI_TRY( mss::change_resetn(i_target, mss::LOW), "change_resetn for %s failed", mss::c_str(i_target) );
//
+ // Flush output drivers
+ //
+
+ // 8. Set FLUSH=1 and INIT_IO=1 in the DDRPHY_ADR_OUTPUT_FORCE_ATEST_CNTL and DDRPHY_DP16_DATA_BIT_DIR1 register
+ // 9. Wait at least 32 dphy_gckn clock cycles.
+ // 10. Set FLUSH=0 and INIT_IO=0 in the DDRPHY_ADR_OUTPUT_FORCE_ATEST_CNTL register
+ FAPI_TRY( mss::flush_output_drivers(i_target), "unable to flush output drivers for %s", mss::c_str(i_target) );
+
+ //
// ZCTL Enable
//
@@ -140,8 +149,6 @@ extern "C"
// slew cal successful
// FAPI_TRY( mss::slew_cal(i_target), "slew_cal for %s failed", mss::c_str(i_target));
- FAPI_TRY( mss::ddr_phy_flush(i_target), "ddr_phy_flush failed for %s", mss::c_str(i_target) );
-
#ifdef LEAVES_OUTPUT_TO_DIMM_TRISTATE
// Per J. Bialas, force_mclk_low can be dasserted.
FAPI_TRY(mss::change_force_mclk_low(i_target, mss::LOW),
OpenPOWER on IntegriCloud