Skip to content

Commit

Permalink
Adds DCD workarounds for bad hardware
Browse files Browse the repository at this point in the history
1) Sticky bit workaround
2) Always start at the midpoint of the DCD range

Change-Id: If6750db88556270f7786b39ab25ac952840d1f23
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/41712
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Tested-by: Hostboot CI <hostboot-ci+hostboot@us.ibm.com>
Dev-Ready: STEPHEN GLANCY <sglancy@us.ibm.com>
Reviewed-by: ANDRE A. MARIN <aamarin@us.ibm.com>
Reviewed-by: Louis Stermole <stermole@us.ibm.com>
Reviewed-by: Jennifer A. Stofer <stofer@us.ibm.com>
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/41714
Reviewed-by: Hostboot Team <hostboot@us.ibm.com>
Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com>
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
  • Loading branch information
sglancy6 authored and dcrowell77 committed Jun 15, 2017
1 parent 679d766 commit 74179c7
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 6 deletions.
41 changes: 37 additions & 4 deletions src/import/chips/p9/procedures/hwp/memory/lib/phy/dcd.C
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
#include <generic/memory/lib/utils/pos.H>
#include <lib/utils/poll.H>
#include <lib/utils/conversions.H>
#include <lib/workarounds/adr32s_workarounds.H>

using fapi2::TARGET_TYPE_MCA;
using fapi2::TARGET_TYPE_MCBIST;
Expand Down Expand Up @@ -104,6 +105,9 @@ fapi2::ReturnCode setup_dll_control_regs( const fapi2::Target<fapi2::TARGET_TYPE
l_data.clearBit<TT::DLL_CAL_GOOD>();

FAPI_TRY(mss::putScom(i_target, r, l_data));

FAPI_TRY(mss::workarounds::adr32s::setup_dll_control_regs( i_target, r ), "%s failed to setup DLL control reg 0x%016lx",
mss::c_str(i_target), r);
}

return fapi2::FAPI2_RC_SUCCESS;
Expand Down Expand Up @@ -159,7 +163,11 @@ fapi2::ReturnCode sw_cal_side_helper( const fapi2::Target<TARGET_TYPE_MCA>& i_ta
{
typedef dutyCycleDistortionTraits<TARGET_TYPE_MCA> TT;

constexpr uint64_t l_dcd_adjust_overflow = 0b1111111;
constexpr uint64_t DD1_OVERFLOW = 0b1111111;
constexpr uint64_t DD2_OVERFLOW = 0b11111111;

// Having an extra bit in DD2 means that the overflow value changes
const uint64_t l_dcd_adjust_overflow = mss::chip_ec_nimbus_lt_2_0(i_target) ? DD1_OVERFLOW : DD2_OVERFLOW;
constexpr uint64_t l_dcd_adjust_underflow = 0b0000000;

constexpr uint64_t l_delay = mss::DELAY_100NS;
Expand Down Expand Up @@ -293,9 +301,17 @@ fapi2::ReturnCode sw_cal_per_register( const fapi2::Target<TARGET_TYPE_MCA>& i_t
uint64_t l_b_side_value = 0;
fapi2::buffer<uint64_t> l_buff;

// Fixes the default seed values
const uint64_t l_default_seed = mss::chip_ec_nimbus_lt_2_0(i_target) ? TT::DD1_DCD_ADJUST_DEFAULT :
TT::DD2_DCD_ADJUST_DEFAULT;

// Note: per the design and lab teams, we should always start out at our nominal value
// This is a bit of a workaround given some broken HW in the lab, not sure if it should go in the workaround file
io_seed = l_default_seed;

auto l_a_rc = sw_cal_side_helper(i_target, i_reg, io_seed, A_SIDE, l_a_side_value);

// Updates the seed value to avoid underflow issues
// Updates the seed value to avoid bad hardware issues
io_seed = (l_a_side_value == 0) ? (io_seed) : (l_a_side_value - 1);

// We want to seed the other side (and each subsequent port) with the
Expand Down Expand Up @@ -407,6 +423,14 @@ void log_reg_results( const fapi2::Target<TARGET_TYPE_MCA>& i_target,
if(l_failed)
{
io_failing_regs.push_back(i_reg);

// Set current error, and log it
FAPI_ASSERT(false,
fapi2::MSS_HARDWARE_DUTY_CLOCK_DISTORTION_CAL_FAILED()
.set_TARGET(i_target)
.set_REGISTER(i_reg),
"DCD hardware calibration failed on %s. register 0x%016lx. Attempting software recovery",
mss::c_str(i_target), i_reg);
}
// Updates sum if we passed
else
Expand All @@ -415,6 +439,15 @@ void log_reg_results( const fapi2::Target<TARGET_TYPE_MCA>& i_target,
get_dcd_value(i_target, i_data, l_result);
io_sum += l_result;
}

// Exits out before error handling
return;

// Handles the error
fapi_try_exit:
// Logs the error
fapi2::logError(fapi2::current_err, fapi2::FAPI2_ERRL_SEV_RECOVERED);
fapi2::current_err = FAPI2_RC_SUCCESS;
}

///
Expand Down Expand Up @@ -530,8 +563,8 @@ fapi2::ReturnCode execute_hw_calibration( const fapi2::Target<TARGET_TYPE_MCA>&
{
// Copies the seed so we can preserve the average
uint64_t l_seed = l_good_average;
FAPI_INF("%s executing software calibration on failing register 0x%016lx with seed of %lu", mss::c_str(i_target), l_reg,
l_seed);
FAPI_INF("%s executing software calibration on failing register 0x%016lx with seed of %lu",
mss::c_str(i_target), l_reg, l_seed);
FAPI_TRY(sw_cal_per_register(i_target, l_reg, l_seed),
"%s failed to execute the software DCD calibration on register 0x%016lx", mss::c_str(i_target), l_reg);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@ namespace adr32s
/// @param[in] i_target MCBIST target on which to operate
/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
/// @note Always needs to be run for DD1.* parts. unsure for DD2
/// TODO:RTC169173 update DCD calibration for DD2
///
fapi2::ReturnCode clear_dcd_firs( const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_target )
{
Expand Down Expand Up @@ -143,6 +142,59 @@ fapi_try_exit:
return fapi2::current_err;
}

///
/// @brief Retries to clear the cal update bit, as it has been seen that the bit can be "sticky" in hardware
/// @param[in] i_target MCA target on which to operate
/// @param[in] i_reg the register on which to operate
/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
///
fapi2::ReturnCode setup_dll_control_regs( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target, const uint64_t i_reg )
{
// Traits definition
typedef dutyCycleDistortionTraits<TARGET_TYPE_MCA> TT;

// Poll limit declaration - this is an engineering judgement value from the lab's experimentation
// The bit thus far has always unstuck after 3 loops, so 10 is more than safe
constexpr uint64_t POLL_LIMIT = 10;
bool l_done = false;
fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;

for(uint64_t i = 0; i < POLL_LIMIT; ++i)
{
fapi2::buffer<uint64_t> l_data;

FAPI_TRY(mss::getScom(i_target, i_reg, l_data), "%s failed to getScom from register 0x%016lx", mss::c_str(i_target),
i_reg);

// If our bit is a 0, then we're done
l_done = !l_data.getBit<TT::DLL_CAL_UPDATE>();

// Break out
if(l_done)
{
FAPI_INF("%s DLL control register 0x%016lx is setup correctly after %lu attempts", mss::c_str(i_target), i_reg, i);
break;
}

// Stops cal from updating and disables cal good to keep parity good (these regs have parity issues on bits 60-63)
l_data.clearBit<TT::DLL_CAL_UPDATE>();
l_data.clearBit<TT::DLL_CAL_GOOD>();

FAPI_TRY(mss::putScom(i_target, i_reg, l_data), "%s failed to putScom from register 0x%016lx", mss::c_str(i_target),
i_reg);
}

// do the error check
FAPI_ASSERT( l_done,
fapi2::MSS_DLL_UPDATE_BIT_STUCK()
.set_TARGET(i_target)
.set_REGISTER(i_reg),
"Failed to setup DLL control reg for %s 0x%016lx", mss::c_str(i_target), i_reg );

fapi_try_exit:
return fapi2::current_err;
}

} // close namespace adr32s
} // close namespace workarounds
} // close namespace mss
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ namespace adr32s
/// @param[in] i_target MCBIST target on which to operate
/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
/// @note Always needs to be run for DD1.* parts. unsure for DD2
/// TODO:RTC169173 update DCD calibration for DD2
///
fapi2::ReturnCode clear_dcd_firs( const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_target );

Expand All @@ -68,6 +67,14 @@ fapi2::ReturnCode clear_dcd_firs( const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>
///
fapi2::ReturnCode duty_cycle_distortion_calibration( const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_target );

///
/// @brief Retries to clear the cal update bit, as it has been seen that the bit can be "sticky" in hardware
/// @param[in] i_target MCA target on which to operate
/// @param[in] i_reg the register on which to operate
/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
///
fapi2::ReturnCode setup_dll_control_regs( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target, const uint64_t i_reg );

} // close namespace adr32s
} // close namespace workarounds
} // close namespace mss
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -469,6 +469,18 @@
</deconfigure>
</hwpError>

<hwpError>
<rc>RC_MSS_DLL_UPDATE_BIT_STUCK</rc>
<description>
The DLL update bit failed to be cleared after a number of loops
</description>
<ffdc>REGISTER</ffdc>
<callout>
<target>TARGET</target>
<priority>HIGH</priority>
</callout>
</hwpError>

<hwpError>
<rc>RC_MSS_DUTY_CLOCK_DISTORTION_CAL_FAILED</rc>
<description>
Expand Down Expand Up @@ -502,6 +514,18 @@
</gard>
</hwpError>

<hwpError>
<rc>RC_MSS_HARDWARE_DUTY_CLOCK_DISTORTION_CAL_FAILED</rc>
<description>
The hardware duty clock distortion calibration algorithm failed
</description>
<ffdc>REGISTER</ffdc>
<callout>
<target>TARGET</target>
<priority>HIGH</priority>
</callout>
</hwpError>

<hwpError>
<rc>RC_MSS_DDR_PHY_RESET_PORT_FIR</rc>
<description>
Expand Down

0 comments on commit 74179c7

Please sign in to comment.