Skip to content

Commit

Permalink
Fix tREFI calculation to use MRW REFRESH REQUEST RATE as opposed to T…
Browse files Browse the repository at this point in the history
…EMP RANGE

Reverting to P8 attribute used to calculate tREFI. Lab request
expects to use MRW REFRESH REQUEST RATE since it has more enum
options to control refresh range and assure we are in SPEC.

Change-Id: Ibdb6023c60fdf000f642becb53513ecaaf88aa15
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/35003
Reviewed-by: Michael D. Pardeik <pardeik@us.ibm.com>
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Reviewed-by: STEPHEN GLANCY <sglancy@us.ibm.com>
Tested-by: Hostboot CI <hostboot-ci+hostboot@us.ibm.com>
Reviewed-by: Matt K. Light <mklight@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/35435
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 Jun 14, 2017
1 parent 389c4cf commit 772291f
Show file tree
Hide file tree
Showing 7 changed files with 69 additions and 37 deletions.
18 changes: 15 additions & 3 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 @@ -636,7 +636,7 @@ fapi2::ReturnCode eff_dimm::dram_trefi()
case fapi2::ENUM_ATTR_MSS_MRW_FINE_REFRESH_MODE_NORMAL:

FAPI_TRY( calc_trefi( mss::refresh_rate::REF1X,
iv_temp_refresh_range,
iv_refresh_rate_request,
l_trefi_in_ps),
"Failed to calculate tREF1 for target %s", mss::c_str(iv_dimm) );
break;
Expand All @@ -645,7 +645,7 @@ fapi2::ReturnCode eff_dimm::dram_trefi()
case fapi2::ENUM_ATTR_MSS_MRW_FINE_REFRESH_MODE_FLY_2X:

FAPI_TRY( calc_trefi( mss::refresh_rate::REF2X,
iv_temp_refresh_range,
iv_refresh_rate_request,
l_trefi_in_ps),
"Failed to calculate tREF2 for target %s", mss::c_str(iv_dimm) );
break;
Expand All @@ -654,7 +654,7 @@ fapi2::ReturnCode eff_dimm::dram_trefi()
case fapi2::ENUM_ATTR_MSS_MRW_FINE_REFRESH_MODE_FLY_4X:

FAPI_TRY( calc_trefi( mss::refresh_rate::REF4X,
iv_temp_refresh_range,
iv_refresh_rate_request,
l_trefi_in_ps),
"Failed to calculate tREF4 for target %s", mss::c_str(iv_dimm) );
break;
Expand All @@ -674,7 +674,9 @@ fapi2::ReturnCode eff_dimm::dram_trefi()

{
// Calculate refresh cycle time in nCK & set attribute
constexpr double PERCENT_ADJUST = 0.999;
std::vector<uint16_t> l_mcs_attrs_trefi(PORTS_PER_MCS, 0);

uint64_t l_trefi_in_nck = 0;

// Retrieve MCS attribute data
Expand All @@ -687,6 +689,16 @@ fapi2::ReturnCode eff_dimm::dram_trefi()
l_trefi_in_nck),
"Error in calculating tREFI for target %s, with value of l_trefi_in_ps: %d", mss::c_str(iv_dimm), l_trefi_in_ps);

// Per Mike P., requested 99.9% of tREFI calculation to avoid any latency impact and violation of any
// refresh specification (across all number of ranks and frequencies) observed during lab tests.

FAPI_INF("For %s, adjusting tREFI calculation by 99.9%, calculated tREFI (nck): %lu, adjusted tREFI (nck): %lu,",
mss::c_str(iv_dimm), l_trefi_in_nck, l_trefi_in_nck * PERCENT_ADJUST);

// The compiler does this under the covers but just to be explicit on intent:
// Floating point arithmetic and truncation of result saved to an unsigned integer
l_trefi_in_nck = static_cast<double>(l_trefi_in_nck * PERCENT_ADJUST);

FAPI_INF("tCK (ps): %d, tREFI (ps): %d, tREFI (nck): %d",
iv_tCK_in_ps, l_trefi_in_ps, l_trefi_in_nck);

Expand Down
4 changes: 2 additions & 2 deletions src/import/chips/p9/procedures/hwp/memory/lib/dimm/eff_dimm.H
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ class eff_dimm
// using attribute accessors
// Could create getters & setters...
uint8_t iv_refresh_mode;
uint8_t iv_temp_refresh_range;
uint8_t iv_refresh_rate_request;

//Delete the default
eff_dimm () = delete;
Expand All @@ -92,7 +92,7 @@ class eff_dimm

FAPI_TRY( clock_period(iv_dimm, iv_tCK_in_ps), "Failed to calculate clock period (tCK)" );

FAPI_TRY( mss::mrw_temp_refresh_range(iv_temp_refresh_range), "Failed mrw_temp_refresh_range()" );
FAPI_TRY( mss::mrw_refresh_rate_request(iv_refresh_rate_request), "Failed mrw_temp_refresh_rate_request()" );
FAPI_TRY( mss::mrw_fine_refresh_mode(iv_refresh_mode), "Failed mrw_fine_refresh_mode()" );

FAPI_TRY( mss::freq(find_target<fapi2::TARGET_TYPE_MCBIST>(iv_dimm), iv_freq));
Expand Down
55 changes: 31 additions & 24 deletions src/import/chips/p9/procedures/hwp/memory/lib/eff_config/timing.C
Original file line number Diff line number Diff line change
Expand Up @@ -88,49 +88,56 @@ static const std::vector<std::pair<uint8_t, uint64_t> > TRFC_DLR4 =
///
/// @brief Calculates refresh interval time
/// @param[in] i_mode fine refresh rate mode
/// @param[in] i_temp_refresh_range temperature refresh range
/// @param[in] i_refresh_request_rate refresh rate
/// @param[out] o_value timing val in ps
/// @return fapi2::ReturnCode
///
fapi2::ReturnCode calc_trefi( const refresh_rate i_mode,
const uint8_t i_temp_refresh_range,
const uint8_t i_refresh_request_rate,
uint64_t& o_timing )
{
uint64_t l_multiplier = 0;
uint64_t l_quotient = 0;
uint64_t l_remainder = 0;
uint64_t l_refresh_request = 0;
constexpr double TEN_PERCENT_FASTER = 0.90;

switch(i_temp_refresh_range)
switch(i_refresh_request_rate)
{
case fapi2::ENUM_ATTR_MSS_MRW_TEMP_REFRESH_RANGE_NORMAL:
l_multiplier = temp_mode::NORMAL;
case fapi2::ENUM_ATTR_MSS_MRW_REFRESH_RATE_REQUEST_SINGLE:
l_refresh_request = TREFI_BASE;
break;

case fapi2::ENUM_ATTR_MSS_MRW_TEMP_REFRESH_RANGE_EXTEND:
l_multiplier = temp_mode::EXTENDED;
case fapi2::ENUM_ATTR_MSS_MRW_REFRESH_RATE_REQUEST_DOUBLE:
// We are truncating but there is no remainder with TREFI_BASE, so we are okay
l_refresh_request = TREFI_BASE / 2;
break;

case fapi2::ENUM_ATTR_MSS_MRW_REFRESH_RATE_REQUEST_SINGLE_10_PERCENT_FASTER:
// We are truncating but there is no remainder with TREFI_BASE, so we are okay
// 10% faster so 100% - 10% = 90%
l_refresh_request = TREFI_BASE * TEN_PERCENT_FASTER;
break;

case fapi2::ENUM_ATTR_MSS_MRW_REFRESH_RATE_REQUEST_DOUBLE_10_PERCENT_FASTER:
// We are truncating but there is no remainder with TREFI_BASE, so we are okay
// 10% faster so 100% - 10% = 90%
l_refresh_request = (TREFI_BASE / 2) * TEN_PERCENT_FASTER;
break;

default:
// Temperature Refresh Range will be a platform attribute set by the MRW,
// which they "shouldn't" mess up as long as use "attribute" enums.
// if someone messes this up we can at least catch it
FAPI_ASSERT( false,
fapi2::MSS_INVALID_TEMP_REFRESH()
.set_TEMP_REFRESH_RANGE(i_temp_refresh_range),
"Incorrect Temperature Ref. Range received: %d ",
i_temp_refresh_range);
// Will catch incorrect MRW value set
FAPI_ASSERT(false,
fapi2::MSS_INVALID_REFRESH_RATE_REQUEST().set_REFRESH_RATE_REQUEST(i_refresh_request_rate),
"Incorrect refresh request rate received: %d ", i_refresh_request_rate);
break;
}

l_quotient = TREFI_BASE / ( int64_t(i_mode) * l_multiplier );
l_remainder = TREFI_BASE % ( int64_t(i_mode) * l_multiplier );
o_timing = l_quotient + (l_remainder == 0 ? 0 : 1);
o_timing = (l_refresh_request / i_mode);

FAPI_INF( "tREFI: %d, quotient: %d, remainder: %d, tREFI_base: %d",
o_timing, l_quotient, l_remainder, TREFI_BASE );
FAPI_INF( "tREFI (ps): %d, refresh request (ps): %d, tREFI_base (ps): %d, REF%dX",
o_timing, l_refresh_request, TREFI_BASE, i_mode );

// FAPI_ASSERT doesn't set current error to good
// FAPI_ASSERT doesn't set current_err as good
return fapi2::FAPI2_RC_SUCCESS;

fapi_try_exit:
return fapi2::current_err;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,15 +68,15 @@ enum guard_band : uint16_t
// when doing integer math, we add-in the inverse correction factor
// Formula used for derivation:
// Guardband = 1000 * (1000* correction_factor) - 1
INVERSE_DDR3_CORRECTION_FACTOR = 989,
INVERSE_DDR4_CORRECTION_FACTOR = 974,
INVERSE_DDR3_CORRECTION_FACTOR = 989, ///< DDR3 correction factor
INVERSE_DDR4_CORRECTION_FACTOR = 974, ///< DDR4 correction factor
};

enum class refresh_rate : uint8_t
enum refresh_rate : uint8_t
{
REF1X = 1,
REF2X = 2,
REF4X = 4,
REF1X = 1, ///< Refresh rate 1X
REF2X = 2, ///< Refresh rate 2X
REF4X = 4, ///< Refresh rate 4X
};

namespace spd
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19920,7 +19920,7 @@ fapi_try_exit:
/// us (SINGLE_10_PERCENT_FASTER) 3.51 us
/// (DOUBLE_10_PERCENT_FASTER)
///
inline fapi2::ReturnCode mrw_refresh_rate_select(uint8_t& o_value)
inline fapi2::ReturnCode mrw_refresh_rate_request(uint8_t& o_value)
{

FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_MSS_MRW_REFRESH_RATE_REQUEST, fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@
</enum>
<default>0x0</default>
<initToZero/>
<mssAccessorName>mrw_refresh_rate_select</mssAccessorName>
<mssAccessorName>mrw_refresh_rate_request</mssAccessorName>
</attribute>

<attribute>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,19 @@
</callout>
</hwpError>

<hwpError>
<rc>RC_MSS_INVALID_REFRESH_RATE_REQUEST</rc>
<description>
Invalid refresh request rate received.
Possibly due to bad MRW setting for ATTR_MSS_MRW_REFRESH_RATE_REQUEST.
</description>
<ffdc>REFRESH_RATE_REQUEST</ffdc>
<callout>
<procedure>CODE</procedure>
<priority>HIGH</priority>
</callout>
</hwpError>

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

0 comments on commit 772291f

Please sign in to comment.