diff options
author | Brian Silver <bsilver@us.ibm.com> | 2016-02-24 10:11:33 -0600 |
---|---|---|
committer | Daniel M. Crowell <dcrowell@us.ibm.com> | 2016-04-01 21:24:31 -0400 |
commit | d8d0a0bbe2f55c8b080d45c36dbd6f377efae4ba (patch) | |
tree | 5baf63425ed24a1fe421d2e18c4d2498ec3fb19c /src/import | |
parent | 63c0bd93248e3f5e4f71f8beb421bc1dda22d660 (diff) | |
download | talos-hostboot-d8d0a0bbe2f55c8b080d45c36dbd6f377efae4ba.tar.gz talos-hostboot-d8d0a0bbe2f55c8b080d45c36dbd6f377efae4ba.zip |
Change WC to follow the new register block pattern
Change-Id: I9f1d24893a0a1e1b8a35880c5d2f9df639b8301f
Original-Change-Id: I20f22cb5ea50c7f8e0d53bb39ef452f892187d2a
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/20851
Tested-by: Jenkins Server
Tested-by: Auto Mirror
Tested-by: Hostboot CI
Reviewed-by: ANDRE A. MARIN <aamarin@us.ibm.com>
Reviewed-by: CRAIG C. HAMILTON <cchamilt@us.ibm.com>
Reviewed-by: Jennifer A. Stofer <stofer@us.ibm.com>
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/22772
Tested-by: FSP CI Jenkins
Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/import')
4 files changed, 445 insertions, 190 deletions
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/mss.H b/src/import/chips/p9/procedures/hwp/memory/lib/mss.H index 41bd9b34a..5d2b6038b 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/mss.H +++ b/src/import/chips/p9/procedures/hwp/memory/lib/mss.H @@ -64,6 +64,8 @@ #include "phy/ddr_phy.H" #include "phy/dp16.H" #include "phy/cal_timers.H" +#include "phy/write_cntrl.H" +#include "phy/read_cntrl.H" #include "utils/dump_regs.H" 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 36e8f13c7..c035c4e5c 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 @@ -884,6 +884,9 @@ fapi2::ReturnCode phy_scominit(const fapi2::Target<TARGET_TYPE_MCBIST>& i_target FAPI_TRY( mss::dp16::write_clock_enable(p, l_pairs) ); FAPI_TRY( mss::dp16::read_clock_enable(p, l_pairs) ); + // Write Control reset + FAPI_TRY( mss::wc::reset(p) ); + // Read Control reset FAPI_TRY( mss::rc::reset(p) ); } diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/phy/ddr_phy.H b/src/import/chips/p9/procedures/hwp/memory/lib/phy/ddr_phy.H index b874bea50..a53e74f70 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/phy/ddr_phy.H +++ b/src/import/chips/p9/procedures/hwp/memory/lib/phy/ddr_phy.H @@ -168,196 +168,6 @@ fapi2::ReturnCode setup_cal_config( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& const uint64_t i_rank, const fapi2::buffer<uint16_t> i_cal_steps_enabled); -/// -/// @brief Setup wc_config0 -/// @tparam T the target type of the MCA/MBA -/// @param[in] i_target the target associated with this cal setup -/// @return FAPI2_RC_SUCCESS iff setup was successful -/// -template< fapi2::TargetType T > -inline fapi2::ReturnCode reset_wc_config0( const fapi2::Target<T>& i_target ); - -/// -/// @brief Setup wc_config0 -/// @param[in] i_target the MCA target associated with this cal setup -/// @return FAPI2_RC_SUCCESS iff setup was successful -/// -template<> -inline fapi2::ReturnCode reset_wc_config0( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target ) -{ - fapi2::buffer<uint64_t> l_data; - uint8_t l_is_sim = 0; - FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_IS_SIMULATION, fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>(), l_is_sim) ); - - // This is a simplification - in sim we don't have DQS wire delays so we don't acccount for them BRS - l_data.insertFromRight<MCA_DDRPHY_WC_CONFIG0_P0_TWLO_TWLOE, - MCA_DDRPHY_WC_CONFIG0_P0_TWLO_TWLOE_LEN>(mss::twlo_twloe(i_target)); - - // WL_ONE_DQS_PULSE = enable (one pulse) - l_data.setBit<MCA_DDRPHY_WC_CONFIG0_P0_WL_ONE_DQS_PULSE>(); - - // FW_WR_RD [same formula as RD_WR? max(tWTR+11,AL+tRTP+3), ATTR_EFF_DRAM_AL(0,1,2)] - // 57:62, 0b000000, (def_is_sim); # is this max? - // 57:62, 0b100000, any; # dd0 = 17 clocks, now 32 from SWyatt - { - const uint64_t FW_WR_RD = l_is_sim ? 0b000000 : 0b100000; - l_data.insertFromRight<MCA_DDRPHY_WC_CONFIG0_P0_FW_WR_RD, - MCA_DDRPHY_WC_CONFIG0_P0_FW_WR_RD_LEN>(FW_WR_RD); - } - - // 63, 0b0, any; # CUSTOM_INIT_WRITE - l_data.clearBit<MCA_DDRPHY_WC_CONFIG0_P0_CUSTOM_INIT_WRITE>(); - - FAPI_DBG("wc_config0 0x%llx (tWLO_tWLOE: %d)", l_data, mss::twlo_twloe(i_target)); - FAPI_TRY( mss::putScom(i_target, MCA_DDRPHY_WC_CONFIG0_P0, l_data) ); - -fapi_try_exit: - return fapi2::current_err; -} - - - - - -/// -/// @brief Setup wc_config1 -/// @tparam T the target type of the MCA/MBA -/// @param[in] i_target the target associated with this cal setup -/// @return FAPI2_RC_SUCCESS iff setup was successful -/// -template< fapi2::TargetType T > -inline fapi2::ReturnCode reset_wc_config1( const fapi2::Target<T>& i_target ); - -/// -/// @brief Setup wc_config1 -/// @param[in] i_target the MCA target associated with this cal setup -/// @return FAPI2_RC_SUCCESS iff setup was successful -/// -template<> -inline fapi2::ReturnCode reset_wc_config1( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target ) -{ - // Reset WC_CONFIG1 with the values directly from the PHY databook - fapi2::buffer<uint64_t> l_data; - - l_data.insertFromRight<MCA_DDRPHY_WC_CONFIG1_P0_BIG_STEP, MCA_DDRPHY_WC_CONFIG1_P0_BIG_STEP_LEN>(WR_LVL_BIG_STEP); - l_data.insertFromRight<MCA_DDRPHY_WC_CONFIG1_P0_SMALL_STEP, MCA_DDRPHY_WC_CONFIG1_P0_SMALL_STEP_LEN>(WR_LVL_SMALL_STEP); - l_data.insertFromRight<MCA_DDRPHY_WC_CONFIG1_P0_WR_PRE_DLY, - MCA_DDRPHY_WC_CONFIG1_P0_WR_PRE_DLY_LEN>(WR_LVL_PRE_DLY); - FAPI_TRY( mss::putScom(i_target, MCA_DDRPHY_WC_CONFIG1_P0, l_data) ); - -fapi_try_exit: - return fapi2::current_err; -} - - - -/// -/// @brief Setup wc_config2 -/// @tparam T the target type of the MCA/MBA -/// @param[in] i_target the target associated with this cal setup -/// @return FAPI2_RC_SUCCESS iff setup was successful -/// -template< fapi2::TargetType T > -inline fapi2::ReturnCode reset_wc_config2( const fapi2::Target<T>& i_target ); - -/// -/// @brief Setup wc_config2 -/// @param[in] i_target the MCA target associated with this cal setup -/// @return FAPI2_RC_SUCCESS iff setup was successful -/// -template<> -inline fapi2::ReturnCode reset_wc_config2( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target ) -{ - fapi2::buffer<uint64_t> l_data; - - l_data.insertFromRight<MCA_DDRPHY_WC_CONFIG2_P0_NUM_VALID_SAMPLES, - MCA_DDRPHY_WC_CONFIG2_P0_NUM_VALID_SAMPLES_LEN>(WR_LVL_NUM_VALID_SAMPLES); - - l_data.insertFromRight<MCA_DDRPHY_WC_CONFIG2_P0_FW_RD_WR, MCA_DDRPHY_WC_CONFIG2_P0_FW_RD_WR_LEN>(WR_CNTR_FW_RD_WR); - - FAPI_TRY( mss::putScom(i_target, MCA_DDRPHY_WC_CONFIG2_P0, l_data) ); - -fapi_try_exit: - return fapi2::current_err; -} - - - - -/// -/// @brief Setup wc_config3 -/// @tparam T the target type of the MCA/MBA -/// @param[in] i_target the target associated with this cal setup -/// @return FAPI2_RC_SUCCESS iff setup was successful -/// -template< fapi2::TargetType T > -inline fapi2::ReturnCode reset_wc_config3( const fapi2::Target<T>& i_target ); - -/// -/// @brief Setup wc_config3 -/// @param[in] i_target the MCA target associated with this cal setup -/// @return FAPI2_RC_SUCCESS iff setup was successful -/// -template<> -inline fapi2::ReturnCode reset_wc_config3( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target ) -{ - fapi2::buffer<uint64_t> l_data; - uint8_t l_is_sim = 0; - FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_IS_SIMULATION, fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>(), l_is_sim) ); - - // MCA_DDRPHY_WC_CONFIG3_P0_MRS_CMD_DQ_ON is 0's - - // 55:60, 0b000000, (def_is_sim); # MRS_CMD_DQ_OFF !! - // 55:60, 0b111111, any ; # MRS_CMD_DQ_OFF !! - { - const uint64_t CMD_DQ_OFF = l_is_sim ? 0b000000 : 0b111111; - l_data.insertFromRight<MCA_DDRPHY_WC_CONFIG3_P0_MRS_CMD_DQ_OFF, - MCA_DDRPHY_WC_CONFIG3_P0_MRS_CMD_DQ_OFF_LEN>(CMD_DQ_OFF); - } - - FAPI_TRY( mss::putScom(i_target, MCA_DDRPHY_WC_CONFIG3_P0, l_data) ); - -fapi_try_exit: - return fapi2::current_err; -} - - -/// -/// @brief Setup WC RTT Write Swap Enable Register -/// @tparam T the target type of the MCA/MBA -/// @param[in] i_target the target -/// @return FAPI2_RC_SUCCESS iff setup was successful -/// -template< fapi2::TargetType T > -inline fapi2::ReturnCode reset_wc_rtt_wr_swap_enable( const fapi2::Target<T>& i_target ); - -/// -/// @brief Setup WC RTT Write Swap Enable Register -/// @param[in] i_target the MCA target -/// @return FAPI2_RC_SUCCESS iff setup was successful -/// -template<> -inline fapi2::ReturnCode reset_wc_rtt_wr_swap_enable( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target ) -{ - fapi2::buffer<uint64_t> l_data; - - FAPI_TRY( mss::getScom(i_target, MCA_DDRPHY_WC_RTT_WR_SWAP_ENABLE_P0, l_data) ); - - // Per John Bialas 1/16: The enable RTT_SWAP bit is causing problems in sim. - l_data.clearBit<MCA_DDRPHY_WC_RTT_WL_SWAP_ENABLE_P0>(); - l_data.setBit<MCA_DDRPHY_WC_RTT_WR_CTL_SWAP_ENABLE_P0>(); - - FAPI_DBG("wc_swap_enable 0x%llx", l_data); - FAPI_TRY( mss::putScom(i_target, MCA_DDRPHY_WC_RTT_WR_SWAP_ENABLE_P0, l_data) ); - -fapi_try_exit: - return fapi2::current_err; -} - - - - - /// /// @brief Setup seq_config0 diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/phy/write_cntrl.H b/src/import/chips/p9/procedures/hwp/memory/lib/phy/write_cntrl.H new file mode 100644 index 000000000..e56dd36ca --- /dev/null +++ b/src/import/chips/p9/procedures/hwp/memory/lib/phy/write_cntrl.H @@ -0,0 +1,440 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: chips/p9/procedures/hwp/memory/lib/phy/write_cntrl.H $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* EKB Project */ +/* */ +/* COPYRIGHT 2016 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* IBM_PROLOG_END_TAG */ + +/// +/// @file write_cntrl.H +/// @brief Subroutines for the PHY write control registers +/// +// *HWP HWP Owner: Brian Silver <bsilver@us.ibm.com> +// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com> +// *HWP Team: Memory +// *HWP Level: 2 +// *HWP Consumed by: FSP:HB + +#ifndef _MSS_WRITE_CNTRL_H_ +#define _MSS_WRITE_CNTRL_H_ + +#include <fapi2.H> +#include "p9_mc_scom_addresses.H" + +namespace mss +{ + +// I have a dream that the PHY code can be shared among controllers. So, I drive the +// engine from a set of traits. This might be folly. Allow me to dream. BRS + +/// +/// @class wcTraits +/// @brief a collection of traits associated with the PHY write control +/// @tparam T fapi2::TargetType representing the PHY +/// +template< fapi2::TargetType T > +class wcTraits; + +/// +/// @class wcTraits<fapi2::TARGET_TYPE_MBA> +/// @brief a collection of traits associated with the Centaur PHY +/// +template<> +class wcTraits<fapi2::TARGET_TYPE_MBA> +{ +}; + +/// +/// @class wcTraits<fapi2::TARGET_TYPE_MCA> +/// @brief a collection of traits associated with the Nimbus PHY write control +/// +template<> +class wcTraits<fapi2::TARGET_TYPE_MCA> +{ + public: + // MCA write control registers + constexpr static uint64_t WC_CONFIG0_REG = MCA_DDRPHY_WC_CONFIG0_P0; + constexpr static uint64_t WC_CONFIG1_REG = MCA_DDRPHY_WC_CONFIG1_P0; + constexpr static uint64_t WC_CONFIG2_REG = MCA_DDRPHY_WC_CONFIG2_P0; + constexpr static uint64_t WC_CONFIG3_REG = MCA_DDRPHY_WC_CONFIG3_P0; + constexpr static uint64_t WC_RTT_WR_SWAP_ENABLE_REG = MCA_DDRPHY_WC_RTT_WR_SWAP_ENABLE_P0; + + constexpr static uint64_t WC_ERROR_MASK0_REG = MCA_DDRPHY_WC_ERROR_MASK0_P0; + constexpr static uint64_t WC_ERROR_STATUS0_REG = MCA_DDRPHY_WC_ERROR_STATUS0_P0; + + + // All the fields + enum + { + TWLO_TWLOE = MCA_DDRPHY_WC_CONFIG0_P0_TWLO_TWLOE, + TWLO_TWLOE_LEN = MCA_DDRPHY_WC_CONFIG0_P0_TWLO_TWLOE_LEN, + WL_ONE_DQS_PULSE = MCA_DDRPHY_WC_CONFIG0_P0_WL_ONE_DQS_PULSE, + FW_WR_RD = MCA_DDRPHY_WC_CONFIG0_P0_FW_WR_RD, + FW_WR_RD_LEN = MCA_DDRPHY_WC_CONFIG0_P0_FW_WR_RD_LEN, + CUSTOM_INIT_WRITE = MCA_DDRPHY_WC_CONFIG0_P0_CUSTOM_INIT_WRITE, + + BIG_STEP = MCA_DDRPHY_WC_CONFIG1_P0_BIG_STEP, + BIG_STEP_LEN = MCA_DDRPHY_WC_CONFIG1_P0_BIG_STEP_LEN, + SMALL_STEP = MCA_DDRPHY_WC_CONFIG1_P0_SMALL_STEP, + SMALL_STEP_LEN = MCA_DDRPHY_WC_CONFIG1_P0_SMALL_STEP_LEN, + WR_PRE_DLY = MCA_DDRPHY_WC_CONFIG1_P0_WR_PRE_DLY, + WR_PRE_DLY_LEN = MCA_DDRPHY_WC_CONFIG1_P0_WR_PRE_DLY_LEN, + + NUM_VALID_SAMPLES = MCA_DDRPHY_WC_CONFIG2_P0_NUM_VALID_SAMPLES, + NUM_VALID_SAMPLES_LEN = MCA_DDRPHY_WC_CONFIG2_P0_NUM_VALID_SAMPLES_LEN, + FW_RD_WR = MCA_DDRPHY_WC_CONFIG2_P0_FW_RD_WR, + FW_RD_WR_LEN = MCA_DDRPHY_WC_CONFIG2_P0_FW_RD_WR_LEN, + IPW_WR_WR = MCA_DDRPHY_WC_CONFIG2_P0_IPW_WR_WR, + IPW_WR_WR_LEN = MCA_DDRPHY_WC_CONFIG2_P0_IPW_WR_WR_LEN, + EN_RESET_DD2_FIX_DIS = MCA_DDRPHY_WC_CONFIG2_P0_EN_RESET_DD2_FIX_DIS, + EN_RESET_WR_DELAY_WL = MCA_DDRPHY_WC_CONFIG2_P0_EN_RESET_WR_DELAY_WL, + + MRS_CMD_DQ_ON = MCA_DDRPHY_WC_CONFIG3_P0_MRS_CMD_DQ_ON, + MRS_CMD_DQ_ON_LEN = MCA_DDRPHY_WC_CONFIG3_P0_MRS_CMD_DQ_ON_LEN, + MRS_CMD_DQ_OFF = MCA_DDRPHY_WC_CONFIG3_P0_MRS_CMD_DQ_OFF, + MRS_CMD_DQ_OFF_LEN = MCA_DDRPHY_WC_CONFIG3_P0_MRS_CMD_DQ_OFF_LEN, + + ERR_WR_CNTL_MASK = MCA_DDRPHY_WC_ERROR_MASK0_P0_WR_CNTL_MASK, + ERR_WR_CNTL = MCA_DDRPHY_WC_ERROR_STATUS0_P0_WR_CNTL, + + RTT_WR_SWAP_ENABLE_P0_WL = MCA_DDRPHY_WC_RTT_WR_SWAP_ENABLE_P0_WL, + RTT_WR_SWAP_ENABLE_P0_CTR = MCA_DDRPHY_WC_RTT_WR_SWAP_ENABLE_P0_CTR, + }; + +}; + +/// +/// @class mss::wc +/// @brief Write Control Class, encapsulates the WC registers +/// @tparam T fapi2 Target Type +/// @tparam TT traits type defaults to wcTraits<T> +/// +template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCA, typename TT = wcTraits<T> > +class wc_class +{ + public: + + /// + /// @brief Read WC_CONFIG0 + /// @param[in] i_target the fapi2 target of the port + /// @param[out] o_data the value of the register + /// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok + /// + static inline fapi2::ReturnCode read_config0( const fapi2::Target<T>& i_target, + fapi2::buffer<uint64_t>& o_data ) + { + FAPI_TRY( mss::getScom(i_target, TT::WC_CONFIG0_REG, o_data) ); + FAPI_DBG("wc_config0: 0x%016llx", o_data); + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Write WC_CONFIG0 + /// @param[in] i_target the fapi2 target of the port + /// @param[in] i_data the value of the register + /// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok + /// + static inline fapi2::ReturnCode write_config0( const fapi2::Target<T>& i_target, + const fapi2::buffer<uint64_t>& i_data ) + { + FAPI_DBG("wc_config0: 0x%016llx", i_data); + FAPI_TRY( mss::putScom(i_target, TT::WC_CONFIG0_REG, i_data) ); + fapi_try_exit: + return fapi2::current_err; + } + + + /// + /// @brief Read WC_CONFIG1 + /// @param[in] i_target the fapi2 target of the port + /// @param[out] o_data the value of the register + /// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok + /// + static inline fapi2::ReturnCode read_config1( const fapi2::Target<T>& i_target, + fapi2::buffer<uint64_t>& o_data ) + { + FAPI_TRY( mss::getScom(i_target, TT::WC_CONFIG1_REG, o_data) ); + FAPI_DBG("wc_config1: 0x%016llx", o_data); + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Write WC_CONFIG1 + /// @param[in] i_target the fapi2 target of the port + /// @param[in] i_data the value of the register + /// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok + /// + static inline fapi2::ReturnCode write_config1( const fapi2::Target<T>& i_target, + const fapi2::buffer<uint64_t>& i_data ) + { + FAPI_DBG("wc_config1: 0x%016llx", i_data); + FAPI_TRY( mss::putScom(i_target, TT::WC_CONFIG1_REG, i_data) ); + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Read WC_CONFIG2 + /// @param[in] i_target the fapi2 target of the port + /// @param[out] o_data the value of the register + /// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok + /// + static inline fapi2::ReturnCode read_config2( const fapi2::Target<T>& i_target, + fapi2::buffer<uint64_t>& o_data ) + { + FAPI_TRY( mss::getScom(i_target, TT::WC_CONFIG2_REG, o_data) ); + FAPI_DBG("wc_config2: 0x%016llx", o_data); + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Write WC_CONFIG2 + /// @param[in] i_target the fapi2 target of the port + /// @param[in] i_data the value of the register + /// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok + /// + static inline fapi2::ReturnCode write_config2( const fapi2::Target<T>& i_target, + const fapi2::buffer<uint64_t>& i_data ) + { + FAPI_DBG("wc_config2: 0x%016llx", i_data); + FAPI_TRY( mss::putScom(i_target, TT::WC_CONFIG2_REG, i_data) ); + fapi_try_exit: + return fapi2::current_err; + } + + + /// + /// @brief Read WC_CONFIG3 + /// @param[in] i_target the fapi2 target of the port + /// @param[out] o_data the value of the register + /// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok + /// + static inline fapi2::ReturnCode read_config3( const fapi2::Target<T>& i_target, + fapi2::buffer<uint64_t>& o_data ) + { + FAPI_TRY( mss::getScom(i_target, TT::WC_CONFIG3_REG, o_data) ); + FAPI_DBG("wc_config3: 0x%016llx", o_data); + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Write WC_CONFIG3 + /// @param[in] i_target the fapi2 target of the port + /// @param[in] i_data the value of the register + /// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok + /// + static inline fapi2::ReturnCode write_config3( const fapi2::Target<T>& i_target, + const fapi2::buffer<uint64_t>& i_data ) + { + FAPI_DBG("wc_config3: 0x%016llx", i_data); + FAPI_TRY( mss::putScom(i_target, TT::WC_CONFIG3_REG, i_data) ); + fapi_try_exit: + return fapi2::current_err; + } + + + /// + /// @brief Read WC_RTT_WR_SWAP_ENABLE + /// @param[in] i_target the fapi2 target of the port + /// @param[out] o_data the value of the register + /// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok + /// + static inline fapi2::ReturnCode read_rtt_wr_swap_enable( const fapi2::Target<T>& i_target, + fapi2::buffer<uint64_t>& o_data ) + { + FAPI_TRY( mss::getScom(i_target, TT::WC_RTT_WR_SWAP_ENABLE_REG, o_data) ); + FAPI_DBG("wc_rtt_wr_swap_enable: 0x%016llx", o_data); + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief Write WC_RTT_WR_SWAP_ENABLE + /// @param[in] i_target the fapi2 target of the port + /// @param[in] i_data the value of the register + /// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok + /// + static inline fapi2::ReturnCode write_rtt_wr_swap_enable( const fapi2::Target<T>& i_target, + const fapi2::buffer<uint64_t>& i_data ) + { + FAPI_DBG("wc_rtt_wr_swap_enable: 0x%016llx", i_data); + FAPI_TRY( mss::putScom(i_target, TT::WC_RTT_WR_SWAP_ENABLE_REG, i_data) ); + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief reset wc_config0 + /// @param[in] i_target, fapi2 target of the port + /// @return fapi2::ReturnCode, FAPI2_RC_SUCCESS if ok + /// + static inline fapi2::ReturnCode reset_config0( const fapi2::Target<T>& i_target ) + { + fapi2::buffer<uint64_t> l_data; + uint8_t l_is_sim = 0; + FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_IS_SIMULATION, fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>(), l_is_sim) ); + + // This is a simplification - in sim we don't have DQS wire delays so we don't acccount for them BRS + l_data.insertFromRight<TT::TWLO_TWLOE, TT::TWLO_TWLOE_LEN>(mss::twlo_twloe(i_target)); + + // WL_ONE_DQS_PULSE = enable (one pulse) + l_data.setBit<TT::WL_ONE_DQS_PULSE>(); + + // FW_WR_RD [same formula as RD_WR? max(tWTR+11,AL+tRTP+3), ATTR_EFF_DRAM_AL(0,1,2)] + // 57:62, 0b000000, (def_is_sim); # is this max? + // 57:62, 0b100000, any; # dd0 = 17 clocks, now 32 from SWyatt + { + const uint64_t FW_WR_RD = l_is_sim ? 0b000000 : 0b100000; + l_data.insertFromRight<TT::FW_WR_RD, TT::FW_WR_RD_LEN>(FW_WR_RD); + } + + // 63, 0b0, any; # CUSTOM_INIT_WRITE + l_data.clearBit<TT::CUSTOM_INIT_WRITE>(); + + FAPI_DBG("wc_config0 reset 0x%llx (tWLO_tWLOE: %d)", l_data, mss::twlo_twloe(i_target)); + FAPI_TRY( write_config0(i_target, l_data) ); + + fapi_try_exit: + return fapi2::current_err; + + } + + /// + /// @brief reset wc_config1 + /// @param[in] i_target, fapi2 target of the port + /// @return fapi2::ReturnCode, FAPI2_RC_SUCCESS if ok + /// + static inline fapi2::ReturnCode reset_config1( const fapi2::Target<T>& i_target ) + { + // Reset WC_CONFIG1 with the values directly from the PHY databook + fapi2::buffer<uint64_t> l_data; + + l_data.insertFromRight<TT::BIG_STEP, TT::BIG_STEP_LEN>(WR_LVL_BIG_STEP); + l_data.insertFromRight<TT::SMALL_STEP, TT::SMALL_STEP_LEN>(WR_LVL_SMALL_STEP); + l_data.insertFromRight<TT::WR_PRE_DLY, TT::WR_PRE_DLY_LEN>(WR_LVL_PRE_DLY); + + FAPI_DBG("wc_config1 reset 0x%llx (big 0x%x small 0x%x wr_pre_dly 0x%x)", + l_data, WR_LVL_BIG_STEP, WR_LVL_SMALL_STEP, WR_LVL_PRE_DLY); + FAPI_TRY( write_config1(i_target, l_data) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief reset wc_config2 + /// @param[in] i_target, fapi2 target of the port + /// @return fapi2::ReturnCode, FAPI2_RC_SUCCESS if ok + /// + static inline fapi2::ReturnCode reset_config2( const fapi2::Target<T>& i_target ) + { + fapi2::buffer<uint64_t> l_data; + + l_data.insertFromRight<TT::NUM_VALID_SAMPLES, TT::NUM_VALID_SAMPLES_LEN>(WR_LVL_NUM_VALID_SAMPLES); + l_data.insertFromRight<TT::FW_RD_WR, TT::FW_RD_WR_LEN>(WR_CNTR_FW_RD_WR); + + FAPI_DBG("wc_config2 reset 0x%llx", l_data); + FAPI_TRY( write_config2(i_target, l_data) ); + + fapi_try_exit: + return fapi2::current_err; + } + + /// + /// @brief reset wc_config3 + /// @param[in] i_target, fapi2 target of the port + /// @return fapi2::ReturnCode, FAPI2_RC_SUCCESS if ok + /// + static inline fapi2::ReturnCode reset_config3( const fapi2::Target<T>& i_target ) + { + fapi2::buffer<uint64_t> l_data; + uint8_t l_is_sim = 0; + FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_IS_SIMULATION, fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>(), l_is_sim) ); + + // MCA_DDRPHY_WC_CONFIG3_P0_MRS_CMD_DQ_ON is 0's + + // 55:60, 0b000000, (def_is_sim); # MRS_CMD_DQ_OFF !! + // 55:60, 0b111111, any ; # MRS_CMD_DQ_OFF !! + { + const uint64_t CMD_DQ_OFF = l_is_sim ? 0b000000 : 0b111111; + l_data.insertFromRight<TT::MRS_CMD_DQ_OFF, TT::MRS_CMD_DQ_OFF_LEN>(CMD_DQ_OFF); + } + + FAPI_DBG("wc_config3 reset 0x%llx", l_data); + FAPI_TRY( write_config3(i_target, l_data) ); + + fapi_try_exit: + return fapi2::current_err; + + } + + + /// + /// @brief reset wc_rtt_wr_swap_enable + /// @param[in] i_target, fapi2 target of the port + /// @return fapi2::ReturnCode, FAPI2_RC_SUCCESS if ok + /// + static inline fapi2::ReturnCode reset_rtt_wr_swap_enable( const fapi2::Target<T>& i_target ) + { + fapi2::buffer<uint64_t> l_data; + + FAPI_TRY( read_rtt_wr_swap_enable(i_target, l_data) ); + + // Per John Bialas 1/16: The enable RTT_SWAP bit is causing problems. + l_data.clearBit<TT::RTT_WR_SWAP_ENABLE_P0_WL>(); + l_data.setBit<TT::RTT_WR_SWAP_ENABLE_P0_CTR>(); + + FAPI_DBG("wc_rtt_wr_swap_enable reset 0x%llx", l_data); + FAPI_TRY( write_rtt_wr_swap_enable(i_target, l_data) ); + + fapi_try_exit: + return fapi2::current_err; + + } + + /// + /// @brief reset wc + /// @param[in] i_target, fapi2 target of the port + /// @return fapi2::ReturnCode, FAPI2_RC_SUCCESS if ok + /// + static inline fapi2::ReturnCode reset( const fapi2::Target<T>& i_target ) + { + FAPI_TRY( reset_config0(i_target) ); + FAPI_TRY( reset_config1(i_target) ); + FAPI_TRY( reset_config2(i_target) ); + FAPI_TRY( reset_config3(i_target) ); + + FAPI_TRY( reset_rtt_wr_swap_enable(i_target) ); + + fapi_try_exit: + return fapi2::current_err; + } + + +}; + +// Touch of sugar here to allow mss::wc::<api>. When we support +// other targets (not just MCA) we will need to remove the default +// template argument for wc_class and we can just rename the class +// then to wc. +using wc = wc_class<fapi2::TARGET_TYPE_MCA>; + +} + +#endif |