Skip to content

Commit

Permalink
Remove ZQCAL redundant CCS inst, move to draminit_training
Browse files Browse the repository at this point in the history
Lab requested to move ZQCL to draminit_training to control
(with granularity) all enabled cal steps from an attribute in
training. Also removing redundant ZQCAL being sent out for both
 a-side/b-side and addr_mirroring since this only applies to MRS cmds.

Added new attribute proposal for CAL_STEPS_ENABLE to
account for LRDIMM training steps and more control bits
such as INITIAL_PAT_WR and WR_VRE_LATCH

Change-Id: Ibb758af74966a5dd659bf3dda86f283f73956bca
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/38648
Reviewed-by: Louis Stermole <stermole@us.ibm.com>
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Tested-by: Hostboot CI <hostboot-ci+hostboot@us.ibm.com>
Reviewed-by: JACOB L. HARVEY <jlharvey@us.ibm.com>
Reviewed-by: Matt K. Light <mklight@us.ibm.com>
Reviewed-by: Thi N. Tran <thi@us.ibm.com>
Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Reviewed-by: Jennifer A. Stofer <stofer@us.ibm.com>
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/38650
Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com>
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
  • Loading branch information
aamarin authored and dcrowell77 committed May 25, 2017
1 parent 4d9e5a4 commit c00a806
Show file tree
Hide file tree
Showing 21 changed files with 480 additions and 236 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
#include <lib/dimm/bcw_load_ddr4.H>
#include <lib/phy/dp16.H>
#include <lib/dimm/ddr4/control_word_ddr4.H>
#include <lib/eff_config/timing.H>

namespace mss
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,11 +84,7 @@ fapi2::ReturnCode mrs_load( const fapi2::Target<TARGET_TYPE_DIMM>& i_target,
{
FAPI_INF("ddr4::mrs_load %s", mss::c_str(i_target));

fapi2::buffer<uint16_t> l_cal_steps;
uint64_t tDLLK = 0;
uint8_t l_dimm_type = 0;

static std::vector< mrs_data<TARGET_TYPE_MCBIST> > l_mrs_data =
static const std::vector< mrs_data<TARGET_TYPE_MCBIST> > MRS_DATA =
{
// JEDEC ordering of MRS per DDR4 power on sequence
{ 3, mrs03, mrs03_decode, mss::tmrd() },
Expand All @@ -97,64 +93,22 @@ fapi2::ReturnCode mrs_load( const fapi2::Target<TARGET_TYPE_DIMM>& i_target,
{ 4, mrs04, mrs04_decode, mss::tmrd() },
{ 2, mrs02, mrs02_decode, mss::tmrd() },
{ 1, mrs01, mrs01_decode, mss::tmrd() },

// We need to wait either tmod or tmrd before zqcl.
{ 0, mrs00, mrs00_decode, std::max(mss::tmrd(), mss::tmod(i_target)) },
// We need to wait tmod before zqcl, a non-mrs command
{ 0, mrs00, mrs00_decode, mss::tmod(i_target) },
};

std::vector< uint64_t > l_ranks;
FAPI_TRY( mss::rank::ranks(i_target, l_ranks) );
FAPI_TRY( mss::tdllk(i_target, tDLLK) );

// Load MRS
for (const auto& d : l_mrs_data)
for (const auto& d : MRS_DATA)
{
for (const auto& r : l_ranks)
{
FAPI_TRY( mrs_engine(i_target, d, r, io_inst) );
}
}

// Load ZQ Cal Long instruction only if the bit in the cal steps says to do so.
FAPI_TRY( mss::cal_step_enable(i_target, l_cal_steps) );

if (l_cal_steps.getBit<EXT_ZQCAL>() != 0)
{
for (const auto& r : l_ranks)
{
// Note: this isn't general - assumes Nimbus via MCBIST instruction here BRS
ccs::instruction_t<TARGET_TYPE_MCBIST> l_inst_a_side = ccs::zqcl_command<TARGET_TYPE_MCBIST>(i_target, r);
ccs::instruction_t<TARGET_TYPE_MCBIST> l_inst_b_side;

FAPI_TRY( mss::address_mirror(i_target, r, l_inst_a_side) );
l_inst_b_side = mss::address_invert(l_inst_a_side);

l_inst_a_side.arr1.insertFromRight<MCBIST_CCS_INST_ARR1_00_IDLES,
MCBIST_CCS_INST_ARR1_00_IDLES_LEN>(tDLLK + mss::tzqinit());
l_inst_b_side.arr1.insertFromRight<MCBIST_CCS_INST_ARR1_00_IDLES,
MCBIST_CCS_INST_ARR1_00_IDLES_LEN>(tDLLK + mss::tzqinit());

// There's nothing to decode here.
FAPI_INF("ZQCL 0x%016llx:0x%016llx %s:rank %d a-side",
l_inst_a_side.arr0, l_inst_a_side.arr1, mss::c_str(i_target), r);
FAPI_INF("ZQCL 0x%016llx:0x%016llx %s:rank %d b-side",
l_inst_b_side.arr0, l_inst_b_side.arr1, mss::c_str(i_target), r);

// Add both to the CCS program
io_inst.push_back(l_inst_a_side);
io_inst.push_back(l_inst_b_side);
}
}

// For LRDIMMs, program BCW to send ZQCal Long command to all databuffers
// in broadcast mode
FAPI_TRY( eff_dimm_type(i_target, l_dimm_type) );

if( l_dimm_type == fapi2::ENUM_ATTR_EFF_DIMM_TYPE_LRDIMM )
{
FAPI_TRY( set_command_space(i_target, command::ZQCL, io_inst) );
}

fapi_try_exit:
return fapi2::current_err;
}
Expand Down
131 changes: 131 additions & 0 deletions src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/zqcal.C
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,134 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */

///
/// @file zqcal.C
/// @brief Subroutines to send ZQCL commands
///
// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
// *HWP HWP Backup: Jacob Harvey <jlharvey@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 2
// *HWP Consumed by: FSP:HB

#include <vector>
#include <fapi2.H>

#include <lib/dimm/ddr4/zqcal.H>
#include <lib/dimm/ddr4/data_buffer_ddr4.H>
#include <lib/ccs/ccs.H>
#include <lib/eff_config/timing.H>

using fapi2::TARGET_TYPE_MCBIST;
using fapi2::TARGET_TYPE_MCA;
using fapi2::TARGET_TYPE_DIMM;

namespace mss
{

///
/// @brief Setup DRAM ZQCL
/// Specializaton for TARGET_TYPE_DIMM
/// @param[in] i_target the target associated with this cal
/// @param[in] i_rank the current rank
/// @param[in,out] io_inst a vector of CCS instructions we should add to
/// @return FAPI2_RC_SUCCESS iff setup was successful
///
template<>
fapi2::ReturnCode setup_dram_zqcal( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
const uint64_t i_rank,
std::vector< ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST> >& io_inst)
{
ccs::instruction_t<TARGET_TYPE_MCBIST> l_inst;

uint64_t tDLLK = 0;
FAPI_TRY( mss::tdllk(i_target, tDLLK) );

// Note: this isn't general - assumes Nimbus via MCBIST instruction here BRS
l_inst = ccs::zqcl_command<TARGET_TYPE_MCBIST>(i_target, i_rank);

l_inst.arr1.insertFromRight<MCBIST_CCS_INST_ARR1_00_IDLES,
MCBIST_CCS_INST_ARR1_00_IDLES_LEN>(tDLLK + mss::tzqinit());

// There's nothing to decode here.
FAPI_INF("ZQCL 0x%016llx:0x%016llx %s:rank %d",
l_inst.arr0, l_inst.arr1, mss::c_str(i_target), i_rank);

// Add both to the CCS program
io_inst.push_back(l_inst);

fapi_try_exit:
return fapi2::current_err;
}

///
/// @brief Setup LRDIMM data buffer ZQCL
/// Specializaton for TARGET_TYPE_DIMM
/// @param[in] i_target the target associated with this cal
/// @param[in,out] io_inst a vector of CCS instructions we should add to
/// @return FAPI2_RC_SUCCESS iff setup was successful
///
template<>
fapi2::ReturnCode setup_data_buffer_zqcal( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
std::vector< ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST> >& io_inst)
{
// For LRDIMMs, program BCW to send ZQCal Long command to all data buffers
// in broadcast mode
uint8_t l_dimm_type = 0;
FAPI_TRY( eff_dimm_type(i_target, l_dimm_type) );

if( l_dimm_type != fapi2::ENUM_ATTR_EFF_DIMM_TYPE_LRDIMM )
{
FAPI_INF("%s Skipping LRDIMM data buffer ZQCL, only done on LRDIMMs", mss::c_str(i_target));
return fapi2::FAPI2_RC_SUCCESS;
}

FAPI_TRY( ddr4::set_command_space(i_target, ddr4::command::ZQCL, io_inst) );

fapi_try_exit:
return fapi2::current_err;
}

///
/// @brief Setup and execute DRAM ZQCL
/// Specializaton for TARGET_TYPE_MCA
/// @param[in] i_target the target associated with this cal
/// @param[in] i_cal_steps_enabled fapi2::buffer<uint16_t> representing the cal steps to enable
/// @return FAPI2_RC_SUCCESS iff setup was successful
///
template<>
fapi2::ReturnCode setup_and_execute_zqcal( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
const fapi2::buffer<uint32_t>& i_cal_steps_enabled)
{
mss::ccs::program<TARGET_TYPE_MCBIST> l_program;

for ( const auto& d : mss::find_targets<fapi2::TARGET_TYPE_DIMM>(i_target) )
{
// If this bit isn't set, nothing to do here...
if ( i_cal_steps_enabled.getBit<DRAM_ZQCAL>() )
{
std::vector<uint64_t> l_ranks;
FAPI_TRY( mss::rank::ranks(d, l_ranks) );

for( const auto& r : l_ranks)
{
FAPI_TRY( mss::setup_dram_zqcal(d, r, l_program.iv_instructions) );
}// ranks
}

// If this bit isn't set, nothing to do here...
if ( i_cal_steps_enabled.getBit<DB_ZQCAL>() )
{
FAPI_TRY( mss::setup_data_buffer_zqcal(d, l_program.iv_instructions) );
}
}// dimm

// execute ZQCAL instructions
FAPI_TRY( mss::ccs::execute(mss::find_target<fapi2::TARGET_TYPE_MCBIST>(i_target), l_program, i_target) );

fapi_try_exit:
return fapi2::current_err;
}

} // ns mss
61 changes: 61 additions & 0 deletions src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/zqcal.H
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,64 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */

///
/// @file zqcal.H
/// @brief Subroutines to send ZQCL commands
///
// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
// *HWP HWP Backup: Jacob Harvey <jlharvey@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 2
// *HWP Consumed by: FSP:HB

#ifndef _MSS_ZQCAL_H_
#define _MSS_ZQCAL_H_

#include <vector>
#include <fapi2.H>
#include <lib/ccs/ccs.H>

namespace mss
{

///
/// @brief Setup DRAM ZQCL
/// @tparam T the target type associated with this cal
/// @tparam TT the target type of the CCS instruction
/// @param[in] i_target the target associated with this cal
/// @param[in] i_rank the current rank
/// @param[in,out] io_inst a vector of CCS instructions we should add to
/// @return FAPI2_RC_SUCCESS iff setup was successful
///
template< fapi2::TargetType T, fapi2::TargetType TT >
fapi2::ReturnCode setup_dram_zqcal( const fapi2::Target<T>& i_target,
const uint64_t i_rank,
std::vector< ccs::instruction_t<TT> >& io_inst);

///
/// @brief Setup LRDIMM data buffer ZQCL
/// @tparam T the target type associated with this cal
/// @tparam TT the target type of the CCS instruction
/// @param[in] i_target the target associated with this cal
/// @param[in,out] io_inst a vector of CCS instructions we should add to
/// @return FAPI2_RC_SUCCESS iff setup was successful
///
template< fapi2::TargetType T, fapi2::TargetType TT >
fapi2::ReturnCode setup_data_buffer_zqcal( const fapi2::Target<T>& i_target,
std::vector< ccs::instruction_t<TT> >& io_inst);

///
/// @brief Setup and execute DRAM ZQCL
/// @tparam T, the target type associated with this cal
/// @param[in] i_target the target associated with this cal
/// @param[in] i_cal_steps_enabled fapi2::buffer<uint16_t> representing the cal steps to enable
/// @return FAPI2_RC_SUCCESS iff setup was successful
///
template< fapi2::TargetType T >
fapi2::ReturnCode setup_and_execute_zqcal( const fapi2::Target<T>& i_target,
const fapi2::buffer<uint32_t>& i_cal_steps_enabled);

}// mss

#endif
29 changes: 16 additions & 13 deletions src/import/chips/p9/procedures/hwp/memory/lib/dimm/eff_dimm.C
Original file line number Diff line number Diff line change
Expand Up @@ -4574,20 +4574,17 @@ fapi_try_exit:
///
fapi2::ReturnCode eff_dimm::cal_step_enable()
{
// These constexpr values are taken from the defiitions in ATTR_MSS_CAL_STEP_ENABLE
// RD/WR VREF correspond to 0x0400 and 0x0100 respectively.
constexpr uint64_t ONLY_1D = 0xFAC0;
constexpr uint64_t RD_VREF_WR_VREF_1D = 0xFFC0;
const uint16_t l_cal_step_value = (mss::chip_ec_feature_skip_hw_vref_cal(iv_mcs) ? ONLY_1D : RD_VREF_WR_VREF_1D);
const uint32_t l_cal_step_value = (mss::chip_ec_feature_skip_hw_vref_cal(iv_mcs) ?
RUN_CAL_SKIP_WR_RD_2D_VREF : RUN_ALL_CAL_STEPS);

FAPI_DBG("%s %s running HW VREF cal. cal_step value: 0x%0x VREF", mss::c_str(iv_mcs),
mss::chip_ec_feature_skip_hw_vref_cal(iv_mcs) ? "not" : "", l_cal_step_value);

// Sets up the vector
std::vector<uint16_t> l_cal_step(PORTS_PER_MCS, l_cal_step_value);
std::vector<uint32_t> l_cal_step(PORTS_PER_MCS, l_cal_step_value);

// Sets the values
return FAPI_ATTR_SET(fapi2::ATTR_MSS_CAL_STEP_ENABLE, iv_mcs, UINT16_VECTOR_TO_1D_ARRAY(l_cal_step, PORTS_PER_MCS));
// Sets the value
return FAPI_ATTR_SET(fapi2::ATTR_MSS_CAL_STEP_ENABLE, iv_mcs, UINT32_VECTOR_TO_1D_ARRAY(l_cal_step, PORTS_PER_MCS));
}

///
Expand All @@ -4597,8 +4594,9 @@ fapi2::ReturnCode eff_dimm::cal_step_enable()
fapi2::ReturnCode eff_dimm::rdvref_enable_bit()
{
// This enables which bits should be run for RD VREF, all 1's indicates that all bits should be run
constexpr uint64_t DISABLE = 0x0000;
constexpr uint64_t ENABLE = 0xFFFF;
constexpr uint16_t DISABLE = 0x0000;
constexpr uint16_t ENABLE = 0xFFFF;

const uint16_t l_vref_enable_value = (mss::chip_ec_feature_skip_hw_vref_cal(iv_mcs) ? DISABLE : ENABLE);

FAPI_DBG("%s %s running HW VREF cal. VREF enable value: 0x%0x", mss::c_str(iv_mcs),
Expand All @@ -4608,16 +4606,21 @@ fapi2::ReturnCode eff_dimm::rdvref_enable_bit()
std::vector<uint16_t> l_vref_enable(PORTS_PER_MCS, l_vref_enable_value);

// Sets the values
return FAPI_ATTR_SET(fapi2::ATTR_MSS_RDVREF_CAL_ENABLE, iv_mcs, UINT16_VECTOR_TO_1D_ARRAY(l_vref_enable,
PORTS_PER_MCS));
return FAPI_ATTR_SET(fapi2::ATTR_MSS_RDVREF_CAL_ENABLE,
iv_mcs,
UINT16_VECTOR_TO_1D_ARRAY(l_vref_enable, PORTS_PER_MCS));
}

///
/// @brief Determines and sets ATTR_MSS_PHY_SEQ_REFRESH_
/// @brief Determines and sets ATTR_MSS_PHY_SEQ_REFRESH
/// @return fapi2::FAPI2_RC_SUCCESS if okay
///
fapi2::ReturnCode eff_dimm::phy_seq_refresh()
{
// default setting is to turn on this workaround, this
// isn't an ec_chip_feature attribute because there is no
// known fix for this coming in DD2.0 modules. But the
// lab wants a control switch
constexpr size_t ENABLE = 1;

FAPI_DBG("Setting PHY_SEQ_REFRESH to %d on %s", ENABLE, mss::c_str(iv_mcs));
Expand Down

0 comments on commit c00a806

Please sign in to comment.