/* IBM_PROLOG_BEGIN_TAG */ /* This is an automatically generated prolog. */ /* */ /* $Source: src/import/chips/p9/procedures/hwp/memory/lib/phy/phy_cntrl.H $ */ /* */ /* OpenPOWER HostBoot Project */ /* */ /* Contributors Listed Below - COPYRIGHT 2016,2019 */ /* [+] International Business Machines Corp. */ /* */ /* */ /* Licensed under the Apache License, Version 2.0 (the "License"); */ /* you may not use this file except in compliance with the License. */ /* You may obtain a copy of the License at */ /* */ /* http://www.apache.org/licenses/LICENSE-2.0 */ /* */ /* Unless required by applicable law or agreed to in writing, software */ /* distributed under the License is distributed on an "AS IS" BASIS, */ /* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ /* implied. See the License for the specific language governing */ /* permissions and limitations under the License. */ /* */ /* IBM_PROLOG_END_TAG */ /// /// @file phy_cntrl.H /// @brief Subroutines for the PHY phy control registers /// // *HWP HWP Owner: Stephen Glancy // *HWP HWP Backup: Andre Marin // *HWP Team: Memory // *HWP Level: 3 // *HWP Consumed by: FSP:HB #ifndef _MSS_PHY_CNTRL_H_ #define _MSS_PHY_CNTRL_H_ #include #include #include #include #include #include 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 pcTraits /// @brief a collection of traits associated with the PHY phy control /// @tparam T fapi2::TargetType representing the PHY /// template< fapi2::TargetType T > class pcTraits; /// /// @class pcTraits /// @brief a collection of traits associated with the Centaur PHY /// template<> class pcTraits { }; /// /// @class pcTraits /// @brief a collection of traits associated with the Nimbus PHY phy control /// template<> class pcTraits { public: // MCA phy control registers static const uint64_t PC_ERROR_STATUS0_REG = MCA_DDRPHY_PC_ERROR_STATUS0_P0; static const uint64_t PC_INIT_CAL_ERROR_REG = MCA_DDRPHY_PC_INIT_CAL_ERROR_P0; static const uint64_t PC_DLL_ZCAL_CAL_STATUS_REG = MCA_DDRPHY_PC_DLL_ZCAL_CAL_STATUS_P0; static const uint64_t PC_RESETS_REG = MCA_DDRPHY_PC_RESETS_P0; static const uint64_t PC_CONFIG0_REG = MCA_DDRPHY_PC_CONFIG0_P0; static const uint64_t PC_CONFIG1_REG = MCA_DDRPHY_PC_CONFIG1_P0; static const uint64_t PC_INIT_CAL_CONFIG1_REG = MCA_DDRPHY_PC_INIT_CAL_CONFIG1_P0; // MCA phy MR shadow registers, indexed by [rank_pair][MR index] static const std::vector< std::vector > PC_MR_SHADOW_REGS; enum { INIT_CAL_ERROR_WR_LEVEL = MCA_DDRPHY_PC_INIT_CAL_ERROR_P0_WR_LEVEL, INIT_CAL_ERROR_INITIAL_PAT_WRITE = MCA_DDRPHY_PC_INIT_CAL_ERROR_P0_INITIAL_PAT_WRITE, INIT_CAL_ERROR_DQS_ALIGN = MCA_DDRPHY_PC_INIT_CAL_ERROR_P0_DQS_ALIGN, INIT_CAL_ERROR_RDCLK_ALIGN = MCA_DDRPHY_PC_INIT_CAL_ERROR_P0_RDCLK_ALIGN, INIT_CAL_ERROR_READ_CTR = MCA_DDRPHY_PC_INIT_CAL_ERROR_P0_READ_CTR, INIT_CAL_ERROR_WRITE_CTR = MCA_DDRPHY_PC_INIT_CAL_ERROR_P0_WRITE_CTR, INIT_CAL_ERROR_INITIAL_COARSE_WR = MCA_DDRPHY_PC_INIT_CAL_ERROR_P0_INITIAL_COARSE_WR, INIT_CAL_ERROR_COARSE_RD = MCA_DDRPHY_PC_INIT_CAL_ERROR_P0_COARSE_RD, INIT_CAL_ERROR_CUSTOM_RD = MCA_DDRPHY_PC_INIT_CAL_ERROR_P0_CUSTOM_RD, INIT_CAL_ERROR_CUSTOM_WR = MCA_DDRPHY_PC_INIT_CAL_ERROR_P0_CUSTOM_WR, INIT_CAL_ERROR_DIGITAL_EYE = MCA_DDRPHY_PC_INIT_CAL_ERROR_P0_DIGITAL_EYE, INIT_CAL_ERROR_VREF = MCA_DDRPHY_PC_INIT_CAL_ERROR_P0_VREF, INIT_CAL_ERROR_RANK_PAIR = MCA_DDRPHY_PC_INIT_CAL_ERROR_P0_RANK_PAIR, INIT_CAL_ERROR_RANK_PAIR_LEN = MCA_DDRPHY_PC_INIT_CAL_ERROR_P0_RANK_PAIR_LEN, INIT_CAL_REFRESH_COUNT = MCA_DDRPHY_PC_INIT_CAL_CONFIG1_P0_REFRESH_COUNT, INIT_CAL_REFRESH_COUNT_LEN = MCA_DDRPHY_PC_INIT_CAL_CONFIG1_P0_REFRESH_COUNT_LEN, INIT_CAL_REFRESH_CONTROL = MCA_DDRPHY_PC_INIT_CAL_CONFIG1_P0_REFRESH_CONTROL, INIT_CAL_REFRESH_CONTROL_LEN = MCA_DDRPHY_PC_INIT_CAL_CONFIG1_P0_REFRESH_CONTROL_LEN, INIT_CAL_REFRESH_ALL_RANKS = MCA_DDRPHY_PC_INIT_CAL_CONFIG1_P0_REFRESH_ALL_RANKS, INIT_CAL_SNOOP_DIS = MCA_DDRPHY_PC_INIT_CAL_CONFIG1_P0_SNOOP_DIS, INIT_CAL_REFRESH_INTERVAL = MCA_DDRPHY_PC_INIT_CAL_CONFIG1_P0_REFRESH_INTERVAL, INIT_CAL_REFRESH_INTERVAL_LEN = MCA_DDRPHY_PC_INIT_CAL_CONFIG1_P0_REFRESH_INTERVAL_LEN, // How many bits are in the field running from INIT_CAL_ERROR_WR_LEVEL to INIT_CAL_ERROR_VREF // Needed to pull the entire field out of the register. CAL_ERROR_FIELD_LEN = 11, DLL_CAL_STATUS_DP_GOOD = MCA_DDRPHY_PC_DLL_ZCAL_CAL_STATUS_P0_DP_GOOD, DLL_CAL_STATUS_DP_ERROR = MCA_DDRPHY_PC_DLL_ZCAL_CAL_STATUS_P0_DP_ERROR, DLL_CAL_STATUS_DP_ERROR_FINE = MCA_DDRPHY_PC_DLL_ZCAL_CAL_STATUS_P0_DP_ERROR_FINE, DLL_CAL_STATUS_ADR_GOOD = MCA_DDRPHY_PC_DLL_ZCAL_CAL_STATUS_P0_ADR_GOOD, DLL_CAL_STATUS_ADR_ERROR = MCA_DDRPHY_PC_DLL_ZCAL_CAL_STATUS_P0_ADR_ERROR, DLL_CAL_STATUS_ADR_ERROR_FINE = MCA_DDRPHY_PC_DLL_ZCAL_CAL_STATUS_P0_ADR_ERROR_FINE, ZCAL_CAL_STATUS_DONE = MCA_DDRPHY_PC_DLL_ZCAL_CAL_STATUS_P0_DONE, SYSCLK_RESET = MCA_DDRPHY_PC_RESETS_P0_SYSCLK_RESET, PVT_OVERRIDE = MCA_DDRPHY_PC_RESETS_P0_PVT_OVERRIDE, ENABLE_ZCAL = MCA_DDRPHY_PC_RESETS_P0_ENABLE_ZCAL, WRITE_LATENCY_OFFSET = MCA_DDRPHY_PC_CONFIG1_P0_WRITE_LATENCY_OFFSET, WRITE_LATENCY_OFFSET_LEN = MCA_DDRPHY_PC_CONFIG1_P0_WRITE_LATENCY_OFFSET_LEN, READ_LATENCY_OFFSET = MCA_DDRPHY_PC_CONFIG1_P0_READ_LATENCY_OFFSET, READ_LATENCY_OFFSET_LEN = MCA_DDRPHY_PC_CONFIG1_P0_READ_LATENCY_OFFSET_LEN, MEMCTL_CIC_FAST = MCA_DDRPHY_PC_CONFIG1_P0_MEMCTL_CIC_FAST, MEMCTL_CTRN_IGNORE = MCA_DDRPHY_PC_CONFIG1_P0_MEMCTL_CTRN_IGNORE, DISABLE_MEMCTL_CAL = MCA_DDRPHY_PC_CONFIG1_P0_DISABLE_MEMCTL_CAL, MEMORY_TYPE = MCA_DDRPHY_PC_CONFIG1_P0_MEMORY_TYPE, MEMORY_TYPE_LEN = MCA_DDRPHY_PC_CONFIG1_P0_MEMORY_TYPE_LEN, DDR4_LATENCY_SW = MCA_DDRPHY_PC_CONFIG1_P0_DDR4_LATENCY_SW, RETRAIN_PERCAL_SW = MCA_DDRPHY_PC_CONFIG1_P0_RETRAIN_PERCAL_SW, // // PC Config0 Protocol has been re-purposed for PDA enable. // // repurposed to pda_enable_override, so zero per John Bialas 4/16 JJM // PDA_ENABLE = MCA_DDRPHY_PC_CONFIG0_P0_PROTOCOL, // PDA_ENABLE_LEN = MCA_DDRPHY_PC_CONFIG0_P0_PROTOCOL_LEN, DATA_MUX4_1MODE = MCA_DDRPHY_PC_CONFIG0_P0_DATA_MUX4_1MODE, DDR4_CMD_SIG_REDUCTION = MCA_DDRPHY_PC_CONFIG0_P0_DDR4_CMD_SIG_REDUCTION, SYSCLK_2X_MEMINTCLKO = MCA_DDRPHY_PC_CONFIG0_P0_SYSCLK_2X_MEMINTCLKO, RANK_OVERRIDE = MCA_DDRPHY_PC_CONFIG0_P0_RANK_OVERRIDE, RANK_OVERRIDE_VALUE = MCA_DDRPHY_PC_CONFIG0_P0_RANK_OVERRIDE_VALUE, RANK_OVERRIDE_VALUE_LEN = MCA_DDRPHY_PC_CONFIG0_P0_RANK_OVERRIDE_VALUE_LEN, LOW_LATENCY = MCA_DDRPHY_PC_CONFIG0_P0_LOW_LATENCY, DDR4_IPW_LOOP_DIS = MCA_DDRPHY_PC_CONFIG0_P0_DDR4_IPW_LOOP_DIS, DDR4_VLEVEL_BANK_GROUP = MCA_DDRPHY_PC_CONFIG0_P0_DDR4_VLEVEL_BANK_GROUP, VPROTH_PSEL_MODE = MCA_DDRPHY_PC_CONFIG0_P0_VPROTH_PSEL_MODE, PBA_ENABLE = P9N2_MCA_DDRPHY_PC_CONFIG0_P0_PBA_ENABLE, }; }; namespace pc { /// /// @brief read PC_CONFIG1 /// @tparam T fapi2 Target Type - derived /// @tparam TT traits type defaults to dp16Traits /// @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 /// template< fapi2::TargetType T, typename TT = pcTraits > inline fapi2::ReturnCode read_config1( const fapi2::Target& i_target, fapi2::buffer& o_data ) { FAPI_TRY( mss::getScom(i_target, TT::PC_CONFIG1_REG, o_data), "%s failed to read pc_config1 register", mss::c_str(i_target) ); FAPI_INF("pc_config1: 0x%016llx", o_data); fapi_try_exit: return fapi2::current_err; } /// /// @brief Write PC_CONFIG1 /// @tparam T fapi2 Target Type - derived /// @tparam TT traits type defaults to dp16Traits /// @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 /// template< fapi2::TargetType T, typename TT = pcTraits > inline fapi2::ReturnCode write_config1( const fapi2::Target& i_target, const fapi2::buffer& i_data ) { FAPI_INF("pc_config1: 0x%016llx", i_data); FAPI_TRY( mss::putScom(i_target, TT::PC_CONFIG1_REG, i_data), "%s failed to write pc_config1 register", mss::c_str(i_target) ); fapi_try_exit: return fapi2::current_err; } /// /// @brief reset pc_config1 /// @tparam T fapi2 Target Type - derived /// @tparam TT traits type defaults to dp16Traits /// @param[in] i_target fapi2 target of the port /// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok /// template< fapi2::TargetType T, typename TT = pcTraits > fapi2::ReturnCode reset_config1( const fapi2::Target& i_target ); /// /// @brief read PC_CONFIG0 /// @tparam T fapi2 Target Type - derived /// @tparam TT traits type defaults to dp16Traits /// @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 /// template< fapi2::TargetType T, typename TT = pcTraits > inline fapi2::ReturnCode read_config0( const fapi2::Target& i_target, fapi2::buffer& o_data ) { FAPI_TRY( mss::getScom(i_target, TT::PC_CONFIG0_REG, o_data), "%s failed to read pc_config0 register", mss::c_str(i_target) ); FAPI_INF("pc_config0: 0x%016llx", o_data); fapi_try_exit: return fapi2::current_err; } /// /// @brief Write PC_CONFIG0 /// @tparam T fapi2 Target Type - derived /// @tparam TT traits type defaults to dp16Traits /// @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 /// template< fapi2::TargetType T, typename TT = pcTraits > inline fapi2::ReturnCode write_config0( const fapi2::Target& i_target, const fapi2::buffer& i_data ) { FAPI_INF("pc_config0: 0x%016llx", i_data); FAPI_TRY( mss::putScom(i_target, TT::PC_CONFIG0_REG, i_data), "%s failed to write pc_config0 register", mss::c_str(i_target) ); fapi_try_exit: return fapi2::current_err; } /// /// @brief reset pc_config0 /// @tparam T fapi2 Target Type - derived /// @tparam TT traits type defaults to dp16Traits /// @param[in] i_target fapi2 target of the port /// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok /// template< fapi2::TargetType T, typename TT = pcTraits > fapi2::ReturnCode reset_config0( const fapi2::Target& i_target ); /// /// @brief read PC_INIT_CAL_CONFIG1 /// @tparam T fapi2 Target Type - derived /// @tparam TT traits type defaults to dp16Traits /// @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 /// template< fapi2::TargetType T, typename TT = pcTraits > inline fapi2::ReturnCode read_init_cal_config1( const fapi2::Target& i_target, fapi2::buffer& o_data ) { FAPI_TRY( mss::getScom(i_target, TT::PC_INIT_CAL_CONFIG1_REG, o_data), "%s failed to read pc_init_cal_config1 register", mss::c_str(i_target) ); FAPI_INF("Read pc_init_cal_config1: 0x%016llx", o_data); fapi_try_exit: return fapi2::current_err; } /// /// @brief write PC_INIT_CAL_CONFIG1 /// @tparam T fapi2 Target Type - derived /// @tparam TT traits type defaults to dp16Traits /// @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 /// template< fapi2::TargetType T, typename TT = pcTraits > inline fapi2::ReturnCode write_init_cal_config1( const fapi2::Target& i_target, const fapi2::buffer& i_data ) { FAPI_INF("Writing to pc_init_cal_config1: 0x%016llx", i_data); FAPI_TRY( mss::putScom(i_target, TT::PC_INIT_CAL_CONFIG1_REG, i_data), "%s failed to write pc_init_cal_config1 register", mss::c_str(i_target) ); fapi_try_exit: return fapi2::current_err; } /// /// @brief set INIT_CAL_REFRESH_COUNT /// @tparam T fapi2 Target Type - derived /// @tparam TT traits type defaults to dp16Traits /// @param[in] i_target the fapi2 target of the port /// @param[out] o_data the value of the register /// @param[in] i_value value to specify the number of cmds /// to insert at the start of init cal /// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok /// template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCA, typename TT = pcTraits > inline void set_refresh_count( fapi2::buffer& o_data, const uint64_t i_state ) { FAPI_INF("set init_cal refresh_count: %d", i_state); o_data.insertFromRight(i_state); } /// /// @brief set INIT_CAL_REFRESH_CONTROL /// @tparam T fapi2 Target Type - defaults to fapi2::TARGET_TYPE_MCA /// @tparam TT traits type defaults to dp16Traits /// @param[out] o_data the value of the register /// @param[in] i_value value to control refresh logic during init cal /// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok /// template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCA, typename TT = pcTraits > inline void set_refresh_control( fapi2::buffer& o_data, const uint64_t i_state ) { FAPI_INF("set init_cal refresh_control: %d", i_state); o_data.insertFromRight(i_state); } /// /// @brief Set PBA_ENABLE /// @tparam T fapi2 Target Type - defaults to fapi2::TARGET_TYPE_MCA /// @tparam TT traits type defaults to dp16Traits /// @param[in,out] io_data the value of the register /// @param[in] i_state mss::LOW or mss::HIGH representing the state of the bit /// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok /// template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCA, typename TT = pcTraits > inline void set_pba_enable( fapi2::buffer& io_data, const mss::states i_state ) { FAPI_INF("set_pba_enable: %s", (i_state == mss::HIGH) ? "high" : "low"); io_data.writeBit(i_state); } /// /// @brief set INIT_CAL_REFRESH_ALL_RANKS /// @tparam T fapi2 Target Type - defaults to fapi2::TARGET_TYPE_MCA /// @tparam TT traits type defaults to dp16Traits /// @param[out] o_data the value of the register /// @param[in] i_state mss::LOW or mss::HIGH representing the state of the bit /// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok /// template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCA, typename TT = pcTraits > inline void set_refresh_all_ranks( fapi2::buffer& o_data, const mss::states i_state ) { FAPI_INF("set init_cal refresh_all_ranks: %s", (i_state == mss::HIGH) ? "high" : "low"); o_data.writeBit(i_state); } /// /// @brief set INIT_CAL_SNOOP_DIS /// @tparam T fapi2 Target Type - defaults to fapi2::TARGET_TYPE_MCA /// @tparam TT traits type defaults to dp16Traits /// @param[out] o_data the value of the register /// @param[in] i_state mss::LOW or mss::HIGH representing the state of the bit /// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok /// template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCA, typename TT = pcTraits > inline void set_snoop_dis( fapi2::buffer& o_data, const mss::states i_state ) { FAPI_INF("set init_cal snoop_dis: %s", (i_state == mss::HIGH) ? "high" : "low"); o_data.writeBit(i_state); } /// /// @brief set INIT_CAL_REFRESH_INTERVAL /// @tparam T fapi2 Target Type - defaults to fapi2::TARGET_TYPE_MCA /// @tparam TT traits type defaults to dp16Traits /// @param[out] o_data the value of the register /// @param[in] i_value tREFI in cycles /// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok /// template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCA, typename TT = pcTraits > inline void set_refresh_interval( fapi2::buffer& o_data, const uint64_t i_value ) { FAPI_INF("set init_cal refresh_interval: %d", i_value); o_data.insertFromRight(i_value); } /// /// @brief read MCA_DDRPHY_PC_DLL_ZCAL_CAL_STATUS /// @tparam T fapi2 Target Type - derived /// @tparam TT traits type defaults to dp16Traits /// @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 /// template< fapi2::TargetType T, typename TT = pcTraits > inline fapi2::ReturnCode read_dll_zcal_status( const fapi2::Target& i_target, fapi2::buffer& o_data ) { FAPI_TRY( mss::getScom(i_target, TT::PC_DLL_ZCAL_CAL_STATUS_REG, o_data), "%s failed to read pc_dll_zcal_status register", mss::c_str(i_target) ); FAPI_INF("pc_dll_zcal_status: 0x%016llx", o_data); fapi_try_exit: return fapi2::current_err; } /// /// @brief Get DP DLL Cal Status /// @param[in] l_good DLL CAL good status of DP or ADR /// @param[in] l_error DLL CAL error status of DP or ADR /// @param[in] l_error_fine DLL CAL error fine status of DP or ADR /// @return mss::states; YES == success, NO == fail, INVALID == still running /// @note Since the these indicators are a summary of all DLLs, all must be started to make /// them valid. /// static inline mss::states dll_cal_status_helper( const bool l_good, const bool l_error, const bool l_error_fine ) { // Full calibration is still going on in at least 1 DLL while all 3 signals are 0. if ((l_good == mss::LOW) && (l_error == mss::LOW) && (l_error_fine == mss::LOW)) { return mss::_INVALID_; } // Full calibration was successful in all DLLs if CAL_GOOD = 1 and both CAL_ERROR and CAL_ERROR_FINE are 0. if ((l_good == mss::HIGH) && (l_error == mss::LOW) && (l_error_fine == mss::LOW)) { return mss::YES; } // Full calibration failed in at least 1 DLL if either CAL_ERROR or CAL_ERROR_FINE are 1. if ((l_error == mss::HIGH) || (l_error_fine == mss::HIGH)) { return mss::NO; } // All cases shoud be covered above // we shouldn't reach here so we add // a saftey net. fapi2::Assert(false); return mss::NO; } /// /// @brief Get DP DLL Cal Status /// @tparam T fapi2 Target Type - derived /// @tparam TT traits type defaults to dp16Traits /// Combine the processing of Good, Error and Error Fine into one functional interface /// @param[in] fapi2::buffer representing the status register to interrogate /// @return mss::states; YES == success, NO == fail, INVALID == still running /// @note Since the these indicators are a summary of all DLLs, all must be started to make /// them valid. /// template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCA, typename TT = pcTraits > inline mss::states get_dll_cal_status( fapi2::buffer& i_data ) { // Lets check the cal status of the DPs first const bool l_dp_good = i_data.getBit(); const bool l_dp_error = i_data.getBit(); const bool l_dp_error_fine = i_data.getBit(); const mss::states l_dp_status = dll_cal_status_helper(l_dp_good, l_dp_error, l_dp_error_fine); // Lets check the cal status of the ADRs second const bool l_adr_good = i_data.getBit(); const bool l_adr_error = i_data.getBit(); const bool l_adr_error_fine = i_data.getBit(); const mss::states l_adr_status = dll_cal_status_helper(l_adr_good, l_adr_error, l_adr_error_fine); FAPI_INF("pc_dll_status: 0x%016llx", i_data); if( l_dp_status == mss::_INVALID_ || l_adr_status == mss::_INVALID_ ) { return mss::_INVALID_; } if( l_dp_status == mss::NO || l_adr_status == mss::NO ) { return mss::NO; } if( l_dp_status == mss::YES && l_adr_status == mss::YES ) { return mss::YES; } // Shouldn't get here, so we put some belt and suspenders FAPI_ERR("pc_dll_cal_status: 0x%016llx unable to calculate state", i_data); fapi2::Assert(false); return mss::NO; } // MCA_DDRPHY_PC_DLL_ZCAL_CAL_STATUS is read-only /// /// @brief Get ZCAL Cal Status /// @tparam T fapi2 Target Type - derived /// @tparam TT traits type defaults to dp16Traits /// @param[in] fapi2::buffer representing the status register to interrogate /// @return mss::states; YES == success, NO == fail /// template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCA, typename TT = pcTraits > inline mss::states get_zcal_status( const fapi2::buffer& i_data ) { FAPI_INF("zcal_status: 0x%016lx", i_data); return (i_data.getBit() == true) ? mss::YES : mss::NO; } /// /// @brief read PC_ERROR_STATUS0 /// @tparam T fapi2 Target Type - derived /// @tparam TT traits type defaults to dp16Traits /// @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 /// template< fapi2::TargetType T, typename TT = pcTraits > inline fapi2::ReturnCode read_error_status0( const fapi2::Target& i_target, fapi2::buffer& o_data ) { FAPI_TRY( mss::getScom(i_target, TT::PC_ERROR_STATUS0_REG, o_data), "%s failed to read pc_error_status0 register", mss::c_str(i_target) ); FAPI_INF("pc_error_status0: 0x%016llx", o_data); fapi_try_exit: return fapi2::current_err; } /// /// @brief Write PC_ERROR_STATUS0 /// @tparam T fapi2 Target Type - derived /// @tparam TT traits type defaults to dp16Traits /// @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 /// template< fapi2::TargetType T, typename TT = pcTraits > inline fapi2::ReturnCode write_error_status0( const fapi2::Target& i_target, const fapi2::buffer& i_data ) { FAPI_INF("pc_error_status0: 0x%016llx", i_data); FAPI_TRY( mss::putScom(i_target, TT::PC_ERROR_STATUS0_REG, i_data), "%s failed to write pc_error_status0 register", mss::c_str(i_target) ); fapi_try_exit: return fapi2::current_err; } /// /// @brief reset pc_error_status0 /// @tparam T fapi2 Target Type - derived /// @tparam TT traits type defaults to dp16Traits /// @param[in] i_target fapi2 target of the port /// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok /// template< fapi2::TargetType T, typename TT = pcTraits > inline fapi2::ReturnCode reset_error_status0( const fapi2::Target& i_target ) { FAPI_TRY( write_error_status0(i_target, 0), "%s failed to clear pc_error_status0 register via write", mss::c_str(i_target) ); fapi_try_exit: return fapi2::current_err; } /// /// @brief read PC_INIT_CAL_ERROR /// @tparam T fapi2 Target Type - derived /// @tparam TT traits type defaults to dp16Traits /// @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 /// template< fapi2::TargetType T, typename TT = pcTraits > inline fapi2::ReturnCode read_init_cal_error( const fapi2::Target& i_target, fapi2::buffer& o_data ) { FAPI_TRY( mss::getScom(i_target, TT::PC_INIT_CAL_ERROR_REG, o_data), "%s failed to read pc_init_cal_error register", mss::c_str(i_target) ); FAPI_INF("pc_init_cal_error: 0x%016llx", o_data); fapi_try_exit: return fapi2::current_err; } /// /// @brief Write PC_INIT_CAL_ERROR /// @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 /// template< fapi2::TargetType T, typename TT = pcTraits > inline fapi2::ReturnCode write_init_cal_error( const fapi2::Target& i_target, const fapi2::buffer& i_data ) { FAPI_INF("pc_init_cal_error: 0x%016llx", i_data); FAPI_TRY( mss::putScom(i_target, TT::PC_INIT_CAL_ERROR_REG, i_data), "%s failed to write pc_init_cal_error register", mss::c_str(i_target) ); fapi_try_exit: return fapi2::current_err; } /// /// @brief reset pc_init_cal_error /// @tparam T fapi2 Target Type - derived /// @tparam TT traits type defaults to dp16Traits /// @param[in] i_target fapi2 target of the port /// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok /// template< fapi2::TargetType T, typename TT = pcTraits > inline fapi2::ReturnCode reset_init_cal_error( const fapi2::Target& i_target ) { FAPI_TRY( write_init_cal_error(i_target, 0), "%s failed to clear pc_init_cal_error register via write", mss::c_str(i_target) ); fapi_try_exit: return fapi2::current_err; } /// /// @brief reset rc /// @tparam T fapi2 Target Type - derived /// @tparam TT traits type defaults to dp16Traits /// @param[in] i_target fapi2 target of the port /// @return fapi2::ReturnCode, FAPI2_RC_SUCCESS if ok /// template< fapi2::TargetType T, typename TT = pcTraits > inline fapi2::ReturnCode reset( const fapi2::Target& i_target ) { // Note that PC_CONFIG0 is statically configured in the initfile - we don't need to reset it. FAPI_TRY( reset_config1(i_target) ); FAPI_TRY( reset_error_status0(i_target) ); FAPI_TRY( reset_init_cal_error(i_target) ); fapi_try_exit: return fapi2::current_err; } /// /// @brief read PC_RESETS /// @tparam T fapi2 Target Type - derived /// @tparam TT traits type defaults to dp16Traits /// @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 /// template< fapi2::TargetType T, typename TT = pcTraits > inline fapi2::ReturnCode read_resets( const fapi2::Target& i_target, fapi2::buffer& o_data ) { FAPI_TRY( mss::getScom(i_target, TT::PC_RESETS_REG, o_data), "%s failed to read pc_resets register", mss::c_str(i_target) ); FAPI_INF("pc_resets: 0x%016llx", o_data); fapi_try_exit: return fapi2::current_err; } /// /// @brief Write PC_RESETS /// @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 /// template< fapi2::TargetType T, typename TT = pcTraits > inline fapi2::ReturnCode write_resets( const fapi2::Target& i_target, const fapi2::buffer& i_data ) { FAPI_INF("pc_resets: 0x%016llx", i_data); FAPI_TRY( mss::putScom(i_target, TT::PC_RESETS_REG, i_data), "%s failed to write pc_resets register", mss::c_str(i_target) ); fapi_try_exit: return fapi2::current_err; } /// /// @brief Set ENABLE_ZCAL in PC_RESETS /// @tparam T fapi2 Target Type - derived /// @tparam TT traits type defaults to dp16Traits /// @param[out] o_data the value of the register /// @param[in] i_state mss::HIGH or mss::LOW /// template< fapi2::TargetType T = fapi2::TARGET_TYPE_MCA, typename TT = pcTraits > inline void set_enable_zcal( fapi2::buffer& o_data, const states i_state ) { FAPI_INF("set_enable_zcal %s", (i_state == mss::LOW ? "low" : "high")); o_data.writeBit(i_state); } } // close namespace pc } // close namespace mss #endif