diff options
Diffstat (limited to 'src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/nvdimm_utils.C')
-rw-r--r-- | src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/nvdimm_utils.C | 148 |
1 files changed, 56 insertions, 92 deletions
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/nvdimm_utils.C b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/nvdimm_utils.C index 869e18f25..8c19b99f9 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/nvdimm_utils.C +++ b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/nvdimm_utils.C @@ -5,7 +5,7 @@ /* */ /* OpenPOWER HostBoot Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2018,2019 */ +/* Contributors Listed Below - COPYRIGHT 2018,2020 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -33,23 +33,25 @@ // *HWP Level: 3 // *HWP Consumed by: FSP:HB -#include <lib/shared/nimbus_defaults.H> #include <fapi2.H> #include <vector> +#include <lib/shared/mss_const.H> +#include <lib/shared/nimbus_defaults.H> +#include <lib/ccs/ccs_traits_nimbus.H> +#include <generic/memory/lib/ccs/ccs.H> #include <lib/dimm/ddr4/nvdimm_utils.H> #include <lib/mc/mc.H> -#include <lib/ccs/ccs.H> #include <lib/dimm/rank.H> #include <lib/mss_attribute_accessors.H> +#include <lib/mcbist/mcbist.H> +#include <lib/utils/mss_nimbus_conversions.H> #include <generic/memory/lib/utils/poll.H> #include <generic/memory/lib/utils/count_dimm.H> #include <generic/memory/lib/utils/mc/gen_mss_port.H> #include <lib/mcbist/address.H> #include <lib/mcbist/memdiags.H> -#include <lib/mcbist/mcbist.H> #include <lib/mcbist/settings.H> -#include <lib/utils/mss_nimbus_conversions.H> #include <generic/memory/lib/utils/pos.H> #include <lib/mc/port.H> #include <lib/phy/dp16.H> @@ -82,7 +84,7 @@ fapi2::ReturnCode get_maint_addr_mode_en( const fapi2::Target<fapi2::TARGET_TYPE mss::states& o_state ) { const auto& l_mcbist = mss::find_target<fapi2::TARGET_TYPE_MCBIST>(i_target); - typedef mcbistTraits<TARGET_TYPE_MCBIST> TT; + typedef mcbistTraits<> TT; fapi2::buffer<uint64_t> l_data; FAPI_TRY( mss::getScom(l_mcbist, TT::MCBAGRAQ_REG, l_data), @@ -105,7 +107,7 @@ fapi2::ReturnCode change_maint_addr_mode_en( const fapi2::Target<fapi2::TARGET_T const mss::states i_state ) { const auto& l_mcbist = mss::find_target<fapi2::TARGET_TYPE_MCBIST>(i_target); - typedef mcbistTraits<TARGET_TYPE_MCBIST> TT; + typedef mcbistTraits<> TT; fapi2::buffer<uint64_t> l_data; FAPI_TRY( mss::getScom(l_mcbist, TT::MCBAGRAQ_REG, l_data), @@ -213,10 +215,10 @@ fapi2::ReturnCode self_refresh_exit_helper( const fapi2::Target<fapi2::TARGET_TY mss::mcbist::address l_start = 0, l_end = 0; mss::mcbist::end_boundary l_end_boundary = mss::mcbist::end_boundary::STOP_AFTER_SLAVE_RANK; l_start.set_port(l_port); - mss::mcbist::stop_conditions l_stop_conditions; + mss::mcbist::stop_conditions<> l_stop_conditions; // Read with targeted scrub - FAPI_TRY ( mss::memdiags::targeted_scrub(l_mcbist, + FAPI_TRY ( mss::memdiags::targeted_scrub<mss::mc_type::NIMBUS>(l_mcbist, l_stop_conditions, l_start, l_end, @@ -264,10 +266,14 @@ template<> fapi2::ReturnCode self_refresh_entry( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target ) { fapi2::buffer<uint64_t> l_mbarpc0_data, l_mbastr0_data; + const auto& l_mcbist = mss::find_target<fapi2::TARGET_TYPE_MCBIST>(i_target); // Entry time to 0 for immediate entry constexpr uint64_t l_str_entry_time = 0; + // Stop mcbist (scrub) in case of MPIPL. It will get restarted in the later istep + FAPI_TRY(mss::mcbist::start_stop(l_mcbist, mss::states::STOP)); + // Step 1 - In MBARPC0Q, disable power domain control, set domain to MAXALL_MIN0, // and disable minimum domain reduction (allow immediate entry of STR) FAPI_TRY(mss::mc::read_mbarpc0(i_target, l_mbarpc0_data)); @@ -322,49 +328,6 @@ fapi_try_exit: } /// -/// @brief Disable powerdown mode in rc09 -/// @param[in] i_target, a fapi2::Target<TARGET_TYPE_DIMM> -/// @param[in,out] io_inst a vector of CCS instructions we should add to -/// @return FAPI2_RC_SUCCESS if and only if ok -/// -fapi2::ReturnCode rc09_disable_powerdown( const fapi2::Target<TARGET_TYPE_DIMM>& i_target, - std::vector< ccs::instruction_t<TARGET_TYPE_MCBIST> >& io_inst) -{ - FAPI_INF("rc09_disable_powerdown %s", mss::c_str(i_target)); - - constexpr uint8_t POWER_DOWN_BIT = 4; - constexpr bool l_sim = false; - constexpr uint8_t FS0 = 0; // Function space 0 - constexpr uint64_t CKE_HIGH = mss::ON; - fapi2::buffer<uint8_t> l_rc09_cw = 0; - std::vector<uint64_t> l_ranks; - - FAPI_TRY(mss::eff_dimm_ddr4_rc09(i_target, l_rc09_cw)); - - // Clear power down enable bit. - l_rc09_cw.clearBit<POWER_DOWN_BIT>(); - - FAPI_TRY( mss::rank::ranks(i_target, l_ranks) ); - - // DES to ensure we exit powerdown properly - FAPI_DBG("deselect for %s", mss::c_str(i_target)); - io_inst.push_back( ccs::des_command<TARGET_TYPE_MCBIST>() ); - - static const cw_data l_rc09_4bit_data( FS0, 9, l_rc09_cw, mss::tmrd() ); - - // Load RC09 - FAPI_TRY( control_word_engine<RCW_4BIT>(i_target, l_rc09_4bit_data, l_sim, io_inst, CKE_HIGH), - "Failed to load 4-bit RC09 control word for %s", - mss::c_str(i_target)); - - // Hold the CKE high - mss::ccs::workarounds::hold_cke_high(io_inst); - -fapi_try_exit: - return fapi2::current_err; -} - -/// /// @brief Load the rcd control words /// @param[in] i_target, a fapi2::Target<TARGET_TYPE_DIMM> /// @param[in,out] io_inst a vector of CCS instructions we should add to @@ -373,11 +336,11 @@ fapi_try_exit: /// with NVDIMMs /// fapi2::ReturnCode rcd_load_nvdimm( const fapi2::Target<TARGET_TYPE_DIMM>& i_target, - std::vector< ccs::instruction_t<TARGET_TYPE_MCBIST> >& io_inst) + std::vector< ccs::instruction_t >& io_inst) { FAPI_INF("rcd_load_nvdimm %s", mss::c_str(i_target)); - constexpr uint64_t CKE_LOW = mss::OFF; + constexpr uint64_t CKE_HIGH = mss::ON; constexpr bool l_sim = false; // Per DDR4RCD02, tSTAB is us. We want this in cycles for the CCS. @@ -425,17 +388,19 @@ fapi2::ReturnCode rcd_load_nvdimm( const fapi2::Target<TARGET_TYPE_DIMM>& i_targ }; // Load 4-bit data - FAPI_TRY( control_word_engine<RCW_4BIT>(i_target, l_rcd_4bit_data, l_sim, io_inst, CKE_LOW), + // Keeping the CKE high as this will be done not in powerdown/STR mode. Not affected for + // the RCD supplier on nvdimm + FAPI_TRY( control_word_engine<RCW_4BIT>(i_target, l_rcd_4bit_data, l_sim, io_inst, CKE_HIGH), "Failed to load 4-bit control words for %s", mss::c_str(i_target)); // Load 8-bit data - FAPI_TRY( control_word_engine<RCW_8BIT>(i_target, l_rcd_8bit_data, l_sim, io_inst, CKE_LOW), + FAPI_TRY( control_word_engine<RCW_8BIT>(i_target, l_rcd_8bit_data, l_sim, io_inst, CKE_HIGH), "Failed to load 8-bit control words for %s", mss::c_str(i_target)); // Load RC09 with CKE_LOW - FAPI_TRY( control_word_engine<RCW_4BIT>(i_target, l_rc09_4bit_data, l_sim, io_inst, CKE_LOW), + FAPI_TRY( control_word_engine<RCW_4BIT>(i_target, l_rc09_4bit_data, l_sim, io_inst, CKE_HIGH), "Failed to load 4-bit RC09 control word for %s", mss::c_str(i_target)); @@ -456,34 +421,13 @@ fapi2::ReturnCode rcd_restore( const fapi2::Target<TARGET_TYPE_MCA>& i_target ) std::vector<uint64_t> l_ranks; // A vector of CCS instructions. We'll ask the targets to fill it, and then we'll execute it - ccs::program<TARGET_TYPE_MCBIST> l_program; + ccs::program l_program; // Clear the initial delays. This will force the CCS engine to recompute the delay based on the // instructions in the CCS instruction vector l_program.iv_poll.iv_initial_delay = 0; l_program.iv_poll.iv_initial_sim_delay = 0; - // We expect to come in with the port in STR. Before proceeding with - // restoring the RCD, power down needs to be disabled first on the RCD so - // the rest of the CWs can be restored with CKE low - for ( const auto& d : mss::find_targets<TARGET_TYPE_DIMM>(i_target) ) - { - FAPI_DBG("rc09_disable_powerdown for %s", mss::c_str(d)); - FAPI_TRY( rc09_disable_powerdown(d, l_program.iv_instructions), - "Failed rc09_disable_powerdown() for %s", mss::c_str(d) ); - }// dimms - - // Exit STR first so CKE is back to high and rcd isn't ignoring us - FAPI_TRY( self_refresh_exit( i_target ) ); - - FAPI_TRY( mss::ccs::workarounds::nvdimm::execute(l_mcbist, l_program, i_target), - "Failed to execute ccs for %s", mss::c_str(i_target) ); - - // Now, drive CKE back to low via STR entry instead of pde (we have data in the drams!) - FAPI_TRY( self_refresh_entry( i_target ) ); - - l_program = ccs::program<TARGET_TYPE_MCBIST>(); //Reset the program - // Now, fill the program with instructions to program the RCD for ( const auto& d : mss::find_targets<TARGET_TYPE_DIMM>(i_target) ) { @@ -513,7 +457,7 @@ fapi2::ReturnCode post_restore_zqcal( const fapi2::Target<fapi2::TARGET_TYPE_MCA const auto& l_mcbist = mss::find_target<TARGET_TYPE_MCBIST>(i_target); std::vector<uint64_t> l_ranks; uint8_t l_trp[MAX_DIMM_PER_PORT]; - ccs::program<TARGET_TYPE_MCBIST> l_program; + ccs::program l_program; // Get tRP FAPI_TRY(mss::eff_dram_trp(mss::find_target<fapi2::TARGET_TYPE_MCS>(i_target), l_trp)); @@ -526,9 +470,9 @@ fapi2::ReturnCode post_restore_zqcal( const fapi2::Target<fapi2::TARGET_TYPE_MCA for ( const auto r : l_ranks) { FAPI_DBG("precharge_all_command for %s", mss::c_str(d)); - l_program.iv_instructions.push_back( ccs::precharge_all_command<TARGET_TYPE_MCBIST>(r, l_trp[0]) ); + l_program.iv_instructions.push_back( ccs::precharge_all_command(r, l_trp[0]) ); FAPI_DBG("zqcal_command for %s", mss::c_str(d)); - l_program.iv_instructions.push_back( ccs::zqcl_command<TARGET_TYPE_MCBIST>(r, mss::tzqinit()) ); + l_program.iv_instructions.push_back( ccs::zqcl_command(r, mss::tzqinit()) ); } }// dimms @@ -608,12 +552,12 @@ fapi2::ReturnCode post_restore_transition( const fapi2::Target<fapi2::TARGET_TYP FAPI_TRY(get_refresh_overrun_mask(i_target, l_refresh_overrun_mask)); FAPI_TRY(change_refresh_overrun_mask(i_target, mss::states::ON)); - // Restore the rcd - FAPI_TRY( rcd_restore( i_target ) ); - // Exit STR FAPI_TRY( self_refresh_exit( i_target ) ); + // Restore the rcd + FAPI_TRY( rcd_restore( i_target ) ); + // Load the MRS FAPI_TRY( mss::mrs_load( i_target, NVDIMM_WORKAROUND ) ); @@ -635,6 +579,26 @@ fapi_try_exit: } /// +/// @brief Helper to change the BAR valid state. Consumed by hostboot +/// @param[in] i_target the target associated with this subroutine +/// @return FAPI2_RC_SUCCESS iff setup was successful +/// +fapi2::ReturnCode change_bar_valid_state( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target, + const uint8_t i_state) +{ + const auto& l_mcs = mss::find_target<fapi2::TARGET_TYPE_MCS>(i_target); + fapi2::buffer<uint64_t> l_data; + + FAPI_TRY( mss::getScom(l_mcs, MCS_MCFGP, l_data) ); + l_data.writeBit<MCS_MCFGP_VALID>(i_state); + FAPI_INF("Changing MCS_MCFGP_VALID to %d on %s", i_state, mss::c_str(l_mcs)); + FAPI_TRY( mss::putScom(l_mcs, MCS_MCFGP, l_data) ); + +fapi_try_exit: + return fapi2::current_err; +} + +/// /// @brief Preload the CCS with the EPOW sequence /// @param[in] i_target the target associated with this subroutine /// @return FAPI2_RC_SUCCESS iff setup was successful @@ -643,15 +607,15 @@ fapi_try_exit: /// fapi2::ReturnCode preload_epow_sequence( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target ) { - typedef ccsTraits<fapi2::TARGET_TYPE_MCBIST> TT; + typedef ccsTraits<mss::mc_type::NIMBUS> TT; const auto& l_mcbist = mss::find_target<TARGET_TYPE_MCBIST>(i_target); const auto& l_dimms = mss::find_targets<TARGET_TYPE_DIMM>(i_target); constexpr uint64_t CS_N_ACTIVE = 0b00; uint8_t l_trp = 0; uint16_t l_trfc = 0; std::vector<uint64_t> l_ranks; - ccs::program<TARGET_TYPE_MCBIST> l_program; - ccs::instruction_t<TARGET_TYPE_MCBIST> l_inst; + ccs::program l_program; + ccs::instruction_t l_inst; // Get tRP and tRFC FAPI_TRY(mss::eff_dram_trp(i_target, l_trp)); @@ -662,14 +626,14 @@ fapi2::ReturnCode preload_epow_sequence( const fapi2::Target<fapi2::TARGET_TYPE_ // Start the program with DES and wait for tRFC // All CKE = high, all CSn = high, Reset_n = high, wait tRFC - l_inst = ccs::des_command<TARGET_TYPE_MCBIST>(l_trfc); + l_inst = ccs::des_command(l_trfc); l_inst.arr0.setBit<TT::ARR0_DDR_RESETN>(); FAPI_INF("des_command() arr0 = 0x%016lx , arr1 = 0x%016lx", l_inst.arr0, l_inst.arr1); l_program.iv_instructions.push_back(l_inst); // Precharge all command // All CKE = high, all CSn = low, Reset_n = high, wait tRP - l_inst = ccs::precharge_all_command<TARGET_TYPE_MCBIST>(0, l_trp); + l_inst = ccs::precharge_all_command(0, l_trp); l_inst.arr0.insertFromRight<TT::ARR0_DDR_CSN_0_1, TT::ARR0_DDR_CSN_0_1_LEN>(CS_N_ACTIVE); l_inst.arr0.insertFromRight<TT::ARR0_DDR_CSN_2_3, TT::ARR0_DDR_CSN_2_3_LEN>(CS_N_ACTIVE); l_inst.arr0.setBit<TT::ARR0_DDR_RESETN>(); @@ -678,7 +642,7 @@ fapi2::ReturnCode preload_epow_sequence( const fapi2::Target<fapi2::TARGET_TYPE_ // Self-refresh entry command // All CKE = low, all CSn = low, Reset_n = high, wait tCKSRE - l_inst = ccs::self_refresh_entry_command<TARGET_TYPE_MCBIST>(0, mss::tcksre(l_dimms[0])); + l_inst = ccs::self_refresh_entry_command(0, mss::tcksre(l_dimms[0])); l_inst.arr0.insertFromRight<TT::ARR0_DDR_CSN_0_1, TT::ARR0_DDR_CSN_0_1_LEN>(CS_N_ACTIVE); l_inst.arr0.insertFromRight<TT::ARR0_DDR_CSN_2_3, TT::ARR0_DDR_CSN_2_3_LEN>(CS_N_ACTIVE); l_inst.arr0.insertFromRight<TT::ARR0_DDR_CKE, TT::ARR0_DDR_CKE_LEN>(mss::CKE_LOW); @@ -688,7 +652,7 @@ fapi2::ReturnCode preload_epow_sequence( const fapi2::Target<fapi2::TARGET_TYPE_ // Push in an empty instruction for RESETn // All CKE = low, all CSn = high (default), Reset_n = low - l_inst = ccs::instruction_t<TARGET_TYPE_MCBIST>(); + l_inst = ccs::instruction_t(); FAPI_INF("Assert RESETn arr0 = 0x%016lx , arr1 = 0x%016lx", l_inst.arr0, l_inst.arr1); l_program.iv_instructions.push_back(l_inst); |