diff options
author | Brian Silver <bsilver@us.ibm.com> | 2016-10-25 06:24:35 -0500 |
---|---|---|
committer | Christian R. Geddes <crgeddes@us.ibm.com> | 2016-10-31 10:36:59 -0400 |
commit | 0cb19a22319130ec4ebeb64ee87a47328297486e (patch) | |
tree | 23678cca2772e2d23043dd3b49f3aaf008b10baf /src | |
parent | c7cf0b2d56200537be4227b246fa5c4754cc7306 (diff) | |
download | talos-hostboot-0cb19a22319130ec4ebeb64ee87a47328297486e.tar.gz talos-hostboot-0cb19a22319130ec4ebeb64ee87a47328297486e.zip |
Add magic port capabilties for DDR PHY
Change-Id: I1cc2c51a2ddab1c20f110899dc5ff84b3233d58e
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/31772
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Reviewed-by: Louis Stermole <stermole@us.ibm.com>
Reviewed-by: ANDRE A. MARIN <aamarin@us.ibm.com>
Tested-by: Hostboot CI <hostboot-ci+hostboot@us.ibm.com>
Reviewed-by: Brian R. Silver <bsilver@us.ibm.com>
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/31801
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: Christian R. Geddes <crgeddes@us.ibm.com>
Diffstat (limited to 'src')
4 files changed, 138 insertions, 21 deletions
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 e78b6f20b..e59742159 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 @@ -76,7 +76,8 @@ fapi2::ReturnCode change_resetn( const fapi2::Target<TARGET_TYPE_MCBIST>& i_targ { fapi2::buffer<uint64_t> l_data; - for (const auto& p : mss::find_targets<TARGET_TYPE_MCA>(i_target)) + // Need to run on the magic port too + for (const auto& p : mss::find_targets_with_magic<TARGET_TYPE_MCA>(i_target)) { FAPI_INF("Change reset to %s PHY: %s", (i_state == HIGH ? "high" : "low"), mss::c_str(p)); @@ -96,8 +97,10 @@ fapi_try_exit: /// fapi2::ReturnCode enable_zctl( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target ) { + // We only need to zcal the magic ports - they have the logic for all the other ports. + const auto l_ports = mss::find_magic_targets<TARGET_TYPE_MCA>(i_target); + fapi2::buffer<uint64_t> l_data; - const auto l_ports = mss::find_targets<TARGET_TYPE_MCA>(i_target); constexpr uint64_t l_zcal_reset_reg = pcTraits<TARGET_TYPE_MCA>::PC_RESETS_REG; constexpr uint64_t l_zcal_status_reg = pcTraits<TARGET_TYPE_MCA>::PC_DLL_ZCAL_CAL_STATUS_REG; uint8_t is_sim = 0; @@ -164,6 +167,11 @@ fapi2::ReturnCode change_force_mclk_low (const fapi2::Target<TARGET_TYPE_MCBIST> fapi2::buffer<uint64_t> l_data; uint8_t is_sim = 0; + // We want to force the memory clocks low for all ports, including the magic port if it's not + // otherwise functional. We don't want to re-enable memory clocks for the magic port if it's + // not otherwise functional. + auto l_ports = (i_state == mss::LOW) ? mss::find_targets_with_magic<TARGET_TYPE_MCA>(i_target) : + mss::find_targets<TARGET_TYPE_MCA>(i_target); FAPI_INF("force mclk %s for all ports", (i_state == mss::LOW ? "low" : "high") ); FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_IS_SIMULATION, fapi2::Target<TARGET_TYPE_SYSTEM>(), is_sim) ); @@ -175,8 +183,7 @@ fapi2::ReturnCode change_force_mclk_low (const fapi2::Target<TARGET_TYPE_MCBIST> return fapi2::FAPI2_RC_SUCCESS; } - // Might as well do this for all the ports while we're here. - for (const auto& p : mss::find_targets<TARGET_TYPE_MCA>(i_target)) + for (const auto& p : l_ports) { FAPI_TRY( mss::getScom(p, MCA_MBA_FARB5Q, l_data) ); l_data.writeBit<MCA_MBA_FARB5Q_CFG_FORCE_MCLK_LOW_N>(i_state); @@ -1145,7 +1152,8 @@ fapi2::ReturnCode flush_output_drivers( const fapi2::Target<fapi2::TARGET_TYPE_M fapi2::buffer<uint64_t> l_adr_data; fapi2::buffer<uint64_t> l_dp16_data; - const auto l_ports = mss::find_targets<TARGET_TYPE_MCA>(i_target); + // Need to run on the magic ports too + const auto l_ports = mss::find_targets_with_magic<TARGET_TYPE_MCA>(i_target); const auto& l_force_atest_reg = adr32sTraits<TARGET_TYPE_MCA>::OUTPUT_DRIVER_REG; const auto& l_data_dir_reg = dp16Traits<TARGET_TYPE_MCA>::DATA_BIT_DIR1; diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/phy/dp16.C b/src/import/chips/p9/procedures/hwp/memory/lib/phy/dp16.C index 28a3bf170..ac2f4353a 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/phy/dp16.C +++ b/src/import/chips/p9/procedures/hwp/memory/lib/phy/dp16.C @@ -727,7 +727,8 @@ fapi2::ReturnCode reset_sysclk( const fapi2::Target<TARGET_TYPE_MCBIST>& i_targe l_data.setBit<MCA_DDRPHY_DP16_SYSCLK_PR0_P0_0_01_ROT_OVERRIDE_EN>(); } - for (const auto& p : i_target.getChildren<TARGET_TYPE_MCA>()) + // Need to run on the magic port too + for (const auto& p : mss::find_targets_with_magic<TARGET_TYPE_MCA>(i_target)) { FAPI_DBG("set dp16_sysclk for %s", mss::c_str(p)); diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/utils/find.H b/src/import/chips/p9/procedures/hwp/memory/lib/utils/find.H index 52561f8ae..c00bbac72 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/utils/find.H +++ b/src/import/chips/p9/procedures/hwp/memory/lib/utils/find.H @@ -41,6 +41,7 @@ #include <vector> #include <lib/utils/pos.H> +#include <lib/utils/c_str.H> namespace mss { @@ -66,6 +67,34 @@ template< fapi2::TargetType M, fapi2::TargetType T > inline fapi2::Target<M> find_target( const fapi2::Target<T>& i_target ); /// +/// @brief find the union of functionl targets and any magic targets +/// @note The PHY has a logic block which is only contained in the 0th PHY in the controller. +/// This makes the 0th PHY 'magic' in that it needs to always be present if not functional. +/// This function returns all functional targets and includes the magic target whether or not +/// it is truly functional. +/// @tparam M the target type to be returned +/// @tparam T the fapi2 target type of the argument +/// @param[in] i_target the fapi2 target T +/// @return a vector of M targets. +/// +template< fapi2::TargetType M, fapi2::TargetType T > +inline std::vector< fapi2::Target<M> > find_targets_with_magic( const fapi2::Target<T>& i_target); + +/// +/// @brief find a set of magic elements based on a fapi2 target +/// @note The PHY has a logic block which is only contained in the 0th PHY in the controller. +/// This makes the 0th PHY 'magic' in that it needs to always be present if not functional. +/// This function returns all magic targets whether or not it is truly functional. +/// It does not include other functional or present targets. +/// @tparam M the target type to be returned +/// @tparam T the fapi2 target type of the argument +/// @param[in] i_target the fapi2 target T +/// @return a vector of M targets. +/// +template< fapi2::TargetType M, fapi2::TargetType T > +inline std::vector< fapi2::Target<M> > find_magic_targets( const fapi2::Target<T>& i_target); + +/// /// @brief find the McBIST given a McBIST /// @param[in] i_self the fapi2 target mcBIST /// @return a McBIST target. @@ -181,6 +210,79 @@ inline std::vector< fapi2::Target<fapi2::TARGET_TYPE_MCA> > find_targets { return i_target.getChildren<fapi2::TARGET_TYPE_MCA>(); } + +/// +/// @brief find the magic MCA connected to an MCBIST +/// @param[in] i_target the fapi2::Target MCBIST +/// @return a vector of fapi2::TARGET_TYPE_MCA +/// +template<> +inline std::vector< fapi2::Target<fapi2::TARGET_TYPE_MCA> > find_magic_targets +( const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_target) +{ + // The magic port is in position 0, relative to the MCBIST + constexpr uint64_t RELATIVE_MAGIC_POS = 0; + + // This is only one magic MCA on every MCBIST, so we only return a vector of one + std::vector<fapi2::Target<fapi2::TARGET_TYPE_MCA>> l_magic_ports; + + // Get all the present MCA children and find the target with the relative position of 0 + for (const auto& p : i_target.getChildren<fapi2::TARGET_TYPE_MCA>(fapi2::TARGET_STATE_PRESENT)) + { + if (mss::relative_pos<fapi2::TARGET_TYPE_MCBIST>(p) == RELATIVE_MAGIC_POS) + { + l_magic_ports.push_back(p); + } + } + + // We don't care if the vector is empty. We don't know what the caller will do with this + // and they might not care if there is no magic port either ... + return l_magic_ports; +} + +/// +/// @brief find the union of functionl targets and any magic targets +/// @param[in] i_target the fapi2::Target MCBIST +/// @return a vector of i2::Target<fapi2::TARGET_TYPE_MCA> +/// +template<> +inline std::vector< fapi2::Target<fapi2::TARGET_TYPE_MCA> > find_targets_with_magic +( const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_target) +{ + // We need the union of the functional target list and the magic target list. We can + // get a little tricky with the MCA's - we know there's only one magic port. + // So if the one magic port isn't in the list of functional ports, add it + auto l_magic_ports = find_magic_targets<fapi2::TARGET_TYPE_MCA>(i_target); + + if (l_magic_ports.size() != 1) + { + FAPI_ERR("Found wrong number of magic ports on %s (%d)", mss::c_str(i_target), l_magic_ports.size()); + fapi2::Assert(false); + } + + auto l_ports = mss::find_targets<fapi2::TARGET_TYPE_MCA>(i_target); + const auto l_magic_pos = mss::relative_pos<fapi2::TARGET_TYPE_MCBIST>(l_magic_ports[0]); + const auto l_magic_port = std::find_if(l_ports.begin(), l_ports.end(), + [&l_magic_pos](const fapi2::Target<fapi2::TARGET_TYPE_MCA>& t) + { + // Check ports by relative position. + const auto l_pos = mss::relative_pos<fapi2::TARGET_TYPE_MCBIST>(t); + FAPI_DBG("checking for magic port at %d candidate is %d", l_magic_pos, l_pos); + return l_magic_pos == l_pos; + }); + + if (l_magic_port == l_ports.end()) + { + // Add the magic port to the front of the port vector. + FAPI_DBG("inserting magic port %d", l_magic_pos); + l_ports.insert(l_ports.begin(), l_magic_ports[0]); + } + + // In either case, l_ports is the proper thing to return. Either the magic port was in + // l_ports or it is now because we inserted it. + return l_ports; +} + /// /// @brief find all the MCA connected to an MCS /// @param[in] i_target a fapi2::Target MCS diff --git a/src/import/chips/p9/procedures/hwp/memory/p9_mss_scominit.C b/src/import/chips/p9/procedures/hwp/memory/p9_mss_scominit.C index a3b1a4b84..d50652db6 100644 --- a/src/import/chips/p9/procedures/hwp/memory/p9_mss_scominit.C +++ b/src/import/chips/p9/procedures/hwp/memory/p9_mss_scominit.C @@ -39,6 +39,7 @@ #include <p9_mcbist_scom.H> #include <p9_ddrphy_scom.H> #include <lib/utils/count_dimm.H> +#include <lib/utils/find.H> #include <lib/phy/ddr_phy.H> using fapi2::TARGET_TYPE_MCA; @@ -53,7 +54,9 @@ using fapi2::FAPI2_RC_SUCCESS; fapi2::ReturnCode p9_mss_scominit( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target ) { FAPI_INF("Start MSS SCOM init"); - auto l_mca_targets = i_target.getChildren<TARGET_TYPE_MCA>(); + + // We need to make sure we scominit the magic port. + const auto l_mca_targets = mss::find_targets_with_magic<TARGET_TYPE_MCA>(i_target); fapi2::ReturnCode l_rc; fapi2::Target<fapi2::TARGET_TYPE_SYSTEM> FAPI_SYSTEM; @@ -64,24 +67,28 @@ fapi2::ReturnCode p9_mss_scominit( const fapi2::Target<TARGET_TYPE_MCBIST>& i_ta return fapi2::FAPI2_RC_SUCCESS; } - for (auto l_mca_target : l_mca_targets ) + for (const auto& l_mca_target : l_mca_targets ) { - if (mss::count_dimm(l_mca_target) == 0) - { - FAPI_INF("... skipping mca_scominit %s - no DIMM ...", mss::c_str(l_mca_target)); - continue; - } - - FAPI_EXEC_HWP(l_rc, p9_mca_scom, l_mca_target, i_target, l_mca_target.getParent<fapi2::TARGET_TYPE_MCS>(), - FAPI_SYSTEM ); + FAPI_INF("scominit for %s", mss::c_str(l_mca_target)); - if (l_rc) + // Can't MCA init ports with no DIMM, they don't have attributes like timing. + if (mss::count_dimm(l_mca_target) != 0) { - FAPI_ERR("Error from p9.mca.scom.initfile"); - fapi2::current_err = l_rc; - goto fapi_try_exit; + FAPI_INF("mca scominit for %s", mss::c_str(l_mca_target)); + FAPI_EXEC_HWP(l_rc, p9_mca_scom, l_mca_target, i_target, l_mca_target.getParent<fapi2::TARGET_TYPE_MCS>(), + FAPI_SYSTEM ); + + if (l_rc) + { + FAPI_ERR("Error from p9.mca.scom.initfile"); + fapi2::current_err = l_rc; + goto fapi_try_exit; + } } + // ... but we do scominit PHY's with no DIMM. There are no attributes needed and we need + // to make sure we init the magic port. + FAPI_INF("phy scominit for %s", mss::c_str(l_mca_target)); FAPI_EXEC_HWP(l_rc, p9_ddrphy_scom, l_mca_target); if (l_rc) @@ -108,4 +115,3 @@ fapi_try_exit: FAPI_INF("End MSS SCOM init"); return fapi2::current_err; } - |