summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBrian Silver <bsilver@us.ibm.com>2016-10-25 06:24:35 -0500
committerChristian R. Geddes <crgeddes@us.ibm.com>2016-10-31 10:36:59 -0400
commit0cb19a22319130ec4ebeb64ee87a47328297486e (patch)
tree23678cca2772e2d23043dd3b49f3aaf008b10baf /src
parentc7cf0b2d56200537be4227b246fa5c4754cc7306 (diff)
downloadtalos-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')
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/phy/ddr_phy.C18
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/phy/dp16.C3
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/utils/find.H102
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/p9_mss_scominit.C36
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;
}
-
OpenPOWER on IntegriCloud