diff options
author | Andre Marin <aamarin@us.ibm.com> | 2017-01-06 15:49:12 -0600 |
---|---|---|
committer | Christian R. Geddes <crgeddes@us.ibm.com> | 2017-02-07 16:56:14 -0500 |
commit | 993c0b9a63ab8faa72d224170c52978b57731a51 (patch) | |
tree | 5ab8fd83acceee6cc3ace6700013d5aa0bfb9034 | |
parent | 21bcf18c2d4da4d3c6cb2d306c17422cdfc80ec6 (diff) | |
download | talos-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>
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; |