diff options
author | Stephen Glancy <sglancy@us.ibm.com> | 2017-10-18 13:46:41 -0500 |
---|---|---|
committer | Christian R. Geddes <crgeddes@us.ibm.com> | 2017-11-21 17:01:30 -0500 |
commit | f40bed180c16c532983f8548fe5901bf28c87888 (patch) | |
tree | 40babacdf2765ad3592266d636d4e38e35cfe09c /src/import/chips/p9/procedures/hwp/memory | |
parent | d7750b78d80c3527bcb5235b8c94ccd5613d5f60 (diff) | |
download | talos-hostboot-f40bed180c16c532983f8548fe5901bf28c87888.tar.gz talos-hostboot-f40bed180c16c532983f8548fe5901bf28c87888.zip |
Adds PDA support
PDA support will be needed for:
1) NVDIMM support (re-programming WR VREF)
2) PDA shmoo
Change-Id: Ic49bbbbe907ee9609ee26f6152de8949cdb999a3
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/48575
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Reviewed-by: ANDRE A. MARIN <aamarin@us.ibm.com>
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Tested-by: HWSV CI <hwsv-ci+hostboot@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/48744
Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com>
Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com>
Reviewed-by: Christian R. Geddes <crgeddes@us.ibm.com>
Diffstat (limited to 'src/import/chips/p9/procedures/hwp/memory')
6 files changed, 450 insertions, 3 deletions
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs_load_ddr4.H b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs_load_ddr4.H index d14ecc34e..746b1621e 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs_load_ddr4.H +++ b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs_load_ddr4.H @@ -800,6 +800,7 @@ fapi2::ReturnCode mrs06_decode(const ccs::instruction_t<fapi2::TARGET_TYPE_MCBIS /// @defgroup mrs-structs /// @addtogroup mrs-structs // Each MRS has it's attributes encapsulated in it's little struct. +// Comparisions for the MRS will be done in the order they'd be built in (according to the JEDEC spec) with the MSB going first /// @{ /// @@ -829,6 +830,49 @@ struct mrs00_data /// mrs00_data( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, fapi2::ReturnCode& o_rc ); + /// + /// @brief Less than operator + /// @param[in] i_rhs right hand comparison operator + /// @bool true if this object is less than i_rhs + /// + bool operator<(const mss::ddr4::mrs00_data& i_rhs) const + { + // MSB to LSB - 2015 JEDEC spec + // write recover/RTP + // CAS latency + // DLL reset + // TM + // Read burst type + // Burst length + + if(iv_write_recovery != i_rhs.iv_write_recovery) + { + return iv_write_recovery < i_rhs.iv_write_recovery; + } + + if(iv_cas_latency != i_rhs.iv_cas_latency) + { + return iv_cas_latency < i_rhs.iv_cas_latency; + } + + if(iv_dll_reset != i_rhs.iv_dll_reset) + { + return iv_dll_reset < i_rhs.iv_dll_reset; + } + + if(iv_test_mode != i_rhs.iv_test_mode) + { + return iv_test_mode < i_rhs.iv_test_mode; + } + + if(iv_read_burst_type != i_rhs.iv_read_burst_type) + { + return iv_read_burst_type < i_rhs.iv_read_burst_type; + } + + return iv_burst_length < i_rhs.iv_burst_length; + } + uint8_t iv_burst_length; uint8_t iv_read_burst_type; uint8_t iv_dll_reset; @@ -861,6 +905,59 @@ struct mrs01_data /// mrs01_data( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, fapi2::ReturnCode& o_rc ); + /// + /// @brief Less than operator + /// @param[in] i_rhs right hand comparison operator + /// @bool true if this object is less than i_rhs + /// + bool operator<(const mss::ddr4::mrs01_data& i_rhs) const + { + // MSB to LSB - 2015 JEDEC spec + // Qoff + // TDQS enable + // RTT_NOM + // Write leveling enable + // Additive latency + // Ouptut driver impedance control + // DLL enable + + if(iv_qoff != i_rhs.iv_qoff) + { + return iv_qoff < i_rhs.iv_qoff; + } + + if(iv_tdqs != i_rhs.iv_tdqs) + { + return iv_tdqs < i_rhs.iv_tdqs; + } + + const auto l_rtt_nom = memcmp(iv_rtt_nom, i_rhs.iv_rtt_nom, sizeof(i_rhs.iv_rtt_nom)); + + if(l_rtt_nom != MEMCMP_EQUAL) + { + return l_rtt_nom < MEMCMP_EQUAL; + } + + if(iv_wl_enable != i_rhs.iv_wl_enable) + { + return iv_wl_enable < i_rhs.iv_wl_enable; + } + + if(iv_additive_latency != i_rhs.iv_additive_latency) + { + return iv_additive_latency < i_rhs.iv_additive_latency; + } + + const auto l_odic = memcmp(iv_odic, i_rhs.iv_odic, sizeof(i_rhs.iv_odic)); + + if(l_odic != MEMCMP_EQUAL) + { + return l_odic < MEMCMP_EQUAL; + } + + return iv_dll_enable < i_rhs.iv_dll_enable; + } + uint8_t iv_dll_enable; uint8_t iv_odic[MAX_RANK_PER_DIMM]; uint8_t iv_additive_latency; @@ -894,6 +991,39 @@ struct mrs02_data /// mrs02_data( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, fapi2::ReturnCode& o_rc ); + /// + /// @brief Less than operator + /// @param[in] i_rhs right hand comparison operator + /// @bool true if this object is less than i_rhs + /// + bool operator<(const mss::ddr4::mrs02_data& i_rhs) const + { + // MSB to LSB - 2015 JEDEC spec + // write crc + // rtt wr + // LPASR + // cwl + + if(iv_write_crc != i_rhs.iv_write_crc) + { + return iv_write_crc < i_rhs.iv_write_crc; + } + + const auto l_rtt_wr = memcmp(iv_dram_rtt_wr, i_rhs.iv_dram_rtt_wr, sizeof(i_rhs.iv_dram_rtt_wr)); + + if(l_rtt_wr != MEMCMP_EQUAL) + { + return l_rtt_wr < MEMCMP_EQUAL; + } + + if(iv_lpasr != i_rhs.iv_lpasr) + { + return iv_lpasr < i_rhs.iv_lpasr; + } + + return iv_cwl < i_rhs.iv_cwl; + } + uint8_t iv_lpasr; uint8_t iv_cwl; uint8_t iv_write_crc; @@ -925,6 +1055,61 @@ struct mrs03_data /// mrs03_data( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, fapi2::ReturnCode& o_rc ); + /// + /// @brief Less than operator + /// @param[in] i_rhs right hand comparison operator + /// @bool true if this object is less than i_rhs + /// + bool operator<(const mss::ddr4::mrs03_data& i_rhs) const + { + // MSB to LSB - 2015 JEDEC spec + // MPR read format + // crc wr latency + // fine refresh + // temp sensor + // PDA (per-DRAM addressability) + // geardown mode + // MPR mode + // MPR page + + if(iv_read_format != i_rhs.iv_read_format) + { + return iv_read_format < i_rhs.iv_read_format; + } + + if(iv_crc_wr_latency != i_rhs.iv_crc_wr_latency) + { + return iv_crc_wr_latency < i_rhs.iv_crc_wr_latency; + } + + if(iv_fine_refresh != i_rhs.iv_fine_refresh) + { + return iv_fine_refresh < i_rhs.iv_fine_refresh; + } + + if(iv_temp_readout != i_rhs.iv_temp_readout) + { + return iv_temp_readout < i_rhs.iv_temp_readout; + } + + if(iv_pda != i_rhs.iv_pda) + { + return iv_pda < i_rhs.iv_pda; + } + + if(iv_geardown != i_rhs.iv_geardown) + { + return iv_geardown < i_rhs.iv_geardown; + } + + if(iv_mpr_mode != i_rhs.iv_mpr_mode) + { + return iv_mpr_mode < i_rhs.iv_mpr_mode; + } + + return iv_mpr_page < i_rhs.iv_mpr_page; + } + uint8_t iv_mpr_mode; uint8_t iv_mpr_page; uint8_t iv_geardown; @@ -959,6 +1144,79 @@ struct mrs04_data /// mrs04_data( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, fapi2::ReturnCode& o_rc ); + /// + /// @brief Less than operator + /// @param[in] i_rhs right hand comparison operator + /// @bool true if this object is less than i_rhs + /// + bool operator<(const mss::ddr4::mrs04_data& i_rhs) const + { + // MSB to LSB - 2015 JEDEC spec + // PPR + // Write preamble + // Read preamble + // Read preamble training mode + // Refresh abort + // CS to command address latency + // Soft PPR + // VREF monitor + // Temperature controlled refresh mode + // Temperature controlled refresh range + // Maximum power down mode + + if(iv_ppr != i_rhs.iv_ppr) + { + return iv_ppr < i_rhs.iv_ppr; + } + + if(iv_wr_preamble != i_rhs.iv_wr_preamble) + { + return iv_wr_preamble < i_rhs.iv_wr_preamble; + } + + if(iv_rd_preamble != i_rhs.iv_rd_preamble) + { + return iv_rd_preamble < i_rhs.iv_rd_preamble; + } + + if(iv_rd_pre_train_mode != i_rhs.iv_rd_pre_train_mode) + { + return iv_rd_pre_train_mode < i_rhs.iv_rd_pre_train_mode; + } + + if(iv_ref_abort != i_rhs.iv_ref_abort) + { + return iv_ref_abort < i_rhs.iv_ref_abort; + } + + if(iv_cs_cmd_latency != i_rhs.iv_cs_cmd_latency) + { + return iv_cs_cmd_latency < i_rhs.iv_cs_cmd_latency; + } + + if(iv_soft_ppr != i_rhs.iv_soft_ppr) + { + return iv_soft_ppr < i_rhs.iv_soft_ppr; + } + + if(iv_vref_mon != i_rhs.iv_vref_mon) + { + return iv_vref_mon < i_rhs.iv_vref_mon; + } + + if(iv_temp_ref_mode != i_rhs.iv_temp_ref_mode) + { + return iv_temp_ref_mode < i_rhs.iv_temp_ref_mode; + } + + if(iv_temp_refresh_range != i_rhs.iv_temp_refresh_range) + { + return iv_temp_refresh_range < i_rhs.iv_temp_refresh_range; + } + + return iv_max_pd_mode < i_rhs.iv_max_pd_mode; + } + uint8_t iv_max_pd_mode; uint8_t iv_temp_refresh_range; uint8_t iv_temp_ref_mode; @@ -996,6 +1254,69 @@ struct mrs05_data /// mrs05_data( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, fapi2::ReturnCode& o_rc ); + /// + /// @brief Less than operator + /// @param[in] i_rhs right hand comparison operator + /// @bool true if this object is less than i_rhs + /// + bool operator<(const mss::ddr4::mrs05_data& i_rhs) const + { + // MSB to LSB - 2015 JEDEC spec + // Read DBI + // Write DBI + // Data mask + // CA parity - persistent error + // RTT_PARK + // ODT input buffer + // CA parity error status + // CRC error clear + // CA parity latency mode + + if(iv_read_dbi != i_rhs.iv_read_dbi) + { + return iv_read_dbi < i_rhs.iv_read_dbi; + } + + if(iv_write_dbi != i_rhs.iv_write_dbi) + { + return iv_write_dbi < i_rhs.iv_write_dbi; + } + + if(iv_data_mask != i_rhs.iv_data_mask) + { + return iv_data_mask < i_rhs.iv_data_mask; + } + + if(iv_ca_parity != i_rhs.iv_ca_parity) + { + return iv_ca_parity < i_rhs.iv_ca_parity; + } + + const auto l_rtt_park = memcmp(iv_rtt_park, i_rhs.iv_rtt_park, sizeof(i_rhs.iv_rtt_park)); + + if(l_rtt_park != MEMCMP_EQUAL) + { + return l_rtt_park < MEMCMP_EQUAL; + } + + if(iv_odt_input_buffer != i_rhs.iv_odt_input_buffer) + { + return iv_odt_input_buffer < i_rhs.iv_odt_input_buffer; + } + + if(iv_ca_parity_error_status != i_rhs.iv_ca_parity_error_status) + { + return iv_ca_parity_error_status < i_rhs.iv_ca_parity_error_status; + } + + if(iv_crc_error_clear != i_rhs.iv_crc_error_clear) + { + return iv_crc_error_clear < i_rhs.iv_crc_error_clear; + } + + return iv_ca_parity_latency < i_rhs.iv_ca_parity_latency; + } + uint8_t iv_ca_parity_latency; uint8_t iv_crc_error_clear; uint8_t iv_ca_parity_error_status; @@ -1031,6 +1352,42 @@ struct mrs06_data /// mrs06_data( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, fapi2::ReturnCode& o_rc ); + /// + /// @brief Less than operator + /// @param[in] i_rhs right hand comparison operator + /// @bool true if this object is less than i_rhs + /// + bool operator<(const mss::ddr4::mrs06_data& i_rhs) const + { + // MSB to LSB - 2015 JEDEC spec + // TCCD_L + // Train enable + // Train range + // Train value + + if(iv_tccd_l != i_rhs.iv_tccd_l) + { + return iv_tccd_l < i_rhs.iv_tccd_l; + } + + const auto l_enable = memcmp(iv_vrefdq_train_enable, i_rhs.iv_vrefdq_train_enable, + sizeof(i_rhs.iv_vrefdq_train_enable)); + + if(l_enable != MEMCMP_EQUAL) + { + return l_enable < MEMCMP_EQUAL; + } + + const auto l_range = memcmp(iv_vrefdq_train_range, i_rhs.iv_vrefdq_train_range, sizeof(i_rhs.iv_vrefdq_train_range)); + + if(l_range != MEMCMP_EQUAL) + { + return l_range < MEMCMP_EQUAL; + } + + return memcmp(iv_vrefdq_train_value, i_rhs.iv_vrefdq_train_value, sizeof(i_rhs.iv_vrefdq_train_value)) < MEMCMP_EQUAL; + } + uint8_t iv_vrefdq_train_value[MAX_RANK_PER_DIMM]; uint8_t iv_vrefdq_train_range[MAX_RANK_PER_DIMM]; uint8_t iv_vrefdq_train_enable[MAX_RANK_PER_DIMM]; diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/mss_vpd_decoder.H b/src/import/chips/p9/procedures/hwp/memory/lib/mss_vpd_decoder.H index 01fe34174..d33f69a26 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/mss_vpd_decoder.H +++ b/src/import/chips/p9/procedures/hwp/memory/lib/mss_vpd_decoder.H @@ -47,8 +47,6 @@ namespace decoder /// inline void select_mt_blob(const std::vector<uint8_t*>& i_blobs, uint8_t** o_blob) { - constexpr uint64_t EQUAL_MEM_CONTENTS = 0; - if( i_blobs.size() != mss::PORTS_PER_MCS ) { // Asserting out instead of collecting FFDC since this is a @@ -65,7 +63,7 @@ inline void select_mt_blob(const std::vector<uint8_t*>& i_blobs, uint8_t** o_blo // correct for version layout, signature hash, and version data. constexpr uint8_t l_zero_array[mss::VPD_KEYWORD_MAX] = {}; - if( memcmp(i_blobs[0], l_zero_array, mss::VPD_KEYWORD_MAX) == EQUAL_MEM_CONTENTS ) + if( memcmp(i_blobs[0], l_zero_array, mss::VPD_KEYWORD_MAX) == MEMCMP_EQUAL ) { *o_blob = i_blobs[1]; return; 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 89bf21328..3fabd4b4e 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 @@ -620,6 +620,15 @@ const std::vector< uint64_t > dp16Traits<TARGET_TYPE_MCA>::WR_ERROR0_REG = MCA_DDRPHY_DP16_WR_ERROR0_P0_4, }; +const std::vector< uint64_t > dp16Traits<TARGET_TYPE_MCA>::DATA_BIT_ENABLE1 = +{ + MCA_DDRPHY_DP16_DATA_BIT_ENABLE1_P0_0, + MCA_DDRPHY_DP16_DATA_BIT_ENABLE1_P0_1, + MCA_DDRPHY_DP16_DATA_BIT_ENABLE1_P0_2, + MCA_DDRPHY_DP16_DATA_BIT_ENABLE1_P0_3, + MCA_DDRPHY_DP16_DATA_BIT_ENABLE1_P0_4, +}; + // Definition of the READ_DELAY registers, per rank pair const std::vector< std::vector<uint64_t> > dp16Traits<TARGET_TYPE_MCA>::READ_DELAY_REG = { 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 521a0afc1..238eaa3dc 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 @@ -206,6 +206,8 @@ class dp16Traits<fapi2::TARGET_TYPE_MCA> static const std::vector< uint64_t > RD_STATUS0_REG; static const std::vector< uint64_t > WR_ERROR0_REG; + // Registers needed for PDA + static const std::vector< uint64_t > DATA_BIT_ENABLE1; // Definitions of the gate delay and waterfall bits' locations constexpr static const uint64_t GATE_DELAY_BIT_POS[NUM_QUAD_PER_DP16] = diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/phy/write_cntrl.H b/src/import/chips/p9/procedures/hwp/memory/lib/phy/write_cntrl.H index 57cb9b34f..a751adb4d 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/phy/write_cntrl.H +++ b/src/import/chips/p9/procedures/hwp/memory/lib/phy/write_cntrl.H @@ -281,6 +281,79 @@ fapi_try_exit: return fapi2::current_err; } +/// +/// @brief Set MRS_CMD_DQ_ON +/// @tparam T fapi2::TargetType - defaults to MCA +/// @tparam TT wcTraits - defaults to MCA version of the traits +/// @param[in,out] io_data buffer to set +/// @param[in] i_value the value to write into the buffer +/// +template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCA, typename TT = wcTraits<T> > +inline void set_pda_dq_on_delay( fapi2::buffer<uint64_t>& io_data, const uint64_t i_value ) +{ + io_data.insertFromRight<TT::MRS_CMD_DQ_ON, TT::MRS_CMD_DQ_ON_LEN>(i_value); +} + +/// +/// @brief Get MRS_CMD_DQ_ON +/// @tparam T fapi2::TargetType - defaults to MCA +/// @tparam TT wcTraits - defaults to MCA version of the traits +/// @param[in] i_data buffer to read from +/// @param[out] o_value the value gotten from the buffer +/// +template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCA, typename TT = wcTraits<T> > +inline void get_pda_dq_on_delay( const fapi2::buffer<uint64_t>& i_data, uint64_t& o_value ) +{ + i_data.extractToRight<TT::MRS_CMD_DQ_ON, TT::MRS_CMD_DQ_ON_LEN>(o_value); +} + +/// +/// @brief Set MRS_CMD_DQ_OFF +/// @tparam T fapi2::TargetType - defaults to MCA +/// @tparam TT wcTraits - defaults to MCA version of the traits +/// @param[in,out] io_data buffer to set +/// @param[in] i_value the value to write into the buffer +/// +template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCA, typename TT = wcTraits<T> > +inline void set_pda_dq_off_delay( fapi2::buffer<uint64_t>& io_data, const uint64_t i_value ) +{ + io_data.insertFromRight<TT::MRS_CMD_DQ_OFF, TT::MRS_CMD_DQ_OFF_LEN>(i_value); +} + +/// +/// @brief Get MRS_CMD_DQ_OFF +/// @tparam T fapi2::TargetType - defaults to MCA +/// @tparam TT wcTraits - defaults to MCA version of the traits +/// @param[in] i_data buffer to read from +/// @param[out] o_value the value gotten from the buffer +/// +template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCA, typename TT = wcTraits<T> > +inline void get_pda_dq_off_delay( const fapi2::buffer<uint64_t>& i_data, uint64_t& o_value ) +{ + i_data.extractToRight<TT::MRS_CMD_DQ_OFF, TT::MRS_CMD_DQ_OFF_LEN>(o_value); +} + +/// +/// @brief Enables or disables MRS in PDA mode in the PHY +/// @param[in,out] io_data buffer to set +/// @param[in] i_state the value to write into the buffer +/// +inline void set_pda_mode( fapi2::buffer<uint64_t>& io_data, const mss::states i_state ) +{ + io_data.writeBit<MCA_DDRPHY_WC_CONFIG3_P0_PDA_RANKDELAY_ENABLE>(i_state); +} + +/// +/// @brief Gets the PDA enable bit in the PHY +/// @param[in] io_data buffer to set +/// @param[out] o_state the value read from the buffer +/// +inline void get_pda_mode( const fapi2::buffer<uint64_t>& i_data, mss::states& o_state ) +{ + o_state = i_data.getBit<MCA_DDRPHY_WC_CONFIG3_P0_PDA_RANKDELAY_ENABLE>() ? + mss::states::ON : + mss::states::OFF; +} /// /// @brief Read WC_RTT_WR_SWAP_ENABLE diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/shared/mss_const.H b/src/import/chips/p9/procedures/hwp/memory/lib/shared/mss_const.H index 840cce7e5..df380c9fd 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/shared/mss_const.H +++ b/src/import/chips/p9/procedures/hwp/memory/lib/shared/mss_const.H @@ -104,6 +104,9 @@ enum sizes // You can't get greater than ~0, so you'd never timeout // TODO RTC:166340 - Clean up MCBIST polling OVERLY_LARGE_NUMBER_OF_POLLS = 5000000000000, + + // Equal comparison value for memcmp + MEMCMP_EQUAL = 0, }; enum times @@ -157,6 +160,11 @@ enum ffdc_function_codes SLOPE = 70, INTERCEPT = 71, POWER_LIMIT = 72, + + // PDA function codes + PDA_WR_VREF_LATCH_CONTAINER = 80, + PDA_WR_VREF_LATCH_VECTOR = 81, + PDA_ADD_COMMAND = 82, }; enum states |