summaryrefslogtreecommitdiffstats
path: root/src/import/chips/p9/procedures/hwp
diff options
context:
space:
mode:
authorBrian Silver <bsilver@us.ibm.com>2016-10-13 09:51:57 -0500
committerDaniel M. Crowell <dcrowell@us.ibm.com>2016-10-16 21:40:15 -0400
commit7326ad3c9b77f2adc19e58280b50934b69c16032 (patch)
treed439631fa4784f6c7f2ca0f3e493077032f9c32e /src/import/chips/p9/procedures/hwp
parent7672512af9ddd64b5899ec41ba817905dd781730 (diff)
downloadtalos-hostboot-7326ad3c9b77f2adc19e58280b50934b69c16032.tar.gz
talos-hostboot-7326ad3c9b77f2adc19e58280b50934b69c16032.zip
Changes to limit DLL cal on spare DP8, stop CSS before starting
Enable parity after command for CCS Disable parity via RC14 Enable DLL (MRS) enable Send 0 value RCD Repair clock-enable RCD control word Change-Id: Id46a675afbc535989f7e0e451a084dfdc4d4a962 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/31142 Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Reviewed-by: ANDRE A. MARIN <aamarin@us.ibm.com> Tested-by: Hostboot CI <hostboot-ci+hostboot@us.ibm.com> Reviewed-by: JACOB L. HARVEY <jlharvey@us.ibm.com> Dev-Ready: Brian R. Silver <bsilver@us.ibm.com> Reviewed-by: Jennifer A. Stofer <stofer@us.ibm.com> Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/31170 Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/import/chips/p9/procedures/hwp')
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/ccs/ccs.C41
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/ccs/ccs.H63
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/rcd_load_ddr4.C70
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/eff_config/eff_config.C15
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/phy/ddr_phy.C2
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/phy/dp16.C12
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/spd/common/raw_cards.C114
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit.C13
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit_training.C15
9 files changed, 201 insertions, 144 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 ef027e813..1428555fd 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
@@ -120,7 +120,7 @@ fapi2::ReturnCode execute_inst_array(const fapi2::Target<TARGET_TYPE_MCBIST>& i_
mss::poll(i_target, TT::STATQ_REG, i_program.iv_poll,
[&status](const size_t poll_remaining, const fapi2::buffer<uint64_t>& stat_reg) -> bool
{
- FAPI_DBG("ccs statq 0x%llx, remaining: %d", stat_reg, poll_remaining);
+ FAPI_INF("ccs statq 0x%llx, remaining: %d", stat_reg, poll_remaining);
status = stat_reg;
return status.getBit<TT::CCS_IN_PROGRESS>() != 1;
},
@@ -129,7 +129,7 @@ fapi2::ReturnCode execute_inst_array(const fapi2::Target<TARGET_TYPE_MCBIST>& i_
// Check for done and success. DONE being the only bit set.
if (status == STAT_QUERY_SUCCESS)
{
- FAPI_DBG("CCS Executed Successfully.");
+ FAPI_INF("CCS Executed Successfully.");
goto fapi_try_exit;
}
@@ -154,17 +154,30 @@ fapi2::ReturnCode execute( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target,
ccs::program<TARGET_TYPE_MCBIST>& i_program,
const std::vector< fapi2::Target<TARGET_TYPE_MCA> >& i_ports)
{
+ typedef ccsTraits<TARGET_TYPE_MCBIST> TT;
+
// Subtract one for the idle we insert at the end
- static const size_t CCS_INSTRUCTION_DEPTH = 32 - 1;
- static const uint64_t CCS_ARR0_ZERO = MCBIST_CCS_INST_ARR0_00;
- static const uint64_t CCS_ARR1_ZERO = MCBIST_CCS_INST_ARR1_00;
+ constexpr size_t CCS_INSTRUCTION_DEPTH = 32 - 1;
+ constexpr uint64_t CCS_ARR0_ZERO = MCBIST_CCS_INST_ARR0_00;
+ constexpr uint64_t CCS_ARR1_ZERO = MCBIST_CCS_INST_ARR1_00;
ccs::instruction_t<TARGET_TYPE_MCBIST> l_des = ccs::des_command<TARGET_TYPE_MCBIST>();
- FAPI_DBG("loading ccs instructions (%d) for %s", i_program.iv_instructions.size(), mss::c_str(i_target));
+ FAPI_INF("loading ccs instructions (%d) for %s", i_program.iv_instructions.size(), mss::c_str(i_target));
auto l_inst_iter = i_program.iv_instructions.begin();
+ // Stop the CCS engine just for giggles - it might be running ...
+ FAPI_TRY( start_stop(i_target, mss::states::STOP) );
+ FAPI_ASSERT( mss::poll(i_target, TT::STATQ_REG, poll_parameters(),
+ [](const size_t poll_remaining, const fapi2::buffer<uint64_t>& stat_reg) -> bool
+ {
+ FAPI_INF("ccs statq (stop) 0x%llx, remaining: %d", stat_reg, poll_remaining);
+ return stat_reg.getBit<TT::CCS_IN_PROGRESS>() != 1;
+ }),
+ fapi2::MSS_CCS_HUNG_TRYING_TO_STOP().set_TARGET_IN_ERROR(i_target),
+ "CCS appears hung (trying to stop)");
+
while (l_inst_iter != i_program.iv_instructions.end())
{
size_t l_inst_count = 0;
@@ -193,7 +206,7 @@ fapi2::ReturnCode execute( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target,
l_total_delay += l_delay * (l_repeat + 1);
- FAPI_DBG("css inst %d: 0x%016lX 0x%016lX (0x%lx, 0x%lx) delay: 0x%x (0x%x) %s",
+ FAPI_INF("css inst %d: 0x%016lX 0x%016lX (0x%lx, 0x%lx) delay: 0x%x (0x%x) %s",
l_inst_count, l_inst_iter->arr0, l_inst_iter->arr1,
CCS_ARR0_ZERO + l_inst_count, CCS_ARR1_ZERO + l_inst_count,
l_delay, l_total_delay, mss::c_str(i_target));
@@ -211,7 +224,7 @@ fapi2::ReturnCode execute( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target,
i_program.iv_poll.iv_initial_sim_delay = cycles_to_simcycles(l_total_delay);
}
- FAPI_DBG("executing ccs instructions (%d:%d, %d) for %s",
+ FAPI_INF("executing ccs instructions (%d:%d, %d) for %s",
i_program.iv_instructions.size(), l_inst_count, i_program.iv_poll.iv_initial_delay, mss::c_str(i_target));
// Insert a DES as our last instruction. DES is idle state anyway and having this
@@ -221,14 +234,14 @@ fapi2::ReturnCode execute( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target,
FAPI_TRY( mss::putScom(i_target, CCS_ARR0_ZERO + l_inst_count, l_des.arr0) );
FAPI_TRY( mss::putScom(i_target, CCS_ARR1_ZERO + l_inst_count, l_des.arr1) );
- FAPI_DBG("css inst %d fixup: 0x%016lX 0x%016lX (0x%lx, 0x%lx) %s",
+ FAPI_INF("css inst %d fixup: 0x%016lX 0x%016lX (0x%lx, 0x%lx) %s",
l_inst_count, l_des.arr0, l_des.arr1,
CCS_ARR0_ZERO + l_inst_count, CCS_ARR1_ZERO + l_inst_count, mss::c_str(i_target));
// Kick off the CCS engine - per port. No broadcast mode for CCS (per Shelton 9/23/15)
- for (auto p : i_ports)
+ for (const auto& p : i_ports)
{
- FAPI_DBG("executing CCS array for port %d (%s)", mss::relative_pos<TARGET_TYPE_MCBIST>(p), mss::c_str(p));
+ FAPI_INF("executing CCS array for port %d (%s)", mss::relative_pos<TARGET_TYPE_MCBIST>(p), mss::c_str(p));
FAPI_TRY( select_ports( i_target, mss::relative_pos<TARGET_TYPE_MCBIST>(p)) );
FAPI_TRY( execute_inst_array(i_target, i_program) );
}
@@ -244,14 +257,14 @@ fapi_try_exit:
/// @tparam T the fapi2::TargetType - derived
/// @tparam TT the ccsTraits associated with T - derived
/// @param[in] fapi2::Target<TARGET_TYPE_MCBIST>& the target to effect
-/// @param[in] the buffer representing the mode register
+/// @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
/// @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 )
+void copy_cke_to_spare_cke<TARGET_TYPE_MCBIST>( const fapi2::Target<TARGET_TYPE_MCBIST>&,
+ fapi2::buffer<uint64_t>&, bool )
{
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 832c22a82..f8b3596e2 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
@@ -63,10 +63,10 @@ template<>
class ccsTraits<fapi2::TARGET_TYPE_MCBIST>
{
public:
- static const uint64_t MODEQ_REG = MCBIST_CCS_MODEQ;
- static const uint64_t MCB_CNTL_REG = MCBIST_MCB_CNTLQ;
- static const uint64_t CNTLQ_REG = MCBIST_CCS_CNTLQ;
- static const uint64_t STATQ_REG = MCBIST_CCS_STATQ;
+ static constexpr uint64_t MODEQ_REG = MCBIST_CCS_MODEQ;
+ static constexpr uint64_t MCB_CNTL_REG = MCBIST_MCB_CNTLQ;
+ static constexpr uint64_t CNTLQ_REG = MCBIST_CCS_CNTLQ;
+ static constexpr uint64_t STATQ_REG = MCBIST_CCS_STATQ;
enum
{
@@ -532,14 +532,14 @@ fapi_try_exit:
/// @tparam T the target type of the chiplet which executes the CCS instruction
/// @tparam TT the CCS traits of the chiplet which executes the CCS instruction
/// @param[in] the target to effect
-/// @param[in] i_buffer the buffer representing the mode register
+/// @param[in,out] io_buffer the buffer representing the mode register
/// @param[in] i_value true iff stop whenever failure occurs.
/// @return void
///
template< fapi2::TargetType T, typename TT = ccsTraits<T> >
-inline void stop_on_err( const fapi2::Target<T>&, fapi2::buffer<uint64_t>& i_buffer, bool i_value)
+inline void stop_on_err( const fapi2::Target<T>&, fapi2::buffer<uint64_t>& io_buffer, const bool i_value)
{
- i_buffer.writeBit<TT::STOP_ON_ERR>(i_value);
+ io_buffer.writeBit<TT::STOP_ON_ERR>(i_value);
}
///
@@ -547,14 +547,14 @@ inline void stop_on_err( const fapi2::Target<T>&, fapi2::buffer<uint64_t>& i_buf
/// @tparam T the target type of the chiplet which executes the CCS instruction
/// @tparam TT the CCS traits of the chiplet which executes the CCS instruction
/// @param[in] the target to effect
-/// @param[in] i_buffer the buffer representing the mode register
+/// @param[in,out] io_buffer the buffer representing the mode register
/// @return void
///
template< fapi2::TargetType T, typename TT = ccsTraits<T> >
-inline void disable_ecc( const fapi2::Target<T>&, fapi2::buffer<uint64_t>& i_buffer)
+inline void disable_ecc( const fapi2::Target<T>&, fapi2::buffer<uint64_t>& io_buffer)
{
- i_buffer.setBit<TT::DISABLE_ECC_ARRAY_CHK>();
- i_buffer.setBit<TT::DISABLE_ECC_ARRAY_CORRECTION>();
+ io_buffer.setBit<TT::DISABLE_ECC_ARRAY_CHK>();
+ io_buffer.setBit<TT::DISABLE_ECC_ARRAY_CORRECTION>();
}
///
@@ -563,14 +563,29 @@ inline void disable_ecc( const fapi2::Target<T>&, fapi2::buffer<uint64_t>& i_buf
/// @tparam T the target type of the chiplet which executes the CCS instruction
/// @tparam TT the CCS traits of the chiplet which executes the CCS instruction
/// @param[in] the target to effect
-/// @param[in] i_buffer the buffer representing the mode register
+/// @param[in,out] io_buffer the buffer representing the mode register
/// @param[in] i_value true iff ignore any array ue or sue errors.
/// @return void
///
template< fapi2::TargetType T, typename TT = ccsTraits<T> >
-inline void ue_disable( const fapi2::Target<T>&, fapi2::buffer<uint64_t>& i_buffer, bool i_value)
+inline void ue_disable( const fapi2::Target<T>&, fapi2::buffer<uint64_t>& io_buffer, const bool i_value)
+{
+ io_buffer.writeBit<TT::UE_DISABLE>(i_value);
+}
+
+///
+/// @brief User sets to a '1'b to force the Hdw to delay parity a cycle
+/// @tparam T the target type of the chiplet which executes the CCS instruction
+/// @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
+/// @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)
{
- i_buffer.writeBit<TT::UE_DISABLE>(i_value);
+ io_buffer.writeBit<TT::CFG_PARITY_AFTER_CMD>(i_value);
}
///
@@ -578,17 +593,17 @@ inline void ue_disable( const fapi2::Target<T>&, fapi2::buffer<uint64_t>& i_buff
/// @tparam T the target type of the chiplet which executes the CCS instruction
/// @tparam TT the CCS traits of the chiplet which executes the CCS instruction
/// @param[in] the target to effect
-/// @param[in] i_buffer the buffer representing the mode register
+/// @param[in,out] io_buffer the buffer representing the mode register
/// @param[in] i_count the count to wait for DDR cal to complete.
/// @param[in] i_mult the DDR calibration time multiplaction factor
/// @return void
///
template< fapi2::TargetType T, typename TT = ccsTraits<T> >
-inline void cal_count( const fapi2::Target<T>&, fapi2::buffer<uint64_t>& i_buffer,
+inline void cal_count( const fapi2::Target<T>&, fapi2::buffer<uint64_t>& io_buffer,
const uint64_t i_count, const uint64_t i_mult)
{
- i_buffer.insertFromRight<TT::DDR_CAL_TIMEOUT_CNT, TT::DDR_CAL_TIMEOUT_CNT_LEN>(i_count);
- i_buffer.insertFromRight<TT::DDR_CAL_TIMEOUT_CNT_MULT, TT::DDR_CAL_TIMEOUT_CNT_MULT_LEN>(i_mult);
+ io_buffer.insertFromRight<TT::DDR_CAL_TIMEOUT_CNT, TT::DDR_CAL_TIMEOUT_CNT_LEN>(i_count);
+ io_buffer.insertFromRight<TT::DDR_CAL_TIMEOUT_CNT_MULT, TT::DDR_CAL_TIMEOUT_CNT_MULT_LEN>(i_mult);
}
///
@@ -600,27 +615,27 @@ inline void cal_count( const fapi2::Target<T>&, fapi2::buffer<uint64_t>& i_buffe
/// @tparam T the fapi2::TargetType - derived
/// @tparam TT the ccsTraits associated with T - derived
/// @param[in] i_target the target to effect
-/// @param[in] i_buffer the buffer representing the mode register
+/// @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
/// @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>& i_buffer, bool i_value);
+void copy_cke_to_spare_cke( const fapi2::Target<T>&, fapi2::buffer<uint64_t>& io_buffer, const bool i_value);
///
/// @brief Read the modeq register appropriate for this target
/// @tparam T the target type of the chiplet which executes the CCS instruction
/// @tparam TT the CCS traits of the chiplet which executes the CCS instruction
/// @param[in] i_target the target to effect
-/// @param[in] i_buffer the buffer representing the mode register
+/// @param[in,out] io_buffer the buffer representing the mode register
/// @return FAPI2_RC_SUCCSS iff ok
///
template< fapi2::TargetType T, typename TT = ccsTraits<T> >
-inline fapi2::ReturnCode read_mode( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& i_buffer)
+inline fapi2::ReturnCode read_mode( const fapi2::Target<T>& i_target, fapi2::buffer<uint64_t>& io_buffer)
{
FAPI_DBG("read mode 0x%llx", TT::MODEQ_REG);
- return mss::getScom(i_target, TT::MODEQ_REG, i_buffer);
+ return mss::getScom(i_target, TT::MODEQ_REG, io_buffer);
}
///
@@ -690,7 +705,7 @@ fapi2::ReturnCode execute_inst_array(const fapi2::Target<T>& i_target, ccs::prog
/// @return FAPI2_RC_SUCCESS iff success
///
template< fapi2::TargetType T, typename TT = ccsTraits<T> >
-fapi2::ReturnCode start_stop( const fapi2::Target<T>& i_target, bool i_start_stop );
+fapi2::ReturnCode start_stop( const fapi2::Target<T>& i_target, const bool i_start_stop );
///
/// @brief Query the status of the CCS engine
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/rcd_load_ddr4.C b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/rcd_load_ddr4.C
index a1f57e489..acad2884d 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/rcd_load_ddr4.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/rcd_load_ddr4.C
@@ -62,7 +62,7 @@ fapi2::ReturnCode rcd_load_ddr4( const fapi2::Target<TARGET_TYPE_DIMM>& i_target
// Per DDR4RCD02, tSTAB is us. We want this in cycles for the CCS.
const uint64_t tSTAB = mss::us_to_cycles(i_target, mss::tstab());
- static std::vector< rcd_data > l_rcd_4bit_data =
+ static const std::vector< rcd_data > l_rcd_4bit_data =
{
{ 0, eff_dimm_ddr4_rc00, mss::tmrd() }, { 1, eff_dimm_ddr4_rc01, mss::tmrd() },
{ 2, eff_dimm_ddr4_rc02, tSTAB }, { 3, eff_dimm_ddr4_rc03, mss::tmrd_l() },
@@ -74,7 +74,7 @@ fapi2::ReturnCode rcd_load_ddr4( const fapi2::Target<TARGET_TYPE_DIMM>& i_target
{ 15, eff_dimm_ddr4_rc15, mss::tmrd() },
};
- static std::vector< rcd_data > l_rcd_8bit_data =
+ static const std::vector< rcd_data > l_rcd_8bit_data =
{
{ 1, eff_dimm_ddr4_rc_1x, mss::tmrd() }, { 2, eff_dimm_ddr4_rc_2x, mss::tmrd() },
{ 3, eff_dimm_ddr4_rc_3x, tSTAB }, { 4, eff_dimm_ddr4_rc_4x, mss::tmrd() },
@@ -87,55 +87,63 @@ fapi2::ReturnCode rcd_load_ddr4( const fapi2::Target<TARGET_TYPE_DIMM>& i_target
fapi2::buffer<uint8_t> l_value;
// A little 4bit RCD love ...
- for (auto d : l_rcd_4bit_data)
+ for (const auto& d : l_rcd_4bit_data)
{
+ // Keep in mind that swizzles count back from SWIZZLE_START for the apprporiate length in bits
+ constexpr uint64_t DATA_LEN = 4;
+ constexpr uint64_t WORD_LEN = 4;
+ constexpr uint64_t SWIZZLE_START = 7;
+
// Note: this isn't general - assumes Nimbus via MCBIST instruction here BRS
ccs::instruction_t<TARGET_TYPE_MCBIST> l_inst = ccs::rcd_command<TARGET_TYPE_MCBIST>(i_target);
FAPI_TRY( d.iv_func(i_target, l_value) );
- // If this control word would be set to 0, skip it - we can rely on the DIMM default
- if (l_value != 0)
- {
- // Data to be written into the 4-bit configuration registers need to be presented on DA0 .. DA3
- mss::swizzle<MCBIST_CCS_INST_ARR0_00_DDR_ADDRESS_0_13, 4, 7>(l_value, l_inst.arr0);
+ // Don't care if the value is 0 - send it anyway
+ // Data to be written into the 4-bit configuration registers need to be presented on DA0 .. DA3
+ mss::swizzle<MCBIST_CCS_INST_ARR0_00_DDR_ADDRESS_0_13,
+ DATA_LEN, SWIZZLE_START>(l_value, l_inst.arr0);
- // Selection of each word of 4-bit control bits is presented on inputs DA4 through DA12
- mss::swizzle < MCBIST_CCS_INST_ARR0_00_DDR_ADDRESS_0_13 + 4, 4, 7 > (d.iv_rcd, l_inst.arr0);
+ // Selection of each word of 4-bit control bits is presented on inputs DA4 through DA12
+ mss::swizzle < MCBIST_CCS_INST_ARR0_00_DDR_ADDRESS_0_13 + DATA_LEN,
+ WORD_LEN, SWIZZLE_START > (d.iv_rcd, l_inst.arr0);
- // For changes to the control word setting [...] the controller needs to wait tMRD[tSTAB] after
- // the last control word access, before further access to the DRAM can take place.
- l_inst.arr1.insertFromRight<MCBIST_CCS_INST_ARR1_00_IDLES, MCBIST_CCS_INST_ARR1_00_IDLES_LEN>(d.iv_delay);
+ // For changes to the control word setting [...] the controller needs to wait tMRD[tSTAB] after
+ // the last control word access, before further access to the DRAM can take place.
+ l_inst.arr1.insertFromRight<MCBIST_CCS_INST_ARR1_00_IDLES, MCBIST_CCS_INST_ARR1_00_IDLES_LEN>(d.iv_delay);
- FAPI_INF("RCD%02d value 0x%x (%d) 0x%016llx:0x%016llx %s", uint8_t(d.iv_rcd), l_value, d.iv_delay,
- l_inst.arr0, l_inst.arr1, mss::c_str(i_target));
- i_inst.push_back(l_inst);
- }
+ FAPI_INF("RCD%02d value 0x%x (%d) 0x%016llx:0x%016llx %s", uint8_t(d.iv_rcd), l_value, d.iv_delay,
+ l_inst.arr0, l_inst.arr1, mss::c_str(i_target));
+ i_inst.push_back(l_inst);
}
// 8bit's turn
for (auto d : l_rcd_8bit_data)
{
+ // Keep in mind that swizzles count back from SWIZZLE_START for the apprporiate length in bits
+ constexpr uint64_t DATA_LEN = 8;
+ constexpr uint64_t WORD_LEN = 5;
+ constexpr uint64_t SWIZZLE_START = 7;
+
// Note: this isn't general - assumes Nimbus via MCBIST instruction here BRS
ccs::instruction_t<TARGET_TYPE_MCBIST> l_inst = ccs::rcd_command<TARGET_TYPE_MCBIST>(i_target);
FAPI_TRY( d.iv_func(i_target, l_value) );
- // If this control word would be set to 0, skip it - we can rely on the DIMM default
- if (l_value != 0)
- {
- // Data to be written into the 8-bit configuration registers need to be presented on DA0 .. DA7
- mss::swizzle<MCBIST_CCS_INST_ARR0_00_DDR_ADDRESS_0_13, 8, 7>(l_value, l_inst.arr0);
+ // Don't care if the value is 0 - send it anyway
+ // Data to be written into the 8-bit configuration registers need to be presented on DA0 .. DA7
+ mss::swizzle<MCBIST_CCS_INST_ARR0_00_DDR_ADDRESS_0_13,
+ DATA_LEN, SWIZZLE_START>(l_value, l_inst.arr0);
- // Selection of each word of 8-bit control bits is presented on inputs DA8 through DA12.
- mss::swizzle < MCBIST_CCS_INST_ARR0_00_DDR_ADDRESS_0_13 + 8, 5, 7 > (d.iv_rcd, l_inst.arr0);
+ // Selection of each word of 8-bit control bits is presented on inputs DA8 through DA12.
+ mss::swizzle < MCBIST_CCS_INST_ARR0_00_DDR_ADDRESS_0_13 + DATA_LEN,
+ WORD_LEN, SWIZZLE_START > (d.iv_rcd, l_inst.arr0);
- // For changes to the control word setting [...] the controller needs to wait tMRD[tSTAB] after
- // the last control word access, before further access to the DRAM can take place.
- l_inst.arr1.insertFromRight<MCBIST_CCS_INST_ARR1_00_IDLES, MCBIST_CCS_INST_ARR1_00_IDLES_LEN>(d.iv_delay);
+ // For changes to the control word setting [...] the controller needs to wait tMRD[tSTAB] after
+ // the last control word access, before further access to the DRAM can take place.
+ l_inst.arr1.insertFromRight<MCBIST_CCS_INST_ARR1_00_IDLES, MCBIST_CCS_INST_ARR1_00_IDLES_LEN>(d.iv_delay);
- FAPI_INF("RCD%XX value 0x%x (%d) 0x%016llx:0x%016llx %s", uint8_t(d.iv_rcd), l_value, d.iv_delay,
- l_inst.arr0, l_inst.arr1, mss::c_str(i_target));
- i_inst.push_back(l_inst);
- }
+ FAPI_INF("RCD%XX value 0x%x (%d) 0x%016llx:0x%016llx %s", uint8_t(d.iv_rcd), l_value, d.iv_delay,
+ l_inst.arr0, l_inst.arr1, mss::c_str(i_target));
+ i_inst.push_back(l_inst);
}
fapi_try_exit:
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/eff_config.C b/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/eff_config.C
index ea214b833..92a5da74d 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/eff_config.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/eff_config.C
@@ -1299,6 +1299,8 @@ fapi_try_exit:
///
fapi2::ReturnCode eff_config::dimm_rc14(const fapi2::Target<TARGET_TYPE_DIMM>& i_target)
{
+ constexpr uint8_t DISABLE_PARITY_MASK = 0b11111110;
+
// Targets
const auto l_mcs = find_target<TARGET_TYPE_MCS>(i_target);
const auto l_mca = find_target<TARGET_TYPE_MCA>(i_target);
@@ -1307,14 +1309,19 @@ fapi2::ReturnCode eff_config::dimm_rc14(const fapi2::Target<TARGET_TYPE_DIMM>& i
const auto l_port_num = index(l_mca);
const auto l_dimm_num = index(i_target);
+ uint8_t l_hacked_rc14;
+
// Retrieve MCS attribute data
uint8_t l_attrs_dimm_rc14[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
FAPI_TRY( eff_dimm_ddr4_rc14(l_mcs, &l_attrs_dimm_rc14[0][0]) );
+ // Disable parity checking
+ l_hacked_rc14 = iv_pDecoder->iv_raw_card.iv_rc0e & DISABLE_PARITY_MASK;
+
// Update MCS attribute
- l_attrs_dimm_rc14[l_port_num][l_dimm_num] = iv_pDecoder->iv_raw_card.iv_rc0e;
+ l_attrs_dimm_rc14[l_port_num][l_dimm_num] = l_hacked_rc14;
- FAPI_INF( "%s: RC14 setting: %d", c_str(i_target), l_attrs_dimm_rc14[l_port_num][l_dimm_num] );
+ FAPI_INF( "%s: RC14 setting: 0x%0x", c_str(i_target), l_attrs_dimm_rc14[l_port_num][l_dimm_num] );
FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_DDR4_RC14, l_mcs, l_attrs_dimm_rc14) );
fapi_try_exit:
@@ -2000,8 +2007,8 @@ fapi2::ReturnCode eff_config::dll_reset(const fapi2::Target<TARGET_TYPE_DIMM>& i
FAPI_TRY( eff_dram_dll_reset(l_mcs, &l_attrs_dll_reset[0][0]) );
- // Default is to not reset DLLs during IPL.
- l_attrs_dll_reset[l_port_num][l_dimm_num] = fapi2::ENUM_ATTR_EFF_DRAM_DLL_RESET_NO;
+ // Default is to reset DLLs during IPL.
+ l_attrs_dll_reset[l_port_num][l_dimm_num] = fapi2::ENUM_ATTR_EFF_DRAM_DLL_RESET_YES;
FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DRAM_DLL_RESET, l_mcs, l_attrs_dll_reset),
"Failed setting attribute for BL");
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 9b83c756f..4c7759395 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
@@ -114,7 +114,7 @@ fapi2::ReturnCode enable_zctl( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target
FAPI_TRY( mss::scom_blastah(l_ports, l_zcal_reset_reg, l_data) );
// 12. Wait at least 1024 dphy_gckn cycles (no sense in doing this in the polling loop as
- // we'll end up doing this delay for every por when we only need to do it once since we
+ // we'll end up doing this delay for every port when we only need to do it once since we
// kicked them all off in parallel
fapi2::delay(mss::cycles_to_ns(i_target, 1024), mss::cycles_to_simcycles(1024));
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 fc20b1965..acf0792e2 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
@@ -1086,7 +1086,6 @@ fapi2::ReturnCode reset_dll( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_targ
// Magic numbers are from the PHY team (see the ddry phy initfile, too.) They are, in fact,
// magic numbers ...
// TK How about a little broadcast action here? BRS
- FAPI_TRY( mss::scom_blastah(i_target, TT::DLL_CNFG_REG, 0x8100) );
FAPI_TRY( mss::scom_blastah(i_target, TT::DLL_DAC_LOWER_REG, 0x8000) );
FAPI_TRY( mss::scom_blastah(i_target, TT::DLL_DAC_UPPER_REG, 0xffe0) );
FAPI_TRY( mss::scom_blastah(i_target, TT::DLL_SLAVE_LOWER_REG, 0x8000) );
@@ -1096,6 +1095,17 @@ fapi2::ReturnCode reset_dll( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_targ
FAPI_TRY( mss::scom_blastah(i_target, TT::DLL_SW_CNTRL_REG, 0x0800) );
FAPI_TRY( mss::scom_blastah(i_target, TT::DLL_VREG_COARSE_REG, 0x0402) );
+ // Can't blast the DLL_CNFG_REG as we need to do magic for the 'last' DP16's DP8
+ // Doing the conditional is far cheaper than a fix-up scom
+ for (const auto& a : TT::DLL_CNFG_REG)
+ {
+ constexpr uint64_t l_dll_reset_data = 0x8100;
+ constexpr uint64_t l_dll_reset_data_no_cal = 0x0100;
+ const uint64_t l_data = (a.second == MCA_DDRPHY_DP16_DLL_CNTL1_P0_4) ? l_dll_reset_data_no_cal : l_dll_reset_data;
+ FAPI_TRY( mss::putScom(i_target, a.first, l_dll_reset_data) );
+ FAPI_TRY( mss::putScom(i_target, a.second, l_data) );
+ }
+
fapi_try_exit:
return fapi2::current_err;
}
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/spd/common/raw_cards.C b/src/import/chips/p9/procedures/hwp/memory/lib/spd/common/raw_cards.C
index 58be65745..e7d32d454 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/spd/common/raw_cards.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/spd/common/raw_cards.C
@@ -68,71 +68,71 @@ enum raw_card_rev : uint8_t
/// @brief raw card B0 settings
///
// TODO RTC:160116 Fill in valid RCD data for LRDIMM
-raw_card_t raw_card_b0( 0x00,
- 0x00,
- 0x00,
- 0x0F,
- 0x03,
- 0x00,
- 0x0E,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x07);
+raw_card_t raw_card_b0( 0x00, // RC00
+ 0x00, // RC01 (C might be the right answer)
+ 0x00, // RC02
+ 0x0F, // RC06_7
+ 0x03, // RC08
+ 0x00, // RC09
+ 0x0E, // RC0B
+ 0x00, // RC0C
+ 0x00, // RC0E
+ 0x00, // RC0F
+ 0x00, // RC1X
+ 0x00, // RC2X
+ 0x00, // RC4X
+ 0x00, // RC5X
+ 0x00, // RC6C
+ 0x00, // RC8X
+ 0x00, // RC9X
+ 0x00, // RCAx
+ 0x07);// RCBX
///
/// @brief raw card C1 settings
///
-raw_card_t raw_card_c1( 0x00,
- 0x0B,
- 0x00,
- 0x0F,
- 0x03,
- 0x0F,
- 0x0E,
- 0x00,
- 0x0D,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x07);
+raw_card_t raw_card_c1( 0x00, // RC00
+ 0x00, // RC01 (C might be the right answer?)
+ 0x00, // RC02
+ 0x0F, // RC06_07
+ 0x03, // RC08
+ 0x00, // RC09
+ 0x0E, // RC0B
+ 0x00, // RC0C
+ 0x0D, // RC0E
+ 0x00, // RC0F
+ 0x00, // RC1X
+ 0x00, // RC2X
+ 0x00, // RC4X
+ 0x00, // RC5X
+ 0x00, // RC6X
+ 0x00, // RC8X
+ 0x00, // RC9X
+ 0x00, // RCAX
+ 0x07);// RCBX
///
/// @brief raw card VBU settings
///
-raw_card_t raw_card_vbu( 0x00,
- 0x00,
- 0x00,
- 0x0F,
- 0x03,
- 0x00,
- 0x0E,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x00,
- 0x07);
+raw_card_t raw_card_vbu( 0x00, // RC00
+ 0x00, // RC01
+ 0x00, // RC02
+ 0x0F, // RC06_07
+ 0x03, // RC08
+ 0x00, // RC09
+ 0x0E, // RC0B
+ 0x00, // RC0C
+ 0x00, // RC0E
+ 0x00, // RC0F
+ 0x00, // RC1X
+ 0x00, // RC2X
+ 0x00, // RC4X
+ 0x00, // RC5X
+ 0x00, // RC6X
+ 0x00, // RC8X
+ 0x00, // RC9X
+ 0x00, // RCAX
+ 0x07);// RCBX
// TODO - RTC:160121 Catch all for adding raw card data for DIMMs
diff --git a/src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit.C b/src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit.C
index da03c8432..a8be31c9b 100644
--- a/src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit.C
+++ b/src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit.C
@@ -60,10 +60,16 @@ extern "C"
mss::ccs::program<TARGET_TYPE_MCBIST> l_program;
+#define CENTAUR_LIKE_PN 1
+#ifdef CENTAUR_LIKE_PN
constexpr uint64_t PCLK_INITIAL_VALUE = 0b10;
constexpr uint64_t NCLK_INITIAL_VALUE = 0b01;
+#else
+ constexpr uint64_t PCLK_INITIAL_VALUE = 0b01;
+ constexpr uint64_t NCLK_INITIAL_VALUE = 0b10;
+#endif
- auto l_mca = i_target.getChildren<TARGET_TYPE_MCA>();
+ const auto l_mca = i_target.getChildren<TARGET_TYPE_MCA>();
FAPI_INF("Start draminit: %s", mss::c_str(i_target));
@@ -95,6 +101,7 @@ extern "C"
mss::ccs::stop_on_err(i_target, l_ccs_config, mss::LOW);
mss::ccs::ue_disable(i_target, l_ccs_config, mss::LOW);
mss::ccs::copy_cke_to_spare_cke(i_target, l_ccs_config, mss::HIGH);
+ mss::ccs::parity_after_cmd(i_target, l_ccs_config, mss::HIGH);
FAPI_TRY( mss::ccs::write_mode(i_target, l_ccs_config) );
}
@@ -110,7 +117,7 @@ extern "C"
// 3. CCS_ADDR_MUX_SEL (FARB5Q(5)) - 1
// 4. CKE out of high impedence
//
- for (auto p : l_mca)
+ for (const auto& p : l_mca)
{
FAPI_TRY( mss::draminit_entry_invariant(p) );
FAPI_TRY( mss::ddr_resetn(p, mss::HIGH) );
@@ -132,7 +139,7 @@ extern "C"
// Per conversation with Shelton and Steve 10/9/15, turn off addr_mux_sel after the CKE CCS but
// before the RCD/MRS CCSs
- for (auto p : l_mca)
+ for (const auto& p : l_mca)
{
FAPI_TRY( change_addr_mux_sel(p, mss::LOW) );
}
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 eacd67862..7b2316f57 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
@@ -76,23 +76,20 @@ extern "C"
// It's unclear if we want to run with this true or false. Right now (10/15) this
// has to be false. Shelton was unclear if this should be on or off in general BRS
- mss::ccs::stop_on_err(i_target, l_ccs_config, false);
- mss::ccs::ue_disable(i_target, l_ccs_config, false);
- mss::ccs::copy_cke_to_spare_cke(i_target, l_ccs_config, true);
+ mss::ccs::stop_on_err(i_target, l_ccs_config, mss::LOW);
+ mss::ccs::ue_disable(i_target, l_ccs_config, mss::LOW);
+ mss::ccs::copy_cke_to_spare_cke(i_target, l_ccs_config, mss::HIGH);
+ mss::ccs::parity_after_cmd(i_target, l_ccs_config, mss::HIGH);
// Hm. Centaur sets this up for the longest duration possible. Can we do better?
mss::ccs::cal_count(i_target, l_ccs_config, ~0, ~0);
-
-#ifndef JIM_SAYS_TURN_OFF_ECC
- mss::ccs::disable_ecc(i_target, l_ccs_config);
-#endif
FAPI_TRY( mss::ccs::write_mode(i_target, l_ccs_config) );
}
// 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());
- for( auto p : i_target.getChildren<TARGET_TYPE_MCA>())
+ for( const auto& p : mss::find_targets<TARGET_TYPE_MCA>(i_target))
{
mss::ccs::program<TARGET_TYPE_MCBIST, TARGET_TYPE_MCA> l_program;
@@ -159,7 +156,7 @@ extern "C"
// For each rank pair we need to calibrate, pop a ccs instruction in an array and execute it.
// NOTE: IF YOU CALIBRATE MORE THAN ONE RANK PAIR PER CCS PROGRAM, MAKE SURE TO CHANGE
// THE PROCESSING OF THE ERRORS. (it's hard to figure out which DIMM failed, too) BRS.
- for (auto rp : l_pairs)
+ for (const auto& rp : l_pairs)
{
auto l_inst = mss::ccs::initial_cal_command<TARGET_TYPE_MCBIST>(rp);
OpenPOWER on IntegriCloud