summaryrefslogtreecommitdiffstats
path: root/src/import/chips/p9/procedures/hwp/memory
diff options
context:
space:
mode:
authorJacob Harvey <jlharvey@us.ibm.com>2017-09-19 09:57:54 -0500
committerDaniel M. Crowell <dcrowell@us.ibm.com>2017-09-26 17:08:55 -0400
commit7f59b42ea81b713c5e3c0cbeed38bd8858aa3ff6 (patch)
treeebd9218a76a6f078d5088b850850c161de093d5c /src/import/chips/p9/procedures/hwp/memory
parentad079f548f91b86b0526927ff32659e82349f895 (diff)
downloadtalos-hostboot-7f59b42ea81b713c5e3c0cbeed38bd8858aa3ff6.tar.gz
talos-hostboot-7f59b42ea81b713c5e3c0cbeed38bd8858aa3ff6.zip
Increment red_waterfall for low vdn fix
Change-Id: Iaa5dbf94fe223cdfef7ebbfe8598f98f5472c956 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/46420 Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Dev-Ready: JACOB L. HARVEY <jlharvey@us.ibm.com> Reviewed-by: Louis Stermole <stermole@us.ibm.com> Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Tested-by: HWSV CI <hwsv-ci+hostboot@us.ibm.com> Reviewed-by: STEPHEN GLANCY <sglancy@us.ibm.com> Tested-by: Hostboot CI <hostboot-ci+hostboot@us.ibm.com> Reviewed-by: Matt K. Light <mklight@us.ibm.com> Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com> Reviewed-by: Jennifer A. Stofer <stofer@us.ibm.com> Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/46455 Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com> Reviewed-by: JACOB L. HARVEY <jlharvey@us.ibm.com>
Diffstat (limited to 'src/import/chips/p9/procedures/hwp/memory')
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/mss_attribute_accessors_manual.H23
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/phy/ddr_phy.C36
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/phy/dp16.H42
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/shared/mss_const.H2
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/workarounds/dp16_workarounds.C101
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/workarounds/dp16_workarounds.H45
6 files changed, 242 insertions, 7 deletions
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/mss_attribute_accessors_manual.H b/src/import/chips/p9/procedures/hwp/memory/lib/mss_attribute_accessors_manual.H
index 89a37afeb..e1a0a31fd 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/mss_attribute_accessors_manual.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/mss_attribute_accessors_manual.H
@@ -283,6 +283,29 @@ fapi_try_exit:
}
///
+/// @brief ATTR_CHIP_EC_FEATURE_MSS_RED_WATERFALL_ADJUST getter
+/// @tparam T the fapi2 target type of the target
+/// @param[in] const ref to the target
+/// @return bool true iff feature is enabled
+///
+template< fapi2::TargetType T >
+inline bool chip_ec_feature_red_waterfall_adjust(const fapi2::Target<T>& i_target)
+{
+ const auto l_chip = mss::find_target<fapi2::TARGET_TYPE_PROC_CHIP>(i_target);
+ uint8_t l_value = 0;
+
+ FAPI_TRY( FAPI_ATTR_GET(fapi2::ATTR_CHIP_EC_FEATURE_MSS_RED_WATERFALL_ADJUST, l_chip, l_value) );
+
+ return (l_value != 0);
+
+fapi_try_exit:
+ FAPI_ERR("failed accessing ATTR_CHIP_EC_FEATURE_MSS_RED_WATERFALL_ADJUST: 0x%lx (target: %s)",
+ uint64_t(fapi2::current_err), mss::c_str(i_target));
+ fapi2::Assert(false);
+ return false;
+}
+
+///
/// @brief ATTR_CHIP_EC_FEATURE_MSS_ENABLE_HW_VREF_CAL getter
/// @tparam T the fapi2 target type of the target
/// @param[in] const ref to the target
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 05286dcfa..86a8621fa 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
@@ -1284,8 +1284,8 @@ fapi2::ReturnCode setup_and_execute_cal( const fapi2::Target<fapi2::TARGET_TYPE_
"%s Failed to run dqs align workaround on rp %d", mss::c_str(i_target), i_rp);
}
- // Run cal steps between RDCLK_ALIGN and RD_CTR if any are selected - note RDCLK_ALIGN takes place after WR_LEVEL
- if (i_cal_steps_enabled.getBit<mss::cal_steps::RDCLK_ALIGN, mss::cal_steps::RDCLK_ALIGN_TO_RD_CTR_LEN>())
+ // Run cal step READ CLOCK ALIGN
+ if (i_cal_steps_enabled.getBit<mss::cal_steps::RDCLK_ALIGN>())
{
// Turn off refresh
FAPI_TRY( mss::workarounds::dqs_align::turn_off_refresh(i_target) );
@@ -1293,11 +1293,35 @@ fapi2::ReturnCode setup_and_execute_cal( const fapi2::Target<fapi2::TARGET_TYPE_
// Sets up the cal steps in the buffer
fapi2::buffer<uint32_t> l_steps_to_execute;
- i_cal_steps_enabled.extract<mss::cal_steps::RDCLK_ALIGN,
- mss::cal_steps::RDCLK_ALIGN_TO_RD_CTR_LEN,
- mss::cal_steps::RDCLK_ALIGN>(l_steps_to_execute);
+ l_steps_to_execute.setBit<mss::cal_steps::RDCLK_ALIGN>();
- FAPI_INF("%s Running rd_clk align through read centering vref on RP%d 0x%08x", mss::c_str(i_target), i_rp,
+ FAPI_INF("%s Running rd_clk align on RP%d 0x%08x", mss::c_str(i_target), i_rp,
+ l_steps_to_execute);
+
+ // Undertake the calibration steps
+ FAPI_TRY( execute_cal_steps_helper(i_target, i_rp, l_steps_to_execute, i_abort_on_error) );
+
+ // Run the red_waterfall workaround for low VDN sensitivity
+ // Increments the waterfall forward by one
+ FAPI_TRY( mss::workarounds::dp16::fix_red_waterfall_gate( i_target, i_rp) );
+
+ // Turn refresh back on
+ FAPI_TRY( mss::workarounds::dqs_align::turn_on_refresh(i_target) );
+ }
+
+ if(i_cal_steps_enabled.getBit<mss::cal_steps::READ_CTR_2D_VREF, mss::cal_steps::READ_VREF_TO_READ_CTR_LEN>())
+ {
+ // Turn off refresh
+ FAPI_TRY( mss::workarounds::dqs_align::turn_off_refresh(i_target) );
+
+ // Sets up the cal steps in the buffer
+ fapi2::buffer<uint32_t> l_steps_to_execute;
+
+ l_steps_to_execute.writeBit<mss::cal_steps::READ_CTR_2D_VREF>
+ (i_cal_steps_enabled.getBit<mss::cal_steps::READ_CTR_2D_VREF>());
+ l_steps_to_execute.writeBit<mss::cal_steps::READ_CTR>(i_cal_steps_enabled.getBit<mss::cal_steps::READ_CTR>());
+
+ FAPI_INF("%s Running read centering vref through read centering on RP%d 0x%08x", mss::c_str(i_target), i_rp,
l_steps_to_execute);
// Undertake the calibration steps
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 7f79078d3..322310162 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
@@ -223,6 +223,14 @@ class dp16Traits<fapi2::TARGET_TYPE_MCA>
MCA_DDRPHY_DP16_DQS_RD_PHASE_SELECT_RANK_PAIR0_P0_0_01_RDCLK_SELECT3,
};
+ constexpr static const uint64_t RED_WATERFALL_BIT_POS[NUM_QUAD_PER_DP16] =
+ {
+ MCA_DDRPHY_DP16_DQS_RD_PHASE_SELECT_RANK_PAIR0_P0_0_01_DQSCLK_SELECT0,
+ MCA_DDRPHY_DP16_DQS_RD_PHASE_SELECT_RANK_PAIR0_P0_0_01_DQSCLK_SELECT1,
+ MCA_DDRPHY_DP16_DQS_RD_PHASE_SELECT_RANK_PAIR0_P0_0_01_DQSCLK_SELECT2,
+ MCA_DDRPHY_DP16_DQS_RD_PHASE_SELECT_RANK_PAIR0_P0_0_01_DQSCLK_SELECT3,
+ };
+
// READ_DELAY registers, indexed by rank_pair
static const std::vector< std::vector< uint64_t > > READ_DELAY_REG;
@@ -2071,6 +2079,24 @@ inline uint64_t get_blue_waterfall( const fapi2::buffer<uint64_t>& i_data )
}
///
+/// @brief Get the red waterfall for the given quad
+/// @tparam uint64_t QUAD - which quad to access
+/// @tparam T fapi2 Target Type - defaults to TARGET_TYPE_MCA
+/// @tparam TT traits type defaults to dp16Traits<T>
+/// @param[in] i_data the value of the register
+/// @return value of the red waterfall
+///
+template< uint64_t QUAD, fapi2::TargetType T = fapi2::TARGET_TYPE_MCA, typename TT = dp16Traits<T> >
+inline uint64_t get_red_waterfall( const fapi2::buffer<uint64_t>& i_data )
+{
+
+ static_assert(QUAD < TT::NUM_QUAD_PER_DP16, "Inserted quad value is not less than the maximum value");
+ uint64_t l_waterfall = 0;
+ i_data.extractToRight<TT::RED_WATERFALL_BIT_POS[QUAD], TT::WATERFALL_LEN>(l_waterfall);
+ return l_waterfall;
+}
+
+///
/// @brief Get the gate delay for the given quad
/// @tparam uint64_t QUAD - which quad to access
/// @tparam T fapi2 Target Type - defaults to TARGET_TYPE_MCA
@@ -2105,6 +2131,22 @@ inline void set_blue_waterfall( fapi2::buffer<uint64_t>& io_data, const uint64_t
}
///
+/// @brief Set the red waterfall for the given quad
+/// @tparam uint64_t QUAD - which quad to access
+/// @tparam T fapi2 Target Type - defaults to TARGET_TYPE_MCA
+/// @tparam TT traits type defaults to dp16Traits<T>
+/// @param[in,out] io_data the value of the register
+/// @param[in] value of the red waterfall
+///
+template< uint64_t QUAD, fapi2::TargetType T = fapi2::TARGET_TYPE_MCA, typename TT = dp16Traits<T> >
+inline void set_red_waterfall( fapi2::buffer<uint64_t>& io_data, const uint64_t i_waterfall )
+{
+
+ static_assert(QUAD < TT::NUM_QUAD_PER_DP16, "QUAD value is not less than the maximum value");
+ io_data.insertFromRight<TT::RED_WATERFALL_BIT_POS[QUAD], TT::WATERFALL_LEN>(i_waterfall);
+}
+
+///
/// @brief Set the gate delay for the given quad
/// @tparam uint64_t QUAD - which quad to access
/// @tparam T fapi2 Target Type - defaults to TARGET_TYPE_MCA
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/shared/mss_const.H b/src/import/chips/p9/procedures/hwp/memory/lib/shared/mss_const.H
index 47e36b170..cf6a871e5 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/shared/mss_const.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/shared/mss_const.H
@@ -232,7 +232,7 @@ enum cal_steps : uint64_t
INITIAL_PAT_WR_TO_RD_CTR_LEN = inclusive_range(INITIAL_PAT_WR, READ_CTR),
WR_VREF_TO_COARSE_RD_LEN = inclusive_range(WRITE_CTR_2D_VREF, COARSE_RD),
- RDCLK_ALIGN_TO_RD_CTR_LEN = inclusive_range(RDCLK_ALIGN, READ_CTR),
+ READ_VREF_TO_READ_CTR_LEN = inclusive_range(READ_CTR_2D_VREF, READ_CTR),
// In this case, we just want to clear everything prior to WR 2D VREF, inclusive range also kills the WR VREF bit
DRAM_ZQCAL_UP_TO_WRITE_CTR_2D_VREF = WRITE_CTR_2D_VREF,
};
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/dp16_workarounds.C b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/dp16_workarounds.C
index ddd73faed..95dbe26f8 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/dp16_workarounds.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/dp16_workarounds.C
@@ -298,6 +298,107 @@ fapi_try_exit:
}
///
+/// @brief Fixes red waterfall values in a port
+/// @param[in] i_target - the target to operate on
+/// @param[in] i_rp - the rank pair to change
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+fapi2::ReturnCode fix_red_waterfall_gate( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target, const uint64_t i_rp)
+{
+ // Checks if the workaround needs to be run
+ const bool l_attr_value = mss::chip_ec_feature_red_waterfall_adjust(i_target);
+
+ if(!l_attr_value)
+ {
+ FAPI_DBG("Skipping running fix_red_waterfall_gate %s", mss::c_str(i_target) );
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
+
+ // Loops through the first 4 DP's as the last DP is a DP08 so we only need to do 2 quads
+ const std::vector<std::vector<uint64_t>> l_dp16_registers =
+ {
+ {
+ {MCA_DDRPHY_DP16_DQS_RD_PHASE_SELECT_RANK_PAIR0_P0_0},
+ {MCA_DDRPHY_DP16_DQS_RD_PHASE_SELECT_RANK_PAIR0_P0_1},
+ {MCA_DDRPHY_DP16_DQS_RD_PHASE_SELECT_RANK_PAIR0_P0_2},
+ {MCA_DDRPHY_DP16_DQS_RD_PHASE_SELECT_RANK_PAIR0_P0_3},
+ },
+ {
+ {MCA_DDRPHY_DP16_DQS_RD_PHASE_SELECT_RANK_PAIR1_P0_0},
+ {MCA_DDRPHY_DP16_DQS_RD_PHASE_SELECT_RANK_PAIR1_P0_1},
+ {MCA_DDRPHY_DP16_DQS_RD_PHASE_SELECT_RANK_PAIR1_P0_2},
+ {MCA_DDRPHY_DP16_DQS_RD_PHASE_SELECT_RANK_PAIR1_P0_3},
+ },
+ {
+ {MCA_DDRPHY_DP16_DQS_RD_PHASE_SELECT_RANK_PAIR2_P0_0},
+ {MCA_DDRPHY_DP16_DQS_RD_PHASE_SELECT_RANK_PAIR2_P0_1},
+ {MCA_DDRPHY_DP16_DQS_RD_PHASE_SELECT_RANK_PAIR2_P0_2},
+ {MCA_DDRPHY_DP16_DQS_RD_PHASE_SELECT_RANK_PAIR2_P0_3},
+ },
+ {
+ {MCA_DDRPHY_DP16_DQS_RD_PHASE_SELECT_RANK_PAIR3_P0_0},
+ {MCA_DDRPHY_DP16_DQS_RD_PHASE_SELECT_RANK_PAIR3_P0_1},
+ {MCA_DDRPHY_DP16_DQS_RD_PHASE_SELECT_RANK_PAIR3_P0_2},
+ {MCA_DDRPHY_DP16_DQS_RD_PHASE_SELECT_RANK_PAIR3_P0_3},
+ }
+ };
+ const std::vector<uint64_t> l_dp08_registers =
+ {
+ {MCA_DDRPHY_DP16_DQS_RD_PHASE_SELECT_RANK_PAIR0_P0_4},
+ {MCA_DDRPHY_DP16_DQS_RD_PHASE_SELECT_RANK_PAIR1_P0_4},
+ {MCA_DDRPHY_DP16_DQS_RD_PHASE_SELECT_RANK_PAIR2_P0_4},
+ {MCA_DDRPHY_DP16_DQS_RD_PHASE_SELECT_RANK_PAIR3_P0_4},
+ };
+
+ // Gets the number of primary ranks to loop through
+ std::vector<uint64_t> l_rank_pairs;
+ FAPI_TRY(mss::rank::get_rank_pairs(i_target, l_rank_pairs));
+
+ FAPI_INF("Changing red waterfalls for %s", mss::c_str(i_target));
+
+ // Loops through all DP16s
+ for(const auto& l_reg : l_dp16_registers[i_rp])
+ {
+ fapi2::buffer<uint64_t> l_waterfall;
+
+ // Getscoms
+ FAPI_TRY(mss::getScom(i_target, l_reg, l_waterfall), "%s Failed to getScom from 0x%016lx",
+ mss::c_str(i_target), l_reg);
+
+ // Updates the data for all quads
+ update_red_waterfall_for_quad<0>(l_waterfall);
+ update_red_waterfall_for_quad<1>(l_waterfall);
+ update_red_waterfall_for_quad<2>(l_waterfall);
+ update_red_waterfall_for_quad<3>(l_waterfall);
+
+ // Putscoms
+ FAPI_TRY(mss::putScom(i_target, l_reg, l_waterfall), "%s Failed to putScom to 0x%016lx",
+ mss::c_str(i_target), l_reg);
+ }
+
+ // Now for the odd man out - the DP08, as it only has two quads.
+ // Note: We are not modifying the non-existant quads, as changing values in the non-existant DP08 has caused FIRs
+ {
+ fapi2::buffer<uint64_t> l_waterfall;
+
+ // Getscoms
+ FAPI_TRY(mss::getScom(i_target, l_dp08_registers[i_rp], l_waterfall), "%s Failed to getScom from 0x%016lx",
+ mss::c_str(i_target), l_dp08_registers[i_rp]);
+
+ // Updates the data for all quads
+ update_red_waterfall_for_quad<0>(l_waterfall);
+ update_red_waterfall_for_quad<1>(l_waterfall);
+
+ // Putscoms
+ FAPI_TRY(mss::putScom(i_target, l_dp08_registers[i_rp], l_waterfall), "%s Failed to putScom to 0x%016lx",
+ mss::c_str(i_target), l_dp08_registers[i_rp]);
+ }
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
/// @brief Fixes blue waterfall values in a port
/// @param[in] i_target - the target to operate on
/// @param[in] i_always_run - ignores the attribute and always run - default = false
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/dp16_workarounds.H b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/dp16_workarounds.H
index 8fdb47f5c..2c9d3872d 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/dp16_workarounds.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/workarounds/dp16_workarounds.H
@@ -197,6 +197,51 @@ fapi2::ReturnCode fix_blue_waterfall_gate( const fapi2::Target<fapi2::TARGET_TYP
const bool i_always_run = false );
///
+/// @brief Fixes red waterfall values in a port
+/// @param[in] i_target - the target to operate on
+/// @param[in] i_rp, the rank pair that's being trained
+/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
+///
+fapi2::ReturnCode fix_red_waterfall_gate( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target, const uint64_t i_rp);
+
+
+///
+/// @brief Moves the red waterfall forward by one
+/// @param[in,out] io_red_waterfall - the red waterfall value
+///
+inline void update_red_waterfall(uint64_t& io_red_waterfall)
+{
+ constexpr uint64_t MAX_RED_WATERFALL_VALUE = 4;
+
+ if (++io_red_waterfall >= MAX_RED_WATERFALL_VALUE)
+ {
+ io_red_waterfall = 0;
+ }
+}
+
+///
+/// @brief Gets the red waterfall and gate delay values for a given DP quad
+/// @tparam uint64_t QUAD - which quad to access
+/// @param[in,out] io_waterfall_reg - waterfall register data
+///
+template< uint64_t QUAD>
+void update_red_waterfall_for_quad(fapi2::buffer<uint64_t>& io_waterfall_reg)
+{
+ constexpr uint64_t NUM_QUAD = 4;
+ // Valid quad values are from 0-3, exit if the requested value is greater
+ static_assert(QUAD < NUM_QUAD, "Inserted quad value is greater than or equal to 4");
+
+ // Gets the data for this Quad
+ auto l_red_waterfall = mss::dp16::get_red_waterfall<QUAD>(io_waterfall_reg);
+
+ // Updates the waterfall and gate delay
+ update_red_waterfall(l_red_waterfall);
+
+ // Sets the data back into the register
+ mss::dp16::set_red_waterfall<QUAD>(io_waterfall_reg, l_red_waterfall);
+}
+
+///
/// @brief Modifies HW calibration results based upon workarounds
/// @param[in] i_target - the target to operate on
/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
OpenPOWER on IntegriCloud