summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndre Marin <aamarin@us.ibm.com>2017-01-06 15:49:12 -0600
committerChristian R. Geddes <crgeddes@us.ibm.com>2017-02-07 16:56:14 -0500
commit993c0b9a63ab8faa72d224170c52978b57731a51 (patch)
tree5ab8fd83acceee6cc3ace6700013d5aa0bfb9034
parent21bcf18c2d4da4d3c6cb2d306c17422cdfc80ec6 (diff)
downloadtalos-hostboot-993c0b9a63ab8faa72d224170c52978b57731a51.tar.gz
talos-hostboot-993c0b9a63ab8faa72d224170c52978b57731a51.zip
Add DP16 API and unit testing needed to set PBA mode for LRDIMMs
Added DATA_BIT_ENABL0, DATA_BIT_DIR0, and DFT_FORCE_OUTPUTS registers and enumerations Change-Id: Ifa2607f85b38628609437ed61b8a5aa7b9f6d844 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/35522 Reviewed-by: Brian R. Silver <bsilver@us.ibm.com> Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Reviewed-by: STEPHEN GLANCY <sglancy@us.ibm.com> Reviewed-by: Louis Stermole <stermole@us.ibm.com> Tested-by: Hostboot CI <hostboot-ci+hostboot@us.ibm.com> Reviewed-by: Jennifer A. Stofer <stofer@us.ibm.com> Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/35526 Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com> Reviewed-by: Christian R. Geddes <crgeddes@us.ibm.com>
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/ccs/ccs.C7
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/ccs/ccs.H14
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/data_buffer_ddr4.H125
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/mc/port.H24
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/phy/ddr_phy.C4
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/phy/dp16.C97
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/phy/dp16.H44
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit_training.C3
8 files changed, 224 insertions, 94 deletions
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/ccs/ccs.C b/src/import/chips/p9/procedures/hwp/memory/lib/ccs/ccs.C
index 1428555fd..8c207d992 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/ccs/ccs.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/ccs/ccs.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* Contributors Listed Below - COPYRIGHT 2015,2017 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -258,13 +258,12 @@ fapi_try_exit:
/// @tparam TT the ccsTraits associated with T - derived
/// @param[in] fapi2::Target<TARGET_TYPE_MCBIST>& the target to effect
/// @param[in,out] the buffer representing the mode register
-/// @param[in] bool true iff Copy CKE signals to CKE Spare on both ports
-/// @return void
+/// @param[in] mss::states - mss::ON iff Copy CKE signals to CKE Spare on both ports
/// @note no-op for p9n
///
template<>
void copy_cke_to_spare_cke<TARGET_TYPE_MCBIST>( const fapi2::Target<TARGET_TYPE_MCBIST>&,
- fapi2::buffer<uint64_t>&, bool )
+ fapi2::buffer<uint64_t>&, states )
{
return;
}
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/ccs/ccs.H b/src/import/chips/p9/procedures/hwp/memory/lib/ccs/ccs.H
index 73de8e68f..5eb230e3f 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/ccs/ccs.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/ccs/ccs.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* Contributors Listed Below - COPYRIGHT 2015,2017 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -702,7 +702,7 @@ fapi_try_exit:
/// @return void
///
template< fapi2::TargetType T, typename TT = ccsTraits<T> >
-inline void stop_on_err( const fapi2::Target<T>&, fapi2::buffer<uint64_t>& io_buffer, const bool i_value)
+inline void stop_on_err( const fapi2::Target<T>&, fapi2::buffer<uint64_t>& io_buffer, const states i_value)
{
io_buffer.writeBit<TT::STOP_ON_ERR>(i_value);
}
@@ -733,7 +733,7 @@ inline void disable_ecc( const fapi2::Target<T>&, fapi2::buffer<uint64_t>& io_bu
/// @return void
///
template< fapi2::TargetType T, typename TT = ccsTraits<T> >
-inline void ue_disable( const fapi2::Target<T>&, fapi2::buffer<uint64_t>& io_buffer, const bool i_value)
+inline void ue_disable( const fapi2::Target<T>&, fapi2::buffer<uint64_t>& io_buffer, const states i_value)
{
io_buffer.writeBit<TT::UE_DISABLE>(i_value);
}
@@ -744,11 +744,11 @@ inline void ue_disable( const fapi2::Target<T>&, fapi2::buffer<uint64_t>& io_buf
/// @tparam TT the CCS traits of the chiplet which executes the CCS instruction
/// @param[in] the target to effect
/// @param[in,out] io_buffer the buffer representing the mode register
-/// @param[in] i_value true iff delay parity a cycle
+/// @param[in] i_value mss::ON iff delay parity a cycle
/// @return void
///
template< fapi2::TargetType T, typename TT = ccsTraits<T> >
-inline void parity_after_cmd( const fapi2::Target<T>&, fapi2::buffer<uint64_t>& io_buffer, const bool i_value)
+inline void parity_after_cmd( const fapi2::Target<T>&, fapi2::buffer<uint64_t>& io_buffer, const states i_value)
{
io_buffer.writeBit<TT::CFG_PARITY_AFTER_CMD>(i_value);
}
@@ -781,12 +781,12 @@ inline void cal_count( const fapi2::Target<T>&, fapi2::buffer<uint64_t>& io_buff
/// @tparam TT the ccsTraits associated with T - derived
/// @param[in] i_target the target to effect
/// @param[in,out] io_buffer the buffer representing the mode register
-/// @param[in] i_value bool true iff Copy CKE signals to CKE Spare on both ports
+/// @param[in] i_value mss::ON iff Copy CKE signals to CKE Spare on both ports
/// @note no-op for p9n
/// @return void
///
template< fapi2::TargetType T, typename TT = ccsTraits<T> >
-void copy_cke_to_spare_cke( const fapi2::Target<T>&, fapi2::buffer<uint64_t>& io_buffer, const bool i_value);
+void copy_cke_to_spare_cke( const fapi2::Target<T>&, fapi2::buffer<uint64_t>& io_buffer, const states i_value);
///
/// @brief Read the modeq register appropriate for this target
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/data_buffer_ddr4.H b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/data_buffer_ddr4.H
index 9c28ef8e7..8e616c195 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/data_buffer_ddr4.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/data_buffer_ddr4.H
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* Contributors Listed Below - COPYRIGHT 2015,2017 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -39,6 +39,7 @@
#include <vector>
#include <fapi2.H>
#include <lib/utils/c_str.H>
+#include <lib/shared/mss_const.H>
#include <lib/dimm/bcw_load_ddr4.H>
#include <lib/phy/dp16.H>
#include <lib/dimm/ddr4/control_word_ddr4.H>
@@ -85,8 +86,9 @@ enum db02_def
FUNC_SPACE_SELECT_CW = 0x7,
// 8 bit BCWs
- BUFF_TRAIN_CONFIG_CW = 0x4,
+ BUFF_CONFIG_CW = 0x1,
DRAM_VREF_CW = 0x6,
+ BUFF_TRAIN_CONFIG_CW = 0x4,
};
namespace ddr4
@@ -205,13 +207,44 @@ fapi_try_exit:
}
///
+/// @brief Boilerplate for setting & printing BCWs
+/// @tparam T the functon space number we want
+/// @param[in] i_target a DIMM target
+/// @param[in] i_data control word data
+/// @param[in,out] io_inst a vector of CCS instructions we should add to
+/// @return FAPI2_RC_SUCCESS if and only if ok
+///
+template< mss::control_word T >
+static fapi2::ReturnCode settings_boilerplate(const fapi2::Target< fapi2::TARGET_TYPE_DIMM >& i_target,
+ const cw_data& i_data,
+ std::vector< ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST> >& io_inst)
+{
+ FAPI_TRY( function_space_select(i_target, i_data.iv_func_space, io_inst),
+ "%s. Failed to select function space %d",
+ mss::c_str(i_target), uint8_t(i_data.iv_func_space) );
+
+ FAPI_TRY( control_word_engine<T>(i_target, i_data, io_inst),
+ "%s. Failed control_word_engine for 8-bit BCW (F%dBC%02lxX)",
+ mss::c_str(i_target), uint8_t(i_data.iv_func_space), uint8_t(i_data.iv_number) );
+
+ // I don't know what already existed in this ccs instruction vector beforehand so
+ // I use the back() method to access the last added ccs instruction of interest
+ FAPI_INF("%s. F%dBC%02lx ccs inst 0x%016llx:0x%016llx, data: %d",
+ mss::c_str(i_target), uint8_t(i_data.iv_func_space), uint8_t(i_data.iv_number),
+ uint64_t(io_inst.back().arr0), uint64_t(io_inst.back().arr1), uint8_t(i_data.iv_data) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
/// @brief Sets data buffer training mode control word
/// @tparam T TargetType of the CCS instruction
/// @param[in] i_target the DIMM target
/// @param[in] i_mode buffer training mode
/// @param[in,out] io_inst a vector of CCS instructions we should add to
/// @return FAPI2_RC_SUCCESS iff ok
-/// @note Sets buffer control word (BC0C) setting
+/// @note Sets buffer control word (BC0C) setting
///
template< fapi2::TargetType T >
inline fapi2::ReturnCode set_buffer_training( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
@@ -238,20 +271,7 @@ inline fapi2::ReturnCode set_buffer_training( const fapi2::Target<fapi2::TARGET_
fapi2::Assert(find_value_from_key(BUFF_TRAINING, i_mode, l_encoding));
cw_data l_data(FUNC_SPACE_0, BUFF_TRAIN_MODE_CW, l_encoding, mss::tmrc());
-
- FAPI_TRY( function_space_select(i_target, l_data.iv_func_space, io_inst),
- "%s. Failed to select function space %d",
- mss::c_str(i_target), uint8_t(l_data.iv_func_space) );
-
- FAPI_TRY( control_word_engine<BCW_4BIT>(i_target, l_data, io_inst),
- "%s. Failed control_word_engine for 4-bit BCW (F%dBC%02lx)",
- mss::c_str(i_target), uint8_t(l_data.iv_func_space), uint8_t(l_data.iv_number) );
-
- // I don't know what already existed in this ccs instruction vector beforehand so
- // I use the back() method to access the last added ccs instruction of interest
- FAPI_INF("%s. F%dBC%02lx ccs inst 0x%016llx:0x%016llx, data: %d",
- mss::c_str(i_target), uint8_t(l_data.iv_func_space), uint8_t(l_data.iv_number),
- uint64_t(io_inst.back().arr0), uint64_t(io_inst.back().arr1), uint8_t(l_data.iv_data) );
+ FAPI_TRY( settings_boilerplate<BCW_4BIT>(i_target, l_data, io_inst) );
fapi_try_exit:
return fapi2::current_err;
@@ -328,21 +348,7 @@ inline fapi2::ReturnCode set_rank_presence( const fapi2::Target<fapi2::TARGET_TY
mss::c_str(i_target), i_num_package_ranks );
{
cw_data l_data(FUNC_SPACE_0, RANK_PRESENCE_CW, l_encoding, mss::tmrc());
-
- FAPI_TRY( function_space_select(i_target, l_data.iv_func_space, io_inst),
- "%s. Failed to select function space %d",
- mss::c_str(i_target), uint8_t(l_data.iv_func_space) );
-
- FAPI_TRY( control_word_engine<BCW_4BIT>(i_target, l_data, io_inst),
- "%s. Failed control_word_engine for 4-bit BCW (F%dBC%02lx)",
- mss::c_str(i_target), uint8_t(l_data.iv_func_space), uint8_t(l_data.iv_number) );
-
- // I don't know what already existed in this ccs instruction vector beforehand so
- // I use the back() method to access the last added ccs instruction of interest
- FAPI_INF("%s. F%dBC%02lx ccs inst 0x%016llx:0x%016llx, data: %d",
- mss::c_str(i_target), uint8_t(l_data.iv_func_space), uint8_t(l_data.iv_number),
- uint64_t(io_inst.back().arr0), uint64_t(io_inst.back().arr1), uint8_t(l_data.iv_data) );
-
+ FAPI_TRY( settings_boilerplate<BCW_4BIT>(i_target, l_data, io_inst) );
}
fapi_try_exit:
@@ -383,20 +389,7 @@ fapi2::ReturnCode set_mrep_timing_control( const fapi2::Target<fapi2::TARGET_TYP
// Function space is determined by rank index for control word since it has a [0:3] range
cw_data l_data( mss::index(i_rank), N, i_trained_timing, mss::tmrc() );
-
- FAPI_TRY( function_space_select(i_target, l_data.iv_func_space, io_inst),
- "%s. Failed to select function space %d",
- mss::c_str(i_target), uint8_t(l_data.iv_func_space) );
-
- FAPI_TRY( control_word_engine<BCW_8BIT>(i_target, l_data, io_inst),
- "%s. Failed control_word_engine for 8-bit BCW (F%dBC%02lxX)",
- mss::c_str(i_target), uint8_t(l_data.iv_func_space), uint8_t(l_data.iv_number) );
-
- // I don't know what already existed in this ccs instruction vector beforehand so
- // I use the back() method to access the last added ccs instruction of interest
- FAPI_INF("%s. F%dBC%02lxX ccs inst 0x%016llx:0x%016llx, data: %d",
- mss::c_str(i_target), uint8_t(l_data.iv_func_space), uint8_t(l_data.iv_number),
- uint64_t(io_inst.back().arr0), uint64_t(io_inst.back().arr1), uint8_t(l_data.iv_data) );
+ FAPI_TRY( settings_boilerplate<BCW_8BIT>(i_target, l_data, io_inst) );
fapi_try_exit:
return fapi2::current_err;
@@ -430,20 +423,38 @@ inline fapi2::ReturnCode set_command_space( const fapi2::Target<fapi2::TARGET_TY
// After issuing a data buffer command via writes to BC06 waiting for tMRC(16 tCK)
// is required before the next DRAM command or BCW write can be issued.
cw_data l_data(FUNC_SPACE_0, CMD_SPACE_CW, i_command, mss::tmrc());
+ FAPI_TRY( settings_boilerplate<BCW_4BIT>(i_target, l_data, io_inst) );
- FAPI_TRY( function_space_select(i_target, l_data.iv_func_space, io_inst),
- "%s. Failed to select function space %d",
- mss::c_str(i_target), uint8_t(l_data.iv_func_space) );
+fapi_try_exit:
+ return fapi2::current_err;
+}
- FAPI_TRY( control_word_engine<BCW_4BIT>(i_target, l_data, io_inst),
- "%s. Failed control_word_engine for 4-bit BCW (F%dBC%02lx)",
- mss::c_str(i_target), uint8_t(l_data.iv_func_space), uint8_t(l_data.iv_number) );
+///
+/// @brief Sets per buffer addressibility (PBA) mode
+/// @tparam T TargetType of the CCS instruction
+/// @param[in] i_target the DIMM target
+/// @param[in] i_state mss::ON or mss::OFF
+/// @param[in,out] io_inst a vector of CCS instructions we should add to
+/// @return FAPI2_RC_SUCCESS iff ok
+/// @note Sets DA0 setting for buffer control word (F0BC1x)
+///
+template< fapi2::TargetType T>
+inline fapi2::ReturnCode set_pba_mode( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
+ const mss::states i_state,
+ std::vector< ccs::instruction_t<T> >& io_inst )
+{
+ constexpr uint64_t MAX_VALID = 1;
- // I don't know what already existed in this ccs instruction vector beforehand so
- // I use the back() method to access the last added ccs instruction of interest
- FAPI_INF("%s. F%dBC%02lx ccs inst 0x%016llx:0x%016llx, data: %d",
- mss::c_str(i_target), uint8_t(l_data.iv_func_space), uint8_t(l_data.iv_number),
- uint64_t(io_inst.back().arr0), uint64_t(io_inst.back().arr1), uint8_t(l_data.iv_data) );
+ // User input programming error asserts program termination
+ if( i_state > MAX_VALID )
+ {
+ FAPI_ERR( "%s. Invalid setting received: %d, largest valid PBA setting is %d",
+ mss::c_str(i_target), i_state, MAX_VALID );
+ fapi2::Assert(false);
+ }
+
+ cw_data l_data(FUNC_SPACE_0, BUFF_CONFIG_CW, i_state, mss::tmrc());
+ FAPI_TRY( settings_boilerplate<BCW_8BIT>(i_target, l_data, io_inst) );
fapi_try_exit:
return fapi2::current_err;
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/mc/port.H b/src/import/chips/p9/procedures/hwp/memory/lib/mc/port.H
index 186c33417..21a62fa2a 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/mc/port.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/mc/port.H
@@ -254,6 +254,28 @@ class portTraits<fapi2::TARGET_TYPE_MCA>
};
///
+/// @brief Read the rdtag delay value
+/// @tparam T the fapi2 target type of the target
+/// @tparam TT the class traits for the port
+/// @param[in] i_target the target
+/// @param[out] o_delay RDTAG_DLY value (in cycles)
+/// @return FAPI2_RC_SUCCESS if and only if ok
+///
+template< fapi2::TargetType T, typename TT = portTraits<T> >
+fapi2::ReturnCode read_rdtag_delay( const fapi2::Target<T>& i_target, uint64_t& o_delay )
+{
+
+ fapi2::buffer<uint64_t> l_data;
+ FAPI_TRY( mss::getScom(i_target, TT::DSM0Q_REG, l_data) );
+ l_data.template extractToRight<TT::DSM0Q_CFG_RDTAG_DLY, TT::DSM0Q_CFG_RDTAG_DLY_LEN>(o_delay);
+
+ FAPI_INF( "RDTAG_DLY %d for %s", uint64_t(o_delay), mss::c_str(i_target) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
/// @brief Change the rdtag delay value
/// @tparam T the fapi2 target type of the target
/// @tparam TT the class traits for the port
@@ -278,7 +300,7 @@ fapi2::ReturnCode change_rdtag_delay( const fapi2::Target<T>& i_target, const ui
fapi2::buffer<uint64_t> l_data;
- FAPI_DBG( "Change RDTAG_DLY to %d %s", i_delay, mss::c_str(i_target) );
+ FAPI_DBG( "Change RDTAG_DLY to %d for %s", i_delay, mss::c_str(i_target) );
FAPI_TRY( mss::getScom(i_target, TT::DSM0Q_REG, l_data) );
l_data.insertFromRight<TT::DSM0Q_CFG_RDTAG_DLY, TT::DSM0Q_CFG_RDTAG_DLY_LEN>(i_delay);
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 c1e6124e1..e58ab08ef 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
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2016 */
+/* Contributors Listed Below - COPYRIGHT 2015,2017 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -1210,7 +1210,7 @@ fapi2::ReturnCode flush_output_drivers( const fapi2::Target<fapi2::TARGET_TYPE_M
// Need to run on the magic ports too
const auto l_ports = mss::find_targets_with_magic<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;
+ const auto& l_data_dir_reg = dp16Traits<TARGET_TYPE_MCA>::DATA_BIT_DIR1_REG;
// Per PHY review 8/16, setup the DATA_BIT_DIR1 with advance_ping_pong and delay_ping_pong_half
mss::dp16::set_adv_pp(l_dp16_data, mss::HIGH);
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 968944ddc..6d75f4b68 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
@@ -194,7 +194,7 @@ const std::vector< std::pair<uint64_t, uint64_t> > dp16Traits<TARGET_TYPE_MCA>::
// 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 =
+const std::vector< uint64_t > dp16Traits<TARGET_TYPE_MCA>::DATA_BIT_DIR1_REG
{
MCA_DDRPHY_DP16_DATA_BIT_DIR1_P0_0,
MCA_DDRPHY_DP16_DATA_BIT_DIR1_P0_1,
@@ -472,6 +472,33 @@ const std::vector< std::vector<std::pair<uint64_t, uint64_t>> > dp16Traits<TARGE
constexpr const uint64_t dp16Traits<fapi2::TARGET_TYPE_MCA>::GATE_DELAY_BIT_POS[];
constexpr const uint64_t dp16Traits<fapi2::TARGET_TYPE_MCA>::BLUE_WATERFALL_BIT_POS[];
+const std::vector< uint64_t > dp16Traits<TARGET_TYPE_MCA>::DATA_BIT_ENABLE0_REG =
+{
+ MCA_DDRPHY_DP16_DATA_BIT_ENABLE0_P0_0,
+ MCA_DDRPHY_DP16_DATA_BIT_ENABLE0_P0_1,
+ MCA_DDRPHY_DP16_DATA_BIT_ENABLE0_P0_2,
+ MCA_DDRPHY_DP16_DATA_BIT_ENABLE0_P0_3,
+ MCA_DDRPHY_DP16_DATA_BIT_ENABLE0_P0_4,
+};
+
+const std::vector< uint64_t > dp16Traits<TARGET_TYPE_MCA>::DATA_BIT_ENABLE1_REG =
+{
+ MCA_0_DDRPHY_DP16_DATA_BIT_ENABLE1_P0_0,
+ MCA_0_DDRPHY_DP16_DATA_BIT_ENABLE1_P0_1,
+ MCA_0_DDRPHY_DP16_DATA_BIT_ENABLE1_P0_2,
+ MCA_0_DDRPHY_DP16_DATA_BIT_ENABLE1_P0_3,
+ MCA_0_DDRPHY_DP16_DATA_BIT_ENABLE1_P0_4,
+};
+
+const std::vector< uint64_t > dp16Traits<TARGET_TYPE_MCA>::RD_DIA_CONFIG5_REG =
+{
+ MCA_DDRPHY_DP16_RD_DIA_CONFIG5_P0_0,
+ MCA_DDRPHY_DP16_RD_DIA_CONFIG5_P0_1,
+ MCA_DDRPHY_DP16_RD_DIA_CONFIG5_P0_2,
+ MCA_DDRPHY_DP16_RD_DIA_CONFIG5_P0_3,
+ MCA_DDRPHY_DP16_RD_DIA_CONFIG5_P0_4,
+};
+
///
/// @brief Given a RD_VREF value, create a PHY 'standard' bit field for that percentage.
/// @tparam T fapi2 Target Type - derived
@@ -2440,33 +2467,73 @@ fapi_try_exit:
}
///
-/// @brief Write FORCE_FIFO_CAPTURE
+/// @brief Write FORCE_FIFO_CAPTURE to all DP16 instances
/// Force DQ capture in Read FIFO to support DDR4 LRDIMM calibration
/// @param[in] i_target the fapi2 target of the port
/// @param[in] i_state mss::states::ON or mss::states::OFF
/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok
///
template<>
-fapi2::ReturnCode write_force_fifo_capture( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+fapi2::ReturnCode write_force_dq_capture( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
const mss::states i_state)
{
- // TK - Some functions have vector as part of the trait class
- // while others have within the function <shrug> - AAM
- static const std::vector< uint64_t > l_addr
- {
- MCA_DDRPHY_DP16_RD_DIA_CONFIG5_P0_0,
- MCA_DDRPHY_DP16_RD_DIA_CONFIG5_P0_1,
- MCA_DDRPHY_DP16_RD_DIA_CONFIG5_P0_2,
- MCA_DDRPHY_DP16_RD_DIA_CONFIG5_P0_3,
- MCA_DDRPHY_DP16_RD_DIA_CONFIG5_P0_4,
- };
+ typedef dp16Traits<TARGET_TYPE_MCA> TT;
+ fapi2::buffer<uint64_t> l_data;
+ l_data.writeBit<TT::FORCE_FIFO_CAPTURE>(i_state);
+
+ FAPI_TRY( mss::scom_blastah(i_target, TT::RD_DIA_CONFIG5_REG, l_data) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Writes DATA_BIT_ENABLE0 to all DP16 instances
+/// @param[in] i_target the fapi2 target of the port
+/// @param[in] i_state mss::states::ON or mss::states::OFF
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok
+///
+template< >
+fapi2::ReturnCode write_data_bit_enable0( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+ const mss::states i_state)
+{
typedef dp16Traits<TARGET_TYPE_MCA> TT;
+
+ // '1'b indicates the DP16 bit is enabled, and is used for sending or receiving
+ // data to or from the memory device.
+ // '0'b indicates the DP16 bit is not used to send or receive data
fapi2::buffer<uint64_t> l_data;
+ l_data.writeBit<TT::DATA_BIT_ENABLE0, TT::DATA_BIT_ENABLE0_LEN>(i_state);
- l_data.writeBit<TT::FORCE_FIFO_CAPTURE>(i_state);
+ FAPI_TRY( mss::scom_blastah(i_target, TT::DATA_BIT_ENABLE0_REG, l_data) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Write DFT_FORCE_OUTPUTS to all DP16 instances
+/// @param[in] i_target the fapi2 target of the port
+/// @param[in] i_state mss::states::ON or mss::states::OFF
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok
+///
+template< >
+fapi2::ReturnCode write_dft_force_outputs( const fapi2::Target< fapi2::TARGET_TYPE_MCA >& i_target,
+ const mss::states i_state)
+{
+ typedef dp16Traits<TARGET_TYPE_MCA> TT;
+
+ // The 24 outputs of the DP16 are forced to a low-impedance state the corresponding DATA_BIT_ENABLE bit is '1'b
+ // and forced to a high-impedence state when the corresponding DATA_BIT_ENABLE bit is '0'b
+
+ // When a DP16 output is forced to a low-z state, the value driven out, '1'b or '0'b , is determined
+ // by the corresponding DATA_BIT_DIR bit value.
+ // The 24 outputs of the DP16 are not forced when set with '0'b
+ fapi2::buffer<uint64_t> l_data;
+ l_data.writeBit<TT::DFT_FORCE_OUTPUTS>(i_state);
- FAPI_TRY( mss::scom_blastah(i_target, l_addr, l_data) );
+ FAPI_TRY( mss::scom_blastah(i_target, TT::DATA_BIT_ENABLE1_REG, l_data) );
fapi_try_exit:
return fapi2::current_err;
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 597d5047e..6da7cfd9b 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
@@ -144,7 +144,7 @@ class dp16Traits<fapi2::TARGET_TYPE_MCA>
static const std::vector< uint64_t > DLL_CNFG_REG;
static const std::vector< uint64_t > RD_VREF_CAL_ENABLE_REG;
static const std::vector< uint64_t > RD_VREF_CAL_ERROR_REG;
- static const std::vector< uint64_t > DATA_BIT_DIR1;
+ static const std::vector< uint64_t > DATA_BIT_DIR1_REG;
static const std::vector< uint64_t > PR_STATIC_OFFSET_REG;
static const std::vector< uint64_t > IO_TX_FET_SLICE_REG;
static const std::vector< uint64_t > IO_TX_PFET_TERM_REG;
@@ -179,6 +179,10 @@ class dp16Traits<fapi2::TARGET_TYPE_MCA>
static const std::vector< std::pair<uint64_t, uint64_t> > WR_VREF_VALUE_RP2_REG;
static const std::vector< std::pair<uint64_t, uint64_t> > WR_VREF_VALUE_RP3_REG;
+ static const std::vector< uint64_t > RD_DIA_CONFIG5_REG;
+ static const std::vector< uint64_t > DATA_BIT_ENABLE0_REG;
+ static const std::vector< uint64_t > DATA_BIT_ENABLE1_REG;
+
// Definitions of the gate delay and waterfall bits' locations
constexpr static const uint64_t GATE_DELAY_BIT_POS[NUM_QUAD_PER_DP16] =
{
@@ -207,7 +211,6 @@ class dp16Traits<fapi2::TARGET_TYPE_MCA>
TSYS_DATA = MCA_DDRPHY_DP16_WRCLK_PR_P0_0_01_TSYS,
TSYS_DATA_LEN = MCA_DDRPHY_DP16_WRCLK_PR_P0_0_01_TSYS_LEN,
- // Seriously PHY guys?
AC_BOOST_WR_DOWN = MCA_DDRPHY_DP16_ACBOOST_CTL_BYTE0_P0_0_01_S0ACENSLICENDRV_DC,
AC_BOOST_WR_DOWN_LEN = MCA_DDRPHY_DP16_ACBOOST_CTL_BYTE0_P0_0_01_S0ACENSLICENDRV_DC_LEN,
AC_BOOST_WR_UP = MCA_DDRPHY_DP16_ACBOOST_CTL_BYTE0_P0_0_01_S0ACENSLICEPDRV_DC,
@@ -331,6 +334,10 @@ class dp16Traits<fapi2::TARGET_TYPE_MCA>
// Read Diagnostic Config 5 (same bit for all MCAs)
FORCE_FIFO_CAPTURE = MCA_DDRPHY_DP16_RD_DIA_CONFIG5_P0_0_01_FORCE_FIFO_CAPTURE,
+
+ DATA_BIT_ENABLE0 = MCA_DDRPHY_DP16_DATA_BIT_ENABLE0_P0_0_01_ENABLE_15,
+ DATA_BIT_ENABLE0_LEN = MCA_DDRPHY_DP16_DATA_BIT_ENABLE0_P0_0_01_ENABLE_15_LEN,
+ DFT_FORCE_OUTPUTS = MCA_DDRPHY_DP16_DATA_BIT_ENABLE1_P0_0_01_DFT_FORCE_OUTPUTS,
};
};
@@ -688,7 +695,6 @@ 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 DATA_BIT_DIR1
/// @tparam I DP16 instance
@@ -703,7 +709,7 @@ inline fapi2::ReturnCode read_data_bit_dir1( const fapi2::Target<T>& i_target, f
{
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_TRY( mss::getScom(i_target, TT::DATA_BIT_DIR1_REG[I], o_data) );
FAPI_INF("data_bit_dir1 dp16%d: 0x%016lx", I, o_data);
fapi_try_exit:
@@ -726,7 +732,7 @@ inline fapi2::ReturnCode write_data_bit_dir1( const fapi2::Target<T>& i_target,
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( mss::putScom(i_target, TT::DATA_BIT_DIR1_REG[I], i_data) );
fapi_try_exit:
return fapi2::current_err;
@@ -1791,9 +1797,35 @@ fapi2::ReturnCode process_wrvref_cal_errors( const fapi2::Target<fapi2::TARGET_T
/// @param[in] i_target the fapi2 target of the port
/// @param[in] i_state mss::states::ON or mss::states::OFF
/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok
+/// @note '1'b Forces DQ capture in Read FIFO to support DDR4 LRDIMM calibration.
+/// '0'b Normal operation
+///
+template< fapi2::TargetType T, typename TT = dp16Traits<T> >
+fapi2::ReturnCode write_force_dq_capture( const fapi2::Target<T>& i_target,
+ const mss::states i_state);
+
+///
+/// @brief Write DATA_BIT_ENABLE0
+/// @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_state mss::states::ON or mss::states::OFF
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok
+///
+template< fapi2::TargetType T, typename TT = dp16Traits<T> >
+fapi2::ReturnCode write_data_bit_enable0( const fapi2::Target<T>& i_target,
+ const mss::states i_state);
+
+///
+/// @brief Write DFT_FORCE_OUTPUTS
+/// @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_state mss::states::ON or mss::states::OFF
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok
///
template< fapi2::TargetType T, typename TT = dp16Traits<T> >
-fapi2::ReturnCode write_force_fifo_capture( const fapi2::Target<T>& i_target,
+fapi2::ReturnCode write_dft_force_outputs( const fapi2::Target<T>& i_target,
const mss::states i_state);
///
diff --git a/src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit_training.C b/src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit_training.C
index 635ccc0cd..8a69371a1 100644
--- a/src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit_training.C
+++ b/src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit_training.C
@@ -93,7 +93,7 @@ extern "C"
}
// Clean out any previous calibration results, set bad-bits and configure the ranks.
- FAPI_DBG("MCA's on this McBIST: %d", i_target.getChildren<TARGET_TYPE_MCA>().size());
+ FAPI_DBG("MCA's on this McBIST: %d", mss::find_targets<TARGET_TYPE_MCA>(i_target).size());
for( const auto& p : mss::find_targets<TARGET_TYPE_MCA>(i_target))
{
@@ -114,7 +114,6 @@ extern "C"
// time it takes one rank to train one training algorithm times the number of
// ranks we're going to train. We fail-safe as worst-case we simply poll the
// register too much - so we can tune this as we learn more.
- l_program.iv_poll.iv_initial_sim_delay = mss::DELAY_100US;
l_program.iv_poll.iv_initial_sim_delay = 200;
l_program.iv_poll.iv_poll_count = 0xFFFF;
OpenPOWER on IntegriCloud