summaryrefslogtreecommitdiffstats
path: root/src/import/chips/p9
diff options
context:
space:
mode:
authorLouis Stermole <stermole@us.ibm.com>2016-08-04 12:43:48 -0500
committerWilliam G. Hoffa <wghoffa@us.ibm.com>2016-08-22 11:47:44 -0400
commit67717a4f64e8cb1728fe2d2d8890394d575d02c2 (patch)
tree26f96d8b2550a8a52ed9b020d1707b79eca20a62 /src/import/chips/p9
parent48f839b9b7e30d1d96807e25cb71a35877eb1184 (diff)
downloadtalos-hostboot-67717a4f64e8cb1728fe2d2d8890394d575d02c2.tar.gz
talos-hostboot-67717a4f64e8cb1728fe2d2d8890394d575d02c2.zip
Adding initialization of PHY RD_VREF according to ATTR_MSS_VPD_MT_VREF_MC_RD
Change-Id: Ie25cff42202834185c796237de2b5dfd387b3c24 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/27997 Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Tested-by: Hostboot CI <hostboot-ci+hostboot@us.ibm.com> Reviewed-by: Brian R. Silver <bsilver@us.ibm.com> Reviewed-by: STEPHEN GLANCY <sglancy@us.ibm.com> Reviewed-by: JACOB L. HARVEY <jlharvey@us.ibm.com> Reviewed-by: Matt K. Light <mklight@us.ibm.com> Reviewed-by: William G. Hoffa <wghoffa@us.ibm.com> Reviewed-by: Jennifer A. Stofer <stofer@us.ibm.com> Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/28116 Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Diffstat (limited to 'src/import/chips/p9')
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/phy/ddr_phy.C3
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/phy/dp16.C112
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/phy/dp16.H50
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/utils/fake_vpd.C2
-rw-r--r--src/import/chips/p9/procedures/xml/attribute_info/memory_mt_attributes.xml2
-rw-r--r--src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_ddr_phy_reset.xml17
6 files changed, 184 insertions, 2 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 2173fd184..dcddc4313 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
@@ -664,6 +664,9 @@ fapi2::ReturnCode phy_scominit(const fapi2::Target<TARGET_TYPE_MCBIST>& i_target
FAPI_TRY( mss::dp16::reset_write_clock_enable(p, l_pairs) );
FAPI_TRY( mss::dp16::reset_read_clock_enable(p, l_pairs) );
+ // Reset Read VREF according to ATTR_MSS_VPD_MT_VREF_MC_RD value
+ FAPI_TRY( mss::dp16::reset_rd_vref(p) );
+
// Write Control reset
FAPI_TRY( mss::wc::reset(p) );
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 c725f5615..c7198d00c 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
@@ -210,6 +210,74 @@ const std::vector< std::pair<uint64_t, uint64_t> > dp16Traits<TARGET_TYPE_MCA>::
{ MCA_DDRPHY_DP16_CTLE_CTL_BYTE0_P0_4, MCA_DDRPHY_DP16_CTLE_CTL_BYTE1_P0_4 },
};
+// Definition of the DP16 RD_VREF Control registers
+// DP16 RD_VREF Control registers all come in pairs - one per 8 bits
+// 5 DP16 per MCA gives us 10 Registers.
+const std::vector< std::pair<uint64_t, uint64_t> > dp16Traits<TARGET_TYPE_MCA>::RD_VREF_CNTRL_REG =
+{
+ { MCA_DDRPHY_DP16_RD_VREF_BYTE0_DAC_P0_0, MCA_DDRPHY_DP16_RD_VREF_BYTE1_DAC_P0_0 },
+ { MCA_DDRPHY_DP16_RD_VREF_BYTE0_DAC_P0_1, MCA_DDRPHY_DP16_RD_VREF_BYTE1_DAC_P0_1 },
+ { MCA_DDRPHY_DP16_RD_VREF_BYTE0_DAC_P0_2, MCA_DDRPHY_DP16_RD_VREF_BYTE1_DAC_P0_2 },
+ { MCA_DDRPHY_DP16_RD_VREF_BYTE0_DAC_P0_3, MCA_DDRPHY_DP16_RD_VREF_BYTE1_DAC_P0_3 },
+ { MCA_DDRPHY_DP16_RD_VREF_BYTE0_DAC_P0_4, MCA_DDRPHY_DP16_RD_VREF_BYTE1_DAC_P0_4 },
+};
+
+///
+/// @brief Given a RD_VREF value, create a PHY 'standard' bit field for that percentage.
+/// @tparam T fapi2 Target Type - derived
+/// @tparam TT traits type defaults to dp16Traits<T>
+/// @param[in] i_target the fapi2 target of the port
+/// @param[in] i_vref the value from the mss_vpd_mt_vref_mc_rd attribute for your target
+/// @param[out] o_bitfield value of DAC bitfield for given VREF setting
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+template< fapi2::TargetType T, typename TT = dp16Traits<T> >
+fapi2::ReturnCode rd_vref_bitfield_helper( const fapi2::Target<T>& i_target,
+ const uint32_t i_vref,
+ uint64_t& o_bitfield )
+{
+ FAPI_INF("rd_vref_bitfield_helper for target %s seeing vref percentage: %d", c_str(i_target), i_vref);
+
+ // Zero is a special "no-op" value, which we can get if the VPD attributes aren't
+ // set up. This can happen for an MCA with no functional DIMM present.
+ if (i_vref == 0)
+ {
+ o_bitfield = 0;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+ else if ( (i_vref > TT::MAX_RD_VREF) || (i_vref < TT::MIN_RD_VREF) )
+ {
+ // Set up some constexprs to work around linker error when pushing traits values into ffdc
+ constexpr uint64_t l_max = TT::MAX_RD_VREF;
+ constexpr uint64_t l_min = TT::MIN_RD_VREF;
+
+ FAPI_ASSERT( false,
+ fapi2::MSS_INVALID_VPD_MT_VREF_MC_RD()
+ .set_VALUE(i_vref)
+ .set_VREF_MAX(l_max)
+ .set_VREF_MIN(l_min)
+ .set_TARGET(i_target),
+ "Target %s VPD_MT_VREF_MC_RD percentage out of bounds (%d - %d): %d",
+ c_str(i_target),
+ TT::MAX_RD_VREF,
+ TT::MIN_RD_VREF,
+ i_vref );
+ }
+ else
+ {
+ // Per R. King, VREF equation is:
+ // Vref = 1.1025 for DAC < 15
+ // Vref = 1.2 - .0065 * DAC for DAC >= 15
+ // where DAC is simply the 7-bit field value
+ // note values multiplied by 10 to make everything an integer
+ o_bitfield = TT::RD_VREF_DVDD * (100000 - i_vref) / TT::RD_VREF_DAC_STEP;
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
namespace dp16
{
@@ -841,5 +909,49 @@ fapi_try_exit:
return fapi2::current_err;
}
+///
+/// @brief Configure Read VREF Registers
+/// @param[in] i_target a MCA target
+/// @return FAPI2_RC_SUCCESs iff ok
+///
+fapi2::ReturnCode reset_rd_vref( const fapi2::Target<TARGET_TYPE_MCA>& i_target )
+{
+ typedef dp16Traits<TARGET_TYPE_MCA> TT;
+
+ std::vector< std::pair<fapi2::buffer<uint64_t>, fapi2::buffer<uint64_t> > > l_data;
+ uint64_t l_vref_bitfield = 0;
+ uint8_t is_sim = 0;
+ uint32_t l_vref = 0;
+
+ FAPI_TRY( mss::vpd_mt_vref_mc_rd(i_target, l_vref) );
+
+ FAPI_TRY( rd_vref_bitfield_helper(i_target, l_vref, l_vref_bitfield) );
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_IS_SIMULATION, fapi2::Target<TARGET_TYPE_SYSTEM>(), is_sim) );
+
+ // Leave the values as-is if we're on VBU or Awan, since we know that works. Use the real value for unit test and HW
+ if (!is_sim)
+ {
+ // Do a read/modify/write
+ FAPI_TRY( mss::scom_suckah(i_target, TT::RD_VREF_CNTRL_REG, l_data) );
+
+ for (auto& l_regpair : l_data)
+ {
+ // Write the same value for all the DQ and DQS nibbles
+ l_regpair.first.insertFromRight<TT::RD_VREF_BYTE0_NIB0, TT::RD_VREF_BYTE0_NIB0_LEN>(l_vref_bitfield);
+ l_regpair.first.insertFromRight<TT::RD_VREF_BYTE0_NIB1, TT::RD_VREF_BYTE0_NIB1_LEN>(l_vref_bitfield);
+ l_regpair.second.insertFromRight<TT::RD_VREF_BYTE1_NIB2, TT::RD_VREF_BYTE1_NIB2_LEN>(l_vref_bitfield);
+ l_regpair.second.insertFromRight<TT::RD_VREF_BYTE1_NIB3, TT::RD_VREF_BYTE1_NIB3_LEN>(l_vref_bitfield);
+ }
+
+ FAPI_INF("blasting VREF settings from VPD to dp16 RD_VREF byte0 and byte1");
+
+ FAPI_TRY( mss::scom_blastah(i_target, TT::RD_VREF_CNTRL_REG, l_data) );
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
} // close namespace dp16
} // close namespace mss
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/phy/dp16.H b/src/import/chips/p9/procedures/hwp/memory/lib/phy/dp16.H
index 33a9f3c4c..b2c7b98c6 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/phy/dp16.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/phy/dp16.H
@@ -123,6 +123,15 @@ class dp16Traits<fapi2::TARGET_TYPE_MCA>
// any of this for some time.
static constexpr uint64_t DLL_PER_DP16 = 2;
+ // Maximum and minimum RD_VREF percentage of VDD. We only test against max and min because
+ // there are so many allowable values.
+ static constexpr uint64_t MAX_RD_VREF = fapi2::ENUM_ATTR_MSS_VPD_MT_VREF_MC_RD_VDD91875;
+ static constexpr uint64_t MIN_RD_VREF = fapi2::ENUM_ATTR_MSS_VPD_MT_VREF_MC_RD_VDD31208;
+
+ // Constants used for converting RD_VREF percentage to DAC settings, normalized to integers
+ static constexpr uint64_t RD_VREF_DVDD = 12;
+ static constexpr uint64_t RD_VREF_DAC_STEP = 6500;
+
// Vectors of DP16 registers. The pair represents the two DLL in per DP16
static const std::vector< std::pair<uint64_t, uint64_t> > DLL_CNFG_REG;
static const std::vector< std::pair<uint64_t, uint64_t> > DLL_DAC_LOWER_REG;
@@ -137,6 +146,7 @@ class dp16Traits<fapi2::TARGET_TYPE_MCA>
static const std::vector< std::pair<uint64_t, uint64_t> > AC_BOOST_CNTRL_REG;
static const std::vector< std::pair<uint64_t, uint64_t> > CTLE_CNTRL_REG;
+ static const std::vector< std::pair<uint64_t, uint64_t> > RD_VREF_CNTRL_REG;
static const std::vector< uint64_t > DATA_BIT_DIR1;
enum
@@ -161,9 +171,32 @@ class dp16Traits<fapi2::TARGET_TYPE_MCA>
CTLE_ODD_CAP_LEN = MCA_DDRPHY_DP16_CTLE_CTL_BYTE0_P0_0_01_NIB_1_3_DQSEL_CAP_LEN,
CTLE_ODD_RES = MCA_DDRPHY_DP16_CTLE_CTL_BYTE0_P0_0_01_NIB_1_3_DQSEL_RES,
CTLE_ODD_RES_LEN = MCA_DDRPHY_DP16_CTLE_CTL_BYTE0_P0_0_01_NIB_1_3_DQSEL_RES_LEN,
+
+ RD_VREF_BYTE0_NIB0 = MCA_DDRPHY_DP16_RD_VREF_BYTE0_DAC_P0_0_01_NIB0,
+ RD_VREF_BYTE0_NIB0_LEN = MCA_DDRPHY_DP16_RD_VREF_BYTE0_DAC_P0_0_01_NIB0_LEN,
+ RD_VREF_BYTE0_NIB1 = MCA_DDRPHY_DP16_RD_VREF_BYTE0_DAC_P0_0_01_NIB1,
+ RD_VREF_BYTE0_NIB1_LEN = MCA_DDRPHY_DP16_RD_VREF_BYTE0_DAC_P0_0_01_NIB1_LEN,
+ RD_VREF_BYTE1_NIB2 = MCA_DDRPHY_DP16_RD_VREF_BYTE1_DAC_P0_0_01_NIB2,
+ RD_VREF_BYTE1_NIB2_LEN = MCA_DDRPHY_DP16_RD_VREF_BYTE1_DAC_P0_0_01_NIB2_LEN,
+ RD_VREF_BYTE1_NIB3 = MCA_DDRPHY_DP16_RD_VREF_BYTE1_DAC_P0_0_01_NIB3,
+ RD_VREF_BYTE1_NIB3_LEN = MCA_DDRPHY_DP16_RD_VREF_BYTE1_DAC_P0_0_01_NIB3_LEN,
};
};
+///
+/// @brief Given a RD_VREF value, create a PHY 'standard' bit field for that percentage.
+/// @tparam T fapi2 Target Type - derived
+/// @tparam TT traits type defaults to dp16Traits<T>
+/// @param[in] i_target the fapi2 target of the port
+/// @param[in] i_vref the value from the mss_vpd_mt_vref_mc_rd attribute for your target
+/// @param[out] o_bitfield value of DAC bitfield for given VREF setting
+/// @return FAPI2_RC_SUCCESS iff ok
+///
+template< fapi2::TargetType T, typename TT = dp16Traits<T> >
+fapi2::ReturnCode rd_vref_bitfield_helper( const fapi2::Target<T>& i_target,
+ const uint32_t i_vref,
+ uint64_t& o_bitfield );
+
namespace dp16
{
@@ -528,6 +561,16 @@ template< fapi2::TargetType T, typename TT = dp16Traits<T> >
fapi2::ReturnCode reset_dll_vreg_config1( const fapi2::Target<T>& i_target );
///
+/// @brief Configure Read VREF Registers
+/// @tparam T the fapi2::TargetType
+/// @tparam TT the target traits
+/// @param[in] i_target a fapi2 target
+/// @return FAPI2_RC_SUCCESs iff ok
+///
+template< fapi2::TargetType T, typename TT = dp16Traits<T> >
+fapi2::ReturnCode reset_rd_vref( const fapi2::Target<T>& i_target );
+
+///
/// Specializations
///
@@ -598,6 +641,13 @@ fapi2::ReturnCode reset_io_tx_config0( const fapi2::Target<fapi2::TARGET_TYPE_MC
///
fapi2::ReturnCode reset_dll_vreg_config1( const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_target );
+///
+/// @brief Configure Read VREF Registers
+/// @param[in] i_target a MCA target
+/// @return FAPI2_RC_SUCCESs iff ok
+///
+fapi2::ReturnCode reset_rd_vref( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target );
+
} // close namespace dp16
} // close namespace mss
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/utils/fake_vpd.C b/src/import/chips/p9/procedures/hwp/memory/lib/utils/fake_vpd.C
index dea9d53b3..5c9982d38 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/utils/fake_vpd.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/utils/fake_vpd.C
@@ -57,7 +57,7 @@ static constexpr uint8_t raw_mt[raw_mt_size] =
0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x16, 0x16, 0x00, 0x01,
- 0x31, 0xaa, 0x00, 0x01, 0x31, 0xaa, 0x80, 0x23, 0x80, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x31, 0xfd, 0x00, 0x01, 0x31, 0xfd, 0x80, 0x23, 0x80, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
diff --git a/src/import/chips/p9/procedures/xml/attribute_info/memory_mt_attributes.xml b/src/import/chips/p9/procedures/xml/attribute_info/memory_mt_attributes.xml
index ef47f5998..504232604 100644
--- a/src/import/chips/p9/procedures/xml/attribute_info/memory_mt_attributes.xml
+++ b/src/import/chips/p9/procedures/xml/attribute_info/memory_mt_attributes.xml
@@ -505,7 +505,7 @@
<initToZero></initToZero>
<valueType>uint32</valueType>
<writeable/>
- <enum>VDD40375 = 40375, VDD41750 = 41750, VDD43125 = 43125, VDD44500 = 44500, VDD45875 = 45875, VDD47250 = 47250, VDD48625 = 48625, VDD50000 = 50000, VDD51375 = 51375, VDD52750 = 52750, VDD54125 = 54125, VDD55500 = 55500, VDD56875 = 56875, VDD58250 = 58250, VDD59625 = 59625, VDD61000 = 61000, VDD60375 = 60375, VDD61750 = 61750, VDD63125 = 63125, VDD64500 = 64500, VDD65875 = 65875, VDD67250 = 67250, VDD68625 = 68625, VDD70000 = 70000, VDD71375 = 71375, VDD72750 = 72750, VDD74125 = 74125, VDD75500 = 75500, VDD76875 = 76875, VDD78250 = 78250, VDD79625 = 79625, VDD81000 = 81000</enum>
+ <enum>VDD91875 = 91875, VDD91333 = 91333, VDD90791 = 90791, VDD90250 = 90250, VDD89708 = 89708, VDD89166 = 89166, VDD88625 = 88625, VDD88083 = 88083, VDD87541 = 87541, VDD87000 = 87000, VDD86458 = 86458, VDD85916 = 85916, VDD85375 = 85375, VDD84833 = 84833, VDD84291 = 84291, VDD83750 = 83750, VDD83208 = 83208, VDD82666 = 82666, VDD82125 = 82125, VDD81583 = 81583, VDD81041 = 81041, VDD80500 = 80500, VDD79958 = 79958, VDD79416 = 79416, VDD78875 = 78875, VDD78333 = 78333, VDD77791 = 77791, VDD77250 = 77250, VDD76708 = 76708, VDD76166 = 76166, VDD75625 = 75625, VDD75083 = 75083, VDD74541 = 74541, VDD74000 = 74000, VDD73458 = 73458, VDD72916 = 72916, VDD72375 = 72375, VDD71833 = 71833, VDD71291 = 71291, VDD70750 = 70750, VDD70208 = 70208, VDD69666 = 69666, VDD69125 = 69125, VDD68583 = 68583, VDD68041 = 68041, VDD67500 = 67500, VDD66958 = 66958, VDD66416 = 66416, VDD65875 = 65875, VDD65333 = 65333, VDD64791 = 64791, VDD64250 = 64250, VDD63708 = 63708, VDD63166 = 63166, VDD62625 = 62625, VDD62083 = 62083, VDD61541 = 61541, VDD61000 = 61000, VDD60458 = 60458, VDD59916 = 59916, VDD59375 = 59375, VDD58833 = 58833, VDD58291 = 58291, VDD57750 = 57750, VDD57208 = 57208, VDD56666 = 56666, VDD56125 = 56125, VDD55583 = 55583, VDD55041 = 55041, VDD54500 = 54500, VDD53958 = 53958, VDD53416 = 53416, VDD52875 = 52875, VDD52333 = 52333, VDD51791 = 51791, VDD51250 = 51250, VDD50708 = 50708, VDD50166 = 50166, VDD49625 = 49625, VDD49083 = 49083, VDD48541 = 48541, VDD48000 = 48000, VDD47458 = 47458, VDD46916 = 46916, VDD46375 = 46375, VDD45833 = 45833, VDD45291 = 45291, VDD44750 = 44750, VDD44208 = 44208, VDD43666 = 43666, VDD43125 = 43125, VDD42583 = 42583, VDD42041 = 42041, VDD41500 = 41500, VDD40958 = 40958, VDD40416 = 40416, VDD39875 = 39875, VDD39333 = 39333, VDD38791 = 38791, VDD38250 = 38250, VDD37708 = 37708, VDD37166 = 37166, VDD36625 = 36625, VDD36083 = 36083, VDD35541 = 35541, VDD35000 = 35000, VDD34458 = 34458, VDD33916 = 33916, VDD33375 = 33375, VDD32833 = 32833, VDD32291 = 32291, VDD31750 = 31750, VDD31208 = 31208</enum>
<mssUnits>percent of Vdd</mssUnits>
<mssBlobStart>206</mssBlobStart>
<mssBlobLength>8</mssBlobLength>
diff --git a/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_ddr_phy_reset.xml b/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_ddr_phy_reset.xml
index bff73626e..3578720a5 100644
--- a/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_ddr_phy_reset.xml
+++ b/src/import/chips/p9/procedures/xml/error_info/p9_memory_mss_ddr_phy_reset.xml
@@ -356,4 +356,21 @@
</gard>
</hwpError>
+<hwpError>
+ <rc>RC_MSS_INVALID_VPD_MT_VREF_MC_RD</rc>
+ <description>
+ Invalid MC RD_VREF value in VPD
+ </description>
+ <ffdc>VALUE</ffdc>
+ <ffdc>VREF_MAX</ffdc>
+ <ffdc>VREF_MIN</ffdc>
+ <callout>
+ <target>TARGET</target>
+ <priority>HIGH</priority>
+ </callout>
+ <deconfigure>
+ <target>TARGET</target>
+ </deconfigure>
+</hwpError>
+
</hwpErrors>
OpenPOWER on IntegriCloud