summaryrefslogtreecommitdiffstats
path: root/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/timing.H
diff options
context:
space:
mode:
Diffstat (limited to 'src/import/chips/p9/procedures/hwp/memory/lib/eff_config/timing.H')
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/eff_config/timing.H44
1 files changed, 33 insertions, 11 deletions
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/timing.H b/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/timing.H
index 88024e7a0..3939e7dc8 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/timing.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/eff_config/timing.H
@@ -270,28 +270,50 @@ constexpr uint64_t twlmrd()
}
///
-/// @brief Calculate TWLO_TWLOE
+/// @brief Mode Register Set command update delay
/// @tparam T fapi2::TargetType of the target used to calculate cycles from ns
-/// @param[in] i_target the target used to get DIMM clocks
-/// @return uint64_t, TWLO_TWLOE in cycles
+/// @param[in] i_target the target used to get clocks
+/// @return max(24nCK,15ns) in clocks
///
template< fapi2::TargetType T >
-inline uint64_t twlo_twloe(const fapi2::Target<T>& i_target)
+inline uint64_t tmod( const fapi2::Target<T>& i_target )
{
- return 12 + mss::ns_to_cycles(i_target, tWLO - tWLOE);
+ // Per DDR4 Full spec update (79-4A) - timing requirements
+ return mss::max_ck_ns( i_target, 24, 15 );
}
///
-/// @brief Mode Register Set command update delay
+/// @brief Calculate TWLO_TWLOE
/// @tparam T fapi2::TargetType of the target used to calculate cycles from ns
-/// @param[in] i_target the target used to get clocks
-/// @return max(24nCK,15ns) in clocks
+/// @param[in] i_target the target used to get DIMM clocks
+/// @return uint64_t, TWLO_TWLOE in cycles
///
template< fapi2::TargetType T >
-inline uint64_t tmod( const fapi2::Target<T>& i_target )
+inline uint64_t twlo_twloe(const fapi2::Target<T>& i_target)
{
- // Per DDR4 Full spec update (79-4A) - timing requirements
- return mss::max_ck_ns( i_target, 24, 15 );
+ // From mthe PHY databook:
+ // 12 + std::max((twldqsen - tmod), (twlo - twlow))
+ // + longest DQS delay in clocks (rounded up) + longest DQ delay in clocks (rounded up)
+ // Magic numbers taken from talking with Anuwat (twloe) and reviewing the Centaur code (ldq/ldqs)
+ constexpr uint64_t l_dq_ck = 1;
+ constexpr uint64_t l_dqs_ck = 1;
+ uint8_t l_wlo_ck = 0;
+ uint64_t l_wloe_ck = mss::ns_to_cycles(i_target, 2);
+ uint64_t l_twlo_twloe = 0;
+
+ FAPI_TRY( mss::vpd_mr_dphy_wlo(i_target, l_wlo_ck) );
+
+ // TODO RTC:160356 This changes if wlo is signed, which it's not but I wonder if it should
+ // be ... (the PHY register is.) It changes because we need to round up to 0 if needed.
+ l_twlo_twloe = 12 + std::max( (twldqsen() + tmod(i_target)), (l_wlo_ck + l_wloe_ck) ) + l_dq_ck + l_dqs_ck;
+ FAPI_INF("twlo_twloe %d for %s", l_twlo_twloe, mss::c_str(i_target));
+ return l_twlo_twloe;
+
+fapi_try_exit:
+ // We're in deep horseradish if we can't get wlo
+ FAPI_ERR("failed to calculate twlo_twloe for %s", mss::c_str(i_target));
+ fapi2::Assert(false);
+ return 0;
}
///
OpenPOWER on IntegriCloud