summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/ccs/ccs.C192
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/ccs/ccs.H308
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs_load_ddr4.H6
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/nvdimm_utils.C10
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/zqcal.C2
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/phy/mss_lrdimm_training.H3
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/shared/mss_const.H3
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit.C1
8 files changed, 338 insertions, 187 deletions
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/ccs/ccs.C b/src/import/chips/p9/procedures/hwp/memory/lib/ccs/ccs.C
index 2c937cd11..89e4be5ee 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/ccs/ccs.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/ccs/ccs.C
@@ -5,7 +5,7 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2018 */
+/* Contributors Listed Below - COPYRIGHT 2015,2019 */
/* [+] International Business Machines Corp. */
/* */
/* */
@@ -50,6 +50,57 @@ namespace ccs
{
///
+/// @brief Determines our rank configuration type across all ports
+/// @param[in] i_target the MCBIST target on which to operate
+/// @param[out] o_rank_config the rank configuration
+/// @return fapi2::ReturnCode fapi2::FAPI2_RC_SUCCESS if ok
+///
+fapi2::ReturnCode get_rank_config(const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_target,
+ std::vector<rank_configuration>& o_rank_config)
+{
+ o_rank_config.clear();
+ // Create one per port, we then use relative indexing to get us the number we need
+ o_rank_config = std::vector<rank_configuration>(PORTS_PER_MCBIST);
+
+ for(const auto& l_mca : mss::find_targets<fapi2::TARGET_TYPE_MCA>(i_target))
+ {
+ rank_configuration l_config;
+ FAPI_TRY(get_rank_config(l_mca, l_config));
+ o_rank_config[mss::relative_pos<fapi2::TARGET_TYPE_MCBIST>(l_mca)] = l_config;
+ }
+
+ return fapi2::FAPI2_RC_SUCCESS;
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Determines our rank configuration type
+/// @param[in] i_target the MCA target on which to operate
+/// @param[out] o_rank_config the rank configuration
+/// @return fapi2::ReturnCode fapi2::FAPI2_RC_SUCCESS if ok
+///
+fapi2::ReturnCode get_rank_config(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+ rank_configuration& o_rank_config)
+{
+ constexpr uint8_t QUAD_RANK_ENABLE = 4;
+ o_rank_config = rank_configuration::DUAL_DIRECT;
+
+ uint8_t l_num_master_ranks[MAX_DIMM_PER_PORT] = {};
+ FAPI_TRY(mss::eff_num_master_ranks_per_dimm(i_target, l_num_master_ranks));
+
+ // We only need to check DIMM0
+ // Our number of ranks should be the same between DIMM's 0/1
+ // Check if we have the right number for encoded mode
+ o_rank_config = l_num_master_ranks[0] == QUAD_RANK_ENABLE ?
+ rank_configuration::QUAD_ENCODED :
+ rank_configuration::DUAL_DIRECT;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
/// @brief Start or stop the CCS engine
/// @param[in] i_target The MCBIST containing the CCS engine
/// @param[in] i_start_stop bool MSS_CCS_START for starting, MSS_CCS_STOP otherwise
@@ -189,6 +240,9 @@ fapi2::ReturnCode execute( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target,
auto l_inst_iter = i_program.iv_instructions.begin();
+ std::vector<rank_configuration> l_rank_configs;
+ FAPI_TRY(get_rank_config(i_target, l_rank_configs));
+
// Stop the CCS engine just for giggles - it might be running ...
FAPI_TRY( start_stop(i_target, mss::states::STOP), "Error in ccs::execute" );
@@ -202,75 +256,81 @@ fapi2::ReturnCode execute( const fapi2::Target<TARGET_TYPE_MCBIST>& i_target,
while (l_inst_iter != i_program.iv_instructions.end())
{
- size_t l_inst_count = 0;
-
- uint64_t l_total_delay = 0;
- uint64_t l_delay = 0;
- uint64_t l_repeat = 0;
- uint8_t l_current_cke = 0;
-
- // Shove the instructions into the CCS engine, in 32 instruction chunks, and execute them
- for (; l_inst_iter != i_program.iv_instructions.end()
- && l_inst_count < CCS_INSTRUCTION_DEPTH; ++l_inst_count, ++l_inst_iter)
- {
- l_inst_iter->arr0.extractToRight<TT::ARR0_DDR_CKE, TT::ARR0_DDR_CKE_LEN>(l_current_cke);
-
- // Make sure this instruction leads to the next. Notice this limits this mechanism to pretty
- // simple (straight line) CCS programs. Anything with a loop or such will need another mechanism.
- l_inst_iter->arr1.insertFromRight<MCBIST_CCS_INST_ARR1_00_GOTO_CMD,
- MCBIST_CCS_INST_ARR1_00_GOTO_CMD_LEN>(l_inst_count + 1);
- FAPI_TRY( mss::putScom(i_target, CCS_ARR0_ZERO + l_inst_count, l_inst_iter->arr0), "Error in ccs::execute" );
- FAPI_TRY( mss::putScom(i_target, CCS_ARR1_ZERO + l_inst_count, l_inst_iter->arr1), "Error in ccs::execute" );
-
- // arr1 contains a specification of the delay and repeat after this instruction, as well
- // as a repeat. Total up the delays as we go so we know how long to wait before polling
- // the CCS engine for completion
- l_inst_iter->arr1.extractToRight<MCBIST_CCS_INST_ARR1_00_IDLES, MCBIST_CCS_INST_ARR1_00_IDLES_LEN>(l_delay);
- l_inst_iter->arr1.extractToRight<MCBIST_CCS_INST_ARR1_00_REPEAT_CMD_CNT,
- MCBIST_CCS_INST_ARR1_00_REPEAT_CMD_CNT>(l_repeat);
-
- l_total_delay += l_delay * (l_repeat + 1);
-
- FAPI_INF("css inst %d: 0x%016lX 0x%016lX (0x%lx, 0x%lx) delay: 0x%x (0x%x) %s",
- l_inst_count, l_inst_iter->arr0, l_inst_iter->arr1,
- CCS_ARR0_ZERO + l_inst_count, CCS_ARR1_ZERO + l_inst_count,
- l_delay, l_total_delay, mss::c_str(i_target));
- }
-
- // Check our program for any delays. If there isn't a iv_initial_delay configured, then
- // we use the delay we just summed from the instructions.
- if (i_program.iv_poll.iv_initial_delay == 0)
- {
- i_program.iv_poll.iv_initial_delay = cycles_to_ns(i_target, l_total_delay);
- }
-
- if (i_program.iv_poll.iv_initial_sim_delay == 0)
- {
- i_program.iv_poll.iv_initial_sim_delay = cycles_to_simcycles(l_total_delay);
- }
-
- FAPI_INF("executing ccs instructions (%d:%d, %d) for %s",
- i_program.iv_instructions.size(), l_inst_count, i_program.iv_poll.iv_initial_delay, mss::c_str(i_target));
-
- // Deselect
- l_des.arr0.insertFromRight<TT::ARR0_DDR_CKE, TT::ARR0_DDR_CKE_LEN>(l_current_cke);
-
- // Insert a DES as our last instruction. DES is idle state anyway and having this
- // here as an instruction forces the CCS engine to wait the delay specified in
- // the last instruction in this array (which it otherwise doesn't do.)
- l_des.arr1.setBit<MCBIST_CCS_INST_ARR1_00_END>();
- FAPI_TRY( mss::putScom(i_target, CCS_ARR0_ZERO + l_inst_count, l_des.arr0), "Error in ccs::execute" );
- FAPI_TRY( mss::putScom(i_target, CCS_ARR1_ZERO + l_inst_count, l_des.arr1), "Error in ccs::execute" );
-
- FAPI_INF("css inst %d fixup: 0x%016lX 0x%016lX (0x%lx, 0x%lx) %s",
- l_inst_count, l_des.arr0, l_des.arr1,
- CCS_ARR0_ZERO + l_inst_count, CCS_ARR1_ZERO + l_inst_count, mss::c_str(i_target));
// Kick off the CCS engine - per port. No broadcast mode for CCS (per Shelton 9/23/15)
for (const auto& p : i_ports)
{
- FAPI_INF("executing CCS array for port %d (%s)", mss::relative_pos<TARGET_TYPE_MCBIST>(p), mss::c_str(p));
- FAPI_TRY( select_ports( i_target, mss::relative_pos<TARGET_TYPE_MCBIST>(p)), "Error in ccs execute" );
+ const auto l_port_index = mss::relative_pos<TARGET_TYPE_MCBIST>(p);
+ size_t l_inst_count = 0;
+
+ uint64_t l_total_delay = 0;
+ uint64_t l_delay = 0;
+ uint64_t l_repeat = 0;
+ uint8_t l_current_cke = 0;
+
+ // Shove the instructions into the CCS engine, in 32 instruction chunks, and execute them
+ for (; l_inst_iter != i_program.iv_instructions.end()
+ && l_inst_count < CCS_INSTRUCTION_DEPTH; ++l_inst_count, ++l_inst_iter)
+ {
+ // First, update the current instruction's chip selects for the current port
+ FAPI_TRY(l_inst_iter->configure_rank(p, l_rank_configs[l_port_index]), "Error in rank config");
+
+ l_inst_iter->arr0.extractToRight<TT::ARR0_DDR_CKE, TT::ARR0_DDR_CKE_LEN>(l_current_cke);
+
+ // Make sure this instruction leads to the next. Notice this limits this mechanism to pretty
+ // simple (straight line) CCS programs. Anything with a loop or such will need another mechanism.
+ l_inst_iter->arr1.insertFromRight<MCBIST_CCS_INST_ARR1_00_GOTO_CMD,
+ MCBIST_CCS_INST_ARR1_00_GOTO_CMD_LEN>(l_inst_count + 1);
+ FAPI_TRY( mss::putScom(i_target, CCS_ARR0_ZERO + l_inst_count, l_inst_iter->arr0), "Error in ccs::execute" );
+ FAPI_TRY( mss::putScom(i_target, CCS_ARR1_ZERO + l_inst_count, l_inst_iter->arr1), "Error in ccs::execute" );
+
+ // arr1 contains a specification of the delay and repeat after this instruction, as well
+ // as a repeat. Total up the delays as we go so we know how long to wait before polling
+ // the CCS engine for completion
+ l_inst_iter->arr1.extractToRight<MCBIST_CCS_INST_ARR1_00_IDLES, MCBIST_CCS_INST_ARR1_00_IDLES_LEN>(l_delay);
+ l_inst_iter->arr1.extractToRight<MCBIST_CCS_INST_ARR1_00_REPEAT_CMD_CNT,
+ MCBIST_CCS_INST_ARR1_00_REPEAT_CMD_CNT>(l_repeat);
+
+ l_total_delay += l_delay * (l_repeat + 1);
+
+ FAPI_INF("css inst %d: 0x%016lX 0x%016lX (0x%lx, 0x%lx) delay: 0x%x (0x%x) %s",
+ l_inst_count, l_inst_iter->arr0, l_inst_iter->arr1,
+ CCS_ARR0_ZERO + l_inst_count, CCS_ARR1_ZERO + l_inst_count,
+ l_delay, l_total_delay, mss::c_str(i_target));
+ }
+
+ // Check our program for any delays. If there isn't a iv_initial_delay configured, then
+ // we use the delay we just summed from the instructions.
+ if (i_program.iv_poll.iv_initial_delay == 0)
+ {
+ i_program.iv_poll.iv_initial_delay = cycles_to_ns(i_target, l_total_delay);
+ }
+
+ if (i_program.iv_poll.iv_initial_sim_delay == 0)
+ {
+ i_program.iv_poll.iv_initial_sim_delay = cycles_to_simcycles(l_total_delay);
+ }
+
+ FAPI_INF("executing ccs instructions (%d:%d, %d) for %s",
+ i_program.iv_instructions.size(), l_inst_count, i_program.iv_poll.iv_initial_delay, mss::c_str(i_target));
+
+ // Deselect
+ l_des.arr0.insertFromRight<TT::ARR0_DDR_CKE, TT::ARR0_DDR_CKE_LEN>(l_current_cke);
+
+ // Insert a DES as our last instruction. DES is idle state anyway and having this
+ // here as an instruction forces the CCS engine to wait the delay specified in
+ // the last instruction in this array (which it otherwise doesn't do.)
+ l_des.arr1.setBit<MCBIST_CCS_INST_ARR1_00_END>();
+ FAPI_TRY( mss::putScom(i_target, CCS_ARR0_ZERO + l_inst_count, l_des.arr0), "Error in ccs::execute" );
+ FAPI_TRY( mss::putScom(i_target, CCS_ARR1_ZERO + l_inst_count, l_des.arr1), "Error in ccs::execute" );
+
+ FAPI_INF("css inst %d fixup: 0x%016lX 0x%016lX (0x%lx, 0x%lx) %s",
+ l_inst_count, l_des.arr0, l_des.arr1,
+ CCS_ARR0_ZERO + l_inst_count, CCS_ARR1_ZERO + l_inst_count, mss::c_str(i_target));
+
+
+ FAPI_INF("executing CCS array for port %d (%s)", l_port_index, mss::c_str(p));
+ FAPI_TRY( select_ports( i_target, l_port_index), "Error in ccs execute" );
FAPI_TRY( execute_inst_array(i_target, i_program, p), "Error in ccs execute" );
}
}
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/ccs/ccs.H b/src/import/chips/p9/procedures/hwp/memory/lib/ccs/ccs.H
index 606014ee7..923b84052 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/ccs/ccs.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/ccs/ccs.H
@@ -70,6 +70,7 @@ class ccsTraits<fapi2::TARGET_TYPE_MCBIST>
static constexpr uint64_t MCB_CNTL_REG = MCBIST_MCB_CNTLQ;
static constexpr uint64_t CNTLQ_REG = MCBIST_CCS_CNTLQ;
static constexpr uint64_t STATQ_REG = MCBIST_CCS_STATQ;
+ static constexpr fapi2::TargetType PORT_TARGET_TYPE = fapi2::TARGET_TYPE_MCA;
enum
{
@@ -216,6 +217,15 @@ static constexpr uint64_t CKE_ARY_SRX[] =
namespace ccs
{
+enum rank_configuration
+{
+ DUAL_DIRECT = 0,
+ QUAD_ENCODED = 1,
+ // Note: we don't include QUAD_DIRECT in here
+ // That's because it uses 4 CS and is board wiring dependent
+ // Not sure if it would use CS23 or CID01 for CS2/3
+};
+
///
/// @brief Enums for CCS return codes
///
@@ -245,98 +255,173 @@ class instruction_t
public:
fapi2::buffer<uint64_t> arr0;
fapi2::buffer<uint64_t> arr1;
+ // The MCA indexed rank on which to operate. If this is invalid, all ranks will be disabled
+ uint64_t iv_rank;
+ // We want to have a switch to update rank or not. A user might want to setup CS in some weird way
+ // In that case, they don't want us "fixing" their CS values
+ // We'll default the rank to be updated - we want to send out CS properly
+ bool iv_update_rank;
///
/// @brief intstruction_t ctor
- /// @param[in] i_target the DIMM this instruction is headed for
/// @param[in] i_rank the rank this instruction is headed for
/// @param[in] i_arr0 the initial value for arr0, defaults to 0
/// @param[in] i_arr1 the initial value for arr1, defaults to 0
+ /// @param[in] i_update_rank true if the rank should be updated before being sent, defaults to true
///
- instruction_t( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target = fapi2::Target<fapi2::TARGET_TYPE_DIMM>(),
- uint64_t i_rank = NO_CHIP_SELECT_ACTIVE,
+ instruction_t( uint64_t i_rank = NO_CHIP_SELECT_ACTIVE,
const fapi2::buffer<uint64_t> i_arr0 = 0,
- const fapi2::buffer<uint64_t> i_arr1 = 0):
+ const fapi2::buffer<uint64_t> i_arr1 = 0,
+ const bool i_update_rank = true):
arr0(i_arr0),
- arr1(i_arr1)
+ arr1(i_arr1),
+ iv_rank(i_rank),
+ iv_update_rank(i_update_rank)
{
- // For DIMM0 .first is the CSN_0_1 setting, .second is the CSN_2_3 setting.
- // For DIMM1 .first is the CSN_2_3 setting, .second is the CSN_0_1 setting.
- static const std::pair<uint64_t, uint64_t> CS_N[mss::MAX_RANK_PER_DIMM] =
+ // Skip setting up the rank if hte user doesn't want us to
+ if(iv_update_rank)
{
- // CS0 L CS1 H => CS2 => H CS3 => H Rank 0
- { 0b01, 0b11 },
-
- // CS0 H CS1 L => CS2 => H CS3 => H Rank 1
- { 0b10, 0b11 },
-
- // CS0 H CS1 H => CS2 => L CS3 => H Rank 2
- { 0b11, 0b01 },
+ // Set the chip selects to be 1's (not active)
+ // We'll fix these up before executing the instructions
+ arr0.insertFromRight<TT::ARR0_DDR_CSN_0_1,
+ TT::ARR0_DDR_CSN_0_1_LEN>(0b11);
+ arr0.insertFromRight<TT::ARR0_DDR_CSN_2_3,
+ TT::ARR0_DDR_CSN_2_3_LEN>(0b11);
+ }
+ }
- // CS0 H CS1 H => CS2 => H CS3 => L Rank 3
- { 0b11, 0b10 },
- };
+ ///
+ /// @brief Updates the rank based upon the passed in rank configuration encoding
+ /// @param[in] i_target the port target for this instruction - for error logging
+ /// @param[in] i_rank_config the rank configuration
+ /// @return fapi2::ReturnCode fapi2::FAPI2_RC_SUCCESS if ok
+ ///
+ fapi2::ReturnCode configure_rank(const fapi2::Target<TT::PORT_TARGET_TYPE>& i_target,
+ const rank_configuration i_rank_config )
+ {
+ // If this instrunction is set to not update the rank, then don't update the rank
+ if(!iv_update_rank)
+ {
+ return fapi2::FAPI2_RC_SUCCESS;
+ }
- // If the rank indicates nothing selected (active low) then we're done.
- if (i_rank == NO_CHIP_SELECT_ACTIVE)
+ // Regardless of rank configurations, if we have NO_CHIP_SELECT_ACTIVE, deactivate all CS
+ if(iv_rank == NO_CHIP_SELECT_ACTIVE)
{
arr0.insertFromRight<TT::ARR0_DDR_CSN_0_1, TT::ARR0_DDR_CSN_0_1_LEN>(0b11);
arr0.insertFromRight<TT::ARR0_DDR_CSN_2_3, TT::ARR0_DDR_CSN_2_3_LEN>(0b11);
- return;
+ return fapi2::FAPI2_RC_SUCCESS;
}
- //
- // Note: This likely needs to be able to handle all DIMM, stacked, encoded CS_n, etc. This
- // might not cut it. Turn this in to a dispatched funtion like c_str() and rcd_load() BRS
- //
+ // First, check rank - we need to make sure that we have a valid rank
+ FAPI_ASSERT(iv_rank < MAX_MRANK_PER_PORT,
+ fapi2::MSS_INVALID_RANK()
+ .set_MCA_TARGET(i_target)
+ .set_RANK(iv_rank)
+ .set_FUNCTION(ffdc_function_codes::CCS_INST_CONFIGURE_RANK),
+ "%s rank out of bounds rank%u", mss::c_str(i_target), iv_rank);
+
+ // Now the fun happens and we can deal with the actual encoding
- // Direct CS mode - just clear the CS_N you're interested in.
- // Setup the chip select based on which dimm in the slot and the rank
- if (mss::index(i_target) == 0)
+ // If we're quad mode, setup the encoding accordingly
+ if(i_rank_config == rank_configuration::QUAD_ENCODED)
{
- // Sanity check the incoming rank. It has to be 0-3 since we're DIMM0
- // Assert since this is a programming error
- if (i_rank >= MAX_RANK_PER_DIMM)
+ // CS 0/1 are first, while CID0/1 are second
+ // In quad enabled mode, CID acts as a "package select"
+ // It selects R0/2 vs R1/3
+ // CS0 vs CS1 selects the low vs high rank in the package
+ // CS0 will select rank 0/1
+ // CS1 will select rank 2/3
+
+ // Note: this is to workaround a Nimbus CCS bug
+ // 1) Nimbus thinks that CID0 is a CID not part of the CS for encoded mode
+ // 2) CID1 doesn't matter for quad encode
+ // 3) we only access ranks 2,3 in encoded mode
+ // 4) we can fake out parity by adding in another 1, so let's do that with CID1
+ // This is easier than calculating our own parity
+ // CS0 H, CS1 L, CID0-> L => Rank 2
+
+ static const std::pair<uint64_t, uint64_t> CS_N[mss::MAX_RANK_PER_DIMM] =
{
- FAPI_ERR("DIMM0 %s CCS instruction looking for bad rank/chip select (%d)",
- mss::c_str(i_target), i_rank);
- fapi2::Assert(false);
- // Not reached but fapi2::Assert isn't [[no return]] so the compiler thinks we're going
- // to run off the array but we're not so this makes the compiler happy.
- return;
- }
+ // CS0 L, CS1 H, CID0-> L => Rank 0
+ { 0b01, 0b00 },
+
+ // CS0 L, CS1 H, CID0-> H => Rank 1
+ { 0b01, 0b11 },
+
+ // CS0 H, CS1 L, CID0-> L => Rank 2
+ { 0b10, 0b00 },
+
+ // CS0 H, CS1 L, CID0-> H => Rank 3
+ { 0b10, 0b11 },
+ };
+ const auto l_dimm_rank = mss::index(iv_rank);
+ const bool l_is_dimm0 = iv_rank < MAX_RANK_PER_DIMM;
+ constexpr uint64_t NON_DIMM_CS = 0b11;
+
+ // Assigns the CS based upon which DIMM we're at
+ const auto CS01 = l_is_dimm0 ? CS_N[l_dimm_rank].first : NON_DIMM_CS;
+ const auto CS23 = l_is_dimm0 ? NON_DIMM_CS : CS_N[l_dimm_rank].first;
+
+ // Setup that rank
arr0.insertFromRight<TT::ARR0_DDR_CSN_0_1,
- TT::ARR0_DDR_CSN_0_1_LEN>(CS_N[i_rank].first);
+ TT::ARR0_DDR_CSN_0_1_LEN>(CS01);
arr0.insertFromRight<TT::ARR0_DDR_CSN_2_3,
- TT::ARR0_DDR_CSN_2_3_LEN>(CS_N[i_rank].second);
+ TT::ARR0_DDR_CSN_2_3_LEN>(CS23);
+ arr0.insertFromRight<TT::ARR0_DDR_CID_0_1,
+ TT::ARR0_DDR_CID_0_1_LEN>(CS_N[l_dimm_rank].second);
}
+
+ // Otherwise, setup for dual-direct mode (our only other supported mode at the moment)
else
{
- // DIMM1's ranks are {4,5,6,7} so we subract the mid-point rank to normalize i_rank for DIMM1
- const uint64_t l_effective_rank = i_rank - RANK_MID_POINT;
-
- // Sanity check that we don't have more than 2 ranks on DIMM1. Effective Config
- // should have caught this with the plug rules, but we will select the rank in the
- // wrong DIMM with this CCS instruction if we blew it, so lets check ... We can assert
- // our way out of this as this is a code bug in Effective Config, so they should have
- // reported a real error long ago ...
- if (l_effective_rank >= MAX_RANKS_DIMM1)
+ // For DIMM0 .first is the CSN_0_1 setting, .second is the CSN_2_3 setting.
+ // For DIMM1 .first is the CSN_2_3 setting, .second is the CSN_0_1 setting.
+ static const std::pair<uint64_t, uint64_t> CS_N[mss::MAX_RANK_PER_DIMM] =
{
- FAPI_ERR("DIMM1 %s CCS instruction looking for bad rank/chip select (%d, %d)",
- mss::c_str(i_target), i_rank, l_effective_rank);
- fapi2::Assert(false);
- // Not reached but fapi2::Assert isn't [[no return]] so the compiler thinks we're going
- // to run off the array but we're not so this makes the compiler happy.
- return;
- }
-
- // Deselect ranks on DIMM1
+ // CS0 L CS1 H => CS2 => H CS3 => H Rank 0
+ { 0b01, 0b11 },
+
+ // CS0 H CS1 L => CS2 => H CS3 => H Rank 1
+ { 0b10, 0b11 },
+
+ // CS0 H CS1 H => CS2 => L CS3 => H Rank 2
+ { 0b11, 0b01 },
+
+ // CS0 H CS1 H => CS2 => H CS3 => L Rank 3
+ { 0b11, 0b10 },
+ };
+
+ const auto l_dimm_rank = mss::index(iv_rank);
+ const bool l_is_dimm0 = iv_rank < MAX_RANK_PER_DIMM;
+
+ // Assigns the CS based upon which DIMM we're at
+ const auto CS01 = l_is_dimm0 ? CS_N[l_dimm_rank].first : CS_N[l_dimm_rank].second;
+ const auto CS23 = l_is_dimm0 ? CS_N[l_dimm_rank].second : CS_N[l_dimm_rank].first;
+
+ // Setup that rank
arr0.insertFromRight<TT::ARR0_DDR_CSN_0_1,
- TT::ARR0_DDR_CSN_0_1_LEN>(CS_N[l_effective_rank].second);
+ TT::ARR0_DDR_CSN_0_1_LEN>(CS01);
arr0.insertFromRight<TT::ARR0_DDR_CSN_2_3,
- TT::ARR0_DDR_CSN_2_3_LEN>(CS_N[l_effective_rank].first);
+ TT::ARR0_DDR_CSN_2_3_LEN>(CS23);
+
+ // Check that we don't have a rank out of bounds case here
+ // We can only have that if
+ // 1) we are DIMM1
+ // 2) our DIMM rank is greater than the maximum allowed number of ranks on DIMM1
+ // So, we pass always if we're DIMM0, or if our DIMM rank is less than the maximum number of DIMM's on rank 1
+ FAPI_ASSERT(l_dimm_rank < MAX_RANKS_DIMM1 || l_is_dimm0,
+ fapi2::MSS_INVALID_RANK()
+ .set_MCA_TARGET(i_target)
+ .set_RANK(iv_rank)
+ .set_FUNCTION(ffdc_function_codes::CCS_INST_CONFIGURE_RANK),
+ "%s rank out of bounds rank%u", mss::c_str(i_target), iv_rank);
}
+
+ return fapi2::FAPI2_RC_SUCCESS;
+ fapi_try_exit:
+ return fapi2::current_err;
}
///
@@ -347,11 +432,31 @@ class instruction_t
inline bool operator==( const instruction_t<T>& i_rhs ) const
{
return arr0 == i_rhs.arr0 &&
- arr1 == i_rhs.arr1;
+ arr1 == i_rhs.arr1 &&
+ iv_rank == i_rhs.iv_rank &&
+ iv_update_rank == i_rhs.iv_update_rank;
}
};
///
+/// @brief Determines our rank configuration type across all ports
+/// @param[in] i_target the MCA target on which to operate
+/// @param[out] o_rank_config the rank configuration
+/// @return fapi2::ReturnCode fapi2::FAPI2_RC_SUCCESS if ok
+///
+fapi2::ReturnCode get_rank_config(const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_target,
+ std::vector<rank_configuration>& o_rank_config);
+
+///
+/// @brief Determines our rank configuration type
+/// @param[in] i_target the MCA target on which to operate
+/// @param[out] o_rank_config the rank configuration
+/// @return fapi2::ReturnCode fapi2::FAPI2_RC_SUCCESS if ok
+///
+fapi2::ReturnCode get_rank_config(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
+ rank_configuration& o_rank_config);
+
+///
/// @brief A class representing a series of CCS instructions, and the
/// CCS engine parameters associated with running the instructions
/// @tparam T fapi2::TargetType representing the fapi2 target which
@@ -402,12 +507,10 @@ static void mrs_rcd_helper( fapi2::buffer<uint64_t>& i_arr0 )
/// @brief Setup activate command instruction
/// @tparam T the target type of the chiplet which executes the CCS instruction
/// @tparam TT the CCS traits of the chiplet which executes the CCS instruction
-/// @param[in] i_target the DIMM this instruction is headed for
/// @param[in] i_rank the rank on this dimm
///
template< fapi2::TargetType T, typename TT = ccsTraits<T> >
-inline instruction_t<T> act_command( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- const uint64_t i_rank)
+inline instruction_t<T> act_command( const uint64_t i_rank)
{
fapi2::buffer<uint64_t> l_boilerplate_arr0;
fapi2::buffer<uint64_t> l_boilerplate_arr1;
@@ -432,7 +535,7 @@ inline instruction_t<T> act_command( const fapi2::Target<fapi2::TARGET_TYPE_DIMM
l_boilerplate_arr0.clearBit<TT::ARR0_DDR_BANK_0_1, TT::ARR0_DDR_BANK_0_1_LEN>();
l_boilerplate_arr0.clearBit<TT::ARR0_DDR_BANK_2>();
- return instruction_t<T>(i_target, i_rank, l_boilerplate_arr0, l_boilerplate_arr1);
+ return instruction_t<T>(i_rank, l_boilerplate_arr0, l_boilerplate_arr1);
}
///
@@ -478,14 +581,13 @@ inline instruction_t<T> rcd_command( const fapi2::Target<fapi2::TARGET_TYPE_DIMM
.template setBit<TT::ARR0_DDR_BANK_GROUP_0>();
// RCD always goes to the 0th rank on the DIMM; either 0 or 4.
- return instruction_t<T>(i_target, (mss::index(i_target) == 0) ? 0 : 4, rcd_boilerplate_arr0, rcd_boilerplate_arr1);
+ return instruction_t<T>((mss::index(i_target) == 0) ? 0 : 4, rcd_boilerplate_arr0, rcd_boilerplate_arr1);
}
///
/// @brief Create, initialize an MRS CCS command
/// @tparam T the target type of the chiplet which executes the CCS instruction
/// @tparam TT the CCS traits of the chiplet which executes the CCS instruction
-/// @param[in] i_target the DIMM this instruction is headed for
/// @param[in] i_rank the rank on this dimm
/// @param[in] i_mrs the specific MRS
/// @return the MRS CCS instruction
@@ -494,8 +596,7 @@ inline instruction_t<T> rcd_command( const fapi2::Target<fapi2::TARGET_TYPE_DIMM
/// in this template definition)
///
template< fapi2::TargetType T, typename TT = ccsTraits<T> >
-inline instruction_t<T> mrs_command( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- const uint64_t i_rank,
+inline instruction_t<T> mrs_command (const uint64_t i_rank,
const uint64_t i_mrs )
{
fapi2::buffer<uint64_t> rcd_boilerplate_arr0;
@@ -514,7 +615,7 @@ inline instruction_t<T> mrs_command( const fapi2::Target<fapi2::TARGET_TYPE_DIMM
rcd_boilerplate_arr0.clearBit<TT::ARR0_DDR_BANK_GROUP_1>();
mss::swizzle<TT::ARR0_DDR_BANK_0_1, 3, 7>(mrs, rcd_boilerplate_arr0);
FAPI_DBG("mrs rcd boiler 0x%llx 0x%llx", uint8_t(mrs), uint64_t(rcd_boilerplate_arr0));
- return instruction_t<T>(i_target, i_rank, rcd_boilerplate_arr0, rcd_boilerplate_arr1);
+ return instruction_t<T>(i_rank, rcd_boilerplate_arr0, rcd_boilerplate_arr1);
}
///
@@ -547,8 +648,9 @@ inline instruction_t<T> des_command(const uint16_t i_idle = 0)
// RAS, CAS, WE no-care
// Device Deslect wants CS_n always high (select nothing using rank NO_CHIP_SELECT_ACTIVE)
- return instruction_t<T>(fapi2::Target<fapi2::TARGET_TYPE_DIMM>(), NO_CHIP_SELECT_ACTIVE,
- rcd_boilerplate_arr0, rcd_boilerplate_arr1);
+ return instruction_t<T>( NO_CHIP_SELECT_ACTIVE,
+ rcd_boilerplate_arr0,
+ rcd_boilerplate_arr1);
}
///
@@ -690,8 +792,7 @@ inline instruction_t<T> initial_cal_command(const uint64_t i_rp)
/// in this template definition)
///
template< fapi2::TargetType T, typename TT = ccsTraits<T> >
-inline instruction_t<T> zqcl_command( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- const uint64_t i_rank,
+inline instruction_t<T> zqcl_command( const uint64_t i_rank,
const uint16_t i_idle = 0 )
{
fapi2::buffer<uint64_t> l_boilerplate_arr0;
@@ -714,14 +815,13 @@ inline instruction_t<T> zqcl_command( const fapi2::Target<fapi2::TARGET_TYPE_DIM
// Insert idle
l_boilerplate_arr1.template insertFromRight<TT::ARR1_IDLES, TT::ARR1_IDLES_LEN>( i_idle );
- return instruction_t<T>(i_target, i_rank, l_boilerplate_arr0, l_boilerplate_arr1);
+ return instruction_t<T>(i_rank, l_boilerplate_arr0, l_boilerplate_arr1);
}
///
/// @brief Setup read command helper function
/// @tparam T the target type of the chiplet which executes the CCS instruction
/// @tparam TT the CCS traits of the chiplet which executes the CCS instruction
-/// @param[in] i_target the DIMM this instruction is headed for
/// @param[in] i_rank the rank on this dimm
/// @param[in] i_bank_addr bank address bits [BG0:BG1] = [62:63] (right aligned)
/// @param[in] i_bank_group_addr bank group address bits [BA0:BA1] = [62:63] (right aligned)
@@ -732,8 +832,7 @@ inline instruction_t<T> zqcl_command( const fapi2::Target<fapi2::TARGET_TYPE_DIM
/// in this template definition)
///
template< fapi2::TargetType T, typename TT = ccsTraits<T> >
-static fapi2::buffer<uint64_t> read_cmd_boilerplate( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- const uint64_t i_rank,
+static fapi2::buffer<uint64_t> read_cmd_boilerplate( const uint64_t i_rank,
const fapi2::buffer<uint64_t>& i_bank_addr = 0,
const fapi2::buffer<uint64_t>& i_bank_group_addr = 0,
const fapi2::buffer<uint64_t>& i_column_addr = 0)
@@ -774,7 +873,6 @@ static fapi2::buffer<uint64_t> read_cmd_boilerplate( const fapi2::Target<fapi2::
/// @brief Setup write command (Fixed BL8 or BC4) instruction
/// @tparam T the target type of the chiplet which executes the CCS instruction
/// @tparam TT the CCS traits of the chiplet which executes the CCS instruction
-/// @param[in] i_target the DIMM this instruction is headed for
/// @param[in] i_rank the rank on this dimm
/// @param[in] i_bank_addr bank address bits [BA0:BA1] = [62:63] (right aligned)
/// @param[in] i_bank_group_addr bank group address bits [BG0:BG1] = [62:63] (right aligned)
@@ -785,15 +883,13 @@ static fapi2::buffer<uint64_t> read_cmd_boilerplate( const fapi2::Target<fapi2::
/// in this template definition)
///
template< fapi2::TargetType T, typename TT = ccsTraits<T> >
-inline instruction_t<T> wr_command( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- const uint64_t i_rank,
+inline instruction_t<T> wr_command( const uint64_t i_rank,
const fapi2::buffer<uint64_t>& i_bank_addr = 0,
const fapi2::buffer<uint64_t>& i_bank_group_addr = 0,
const fapi2::buffer<uint64_t>& i_column_addr = 0)
{
// WR's and RD's are very similar, so we just use the RD command boiler plate and modify the command to a WR
- fapi2::buffer<uint64_t> l_boilerplate_arr0 = read_cmd_boilerplate<T>(i_target,
- i_rank,
+ fapi2::buffer<uint64_t> l_boilerplate_arr0 = read_cmd_boilerplate<T>(i_rank,
i_bank_addr,
i_bank_group_addr,
i_column_addr);
@@ -804,14 +900,13 @@ inline instruction_t<T> wr_command( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>
.template clearBit<TT::ARR0_DDR_ADDRESS_15>()
.template clearBit<TT::ARR0_DDR_ADDRESS_14>();
- return instruction_t<T>(i_target, i_rank, l_boilerplate_arr0, l_boilerplate_arr1);
+ return instruction_t<T>(i_rank, l_boilerplate_arr0, l_boilerplate_arr1);
}
///
/// @brief Setup read command (Fixed BL8 or BC4) instruction
/// @tparam T the target type of the chiplet which executes the CCS instruction
/// @tparam TT the CCS traits of the chiplet which executes the CCS instruction
-/// @param[in] i_target the DIMM this instruction is headed for
/// @param[in] i_rank the rank on this dimm
/// @param[in] i_bank_addr bank address bits [BA0:BA1] = [62:63] (right aligned)
/// @param[in] i_bank_group_addr bank group address bits [BG0:BG1] = [62:63] (right aligned)
@@ -822,8 +917,7 @@ inline instruction_t<T> wr_command( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>
/// in this template definition)
///
template< fapi2::TargetType T, typename TT = ccsTraits<T> >
-inline instruction_t<T> rd_command( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- const uint64_t i_rank,
+inline instruction_t<T> rd_command( const uint64_t i_rank,
const fapi2::buffer<uint64_t>& i_bank_addr = 0,
const fapi2::buffer<uint64_t>& i_bank_group_addr = 0,
const fapi2::buffer<uint64_t>& i_column_addr = 0)
@@ -831,20 +925,21 @@ inline instruction_t<T> rd_command( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>
fapi2::buffer<uint64_t> l_boilerplate_arr0;
fapi2::buffer<uint64_t> l_boilerplate_arr1;
- l_boilerplate_arr0 = read_cmd_boilerplate<fapi2::TARGET_TYPE_MCBIST>(i_target, i_rank, i_bank_addr,
- i_bank_group_addr, i_column_addr);
+ l_boilerplate_arr0 = read_cmd_boilerplate<fapi2::TARGET_TYPE_MCBIST>(i_rank,
+ i_bank_addr,
+ i_bank_group_addr,
+ i_column_addr);
// Setup ADDR10/AP based on read type
l_boilerplate_arr0.clearBit<TT::ARR0_DDR_ADDRESS_10>();
- return instruction_t<T>(i_target, i_rank, l_boilerplate_arr0, l_boilerplate_arr1);
+ return instruction_t<T>(i_rank, l_boilerplate_arr0, l_boilerplate_arr1);
}
///
/// @brief Setup read w/auto precharge command (Fixed BL8 or BC4) instruction
/// @tparam T the target type of the chiplet which executes the CCS instruction
/// @tparam TT the CCS traits of the chiplet which executes the CCS instruction
-/// @param[in] i_target the DIMM this instruction is headed for
/// @param[in] i_rank the rank on this dimm
/// @param[in] i_bank_addr bank address bits [BG0:BG1] = [62:63] (right aligned)
/// @param[in] i_bank_group_addr bank group address bits [BA0:BA1] = [62:63] (right aligned)
@@ -855,8 +950,7 @@ inline instruction_t<T> rd_command( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>
/// in this template definition)
///
template< fapi2::TargetType T, typename TT = ccsTraits<T> >
-inline instruction_t<T> rda_command( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- const uint64_t i_rank,
+inline instruction_t<T> rda_command( const uint64_t i_rank,
const fapi2::buffer<uint64_t>& i_bank_addr = 0,
const fapi2::buffer<uint64_t>& i_bank_group_addr = 0,
const fapi2::buffer<uint64_t>& i_column_addr = 0)
@@ -864,20 +958,21 @@ inline instruction_t<T> rda_command( const fapi2::Target<fapi2::TARGET_TYPE_DIMM
fapi2::buffer<uint64_t> l_boilerplate_arr0;
fapi2::buffer<uint64_t> l_boilerplate_arr1;
- l_boilerplate_arr0 = read_cmd_boilerplate<fapi2::TARGET_TYPE_MCBIST>(i_target, i_rank, i_bank_addr,
- i_bank_group_addr, i_column_addr);
+ l_boilerplate_arr0 = read_cmd_boilerplate<fapi2::TARGET_TYPE_MCBIST>(i_rank,
+ i_bank_addr,
+ i_bank_group_addr,
+ i_column_addr);
// Setup ADDR10/AP based on read type
l_boilerplate_arr0.setBit<TT::ARR0_DDR_ADDRESS_10>();
- return instruction_t<T>(i_target, i_rank, l_boilerplate_arr0, l_boilerplate_arr1);
+ return instruction_t<T>(i_rank, l_boilerplate_arr0, l_boilerplate_arr1);
}
///
/// @brief Setup precharge all banks command instruction
/// @tparam T the target type of the chiplet which executes the CCS instruction
/// @tparam TT the CCS traits of the chiplet which executes the CCS instruction
-/// @param[in] i_target the DIMM this instruction is headed for
/// @param[in] i_rank the rank on this dimm
/// @param[in] i_idle the idle time to the next command (default to 0)
/// @return the precharge all banks command CCS instruction
@@ -886,8 +981,7 @@ inline instruction_t<T> rda_command( const fapi2::Target<fapi2::TARGET_TYPE_DIMM
/// in this template definition)
///
template< fapi2::TargetType T, typename TT = ccsTraits<T> >
-inline instruction_t<T> precharge_all_command( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- const uint64_t i_rank,
+inline instruction_t<T> precharge_all_command( const uint64_t i_rank,
const uint16_t i_idle = 0 )
{
fapi2::buffer<uint64_t> l_boilerplate_arr0;
@@ -913,22 +1007,20 @@ inline instruction_t<T> precharge_all_command( const fapi2::Target<fapi2::TARGET
// From DDR4 Spec table 17:
// All other bits from the command truth table or 'V', for valid (1 or 0)
- return instruction_t<T>(i_target, i_rank, l_boilerplate_arr0, l_boilerplate_arr1);
+ return instruction_t<T>(i_rank, l_boilerplate_arr0, l_boilerplate_arr1);
}
///
/// @brief Setup self-refresh entry command instruction
/// @tparam T the target type of the chiplet which executes the CCS instruction
/// @tparam TT the CCS traits of the chiplet which executes the CCS instruction
-/// @param[in] i_target the DIMM this instruction is headed for
/// @param[in] i_rank the rank on this dimm
/// @param[in] i_idle the idle time to the next command (default to 0)
/// @return the self-refresh entry command CCS instruction
/// @note THIS IS FOR DDR4 NON-LRDIMM ONLY RIGHT NOW
///
template< fapi2::TargetType T, typename TT = ccsTraits<T> >
-inline instruction_t<T> self_refresh_entry_command( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- const uint64_t i_rank, const uint16_t i_idle = 0 )
+inline instruction_t<T> self_refresh_entry_command( const uint64_t i_rank, const uint16_t i_idle = 0 )
{
fapi2::buffer<uint64_t> l_boilerplate_arr0;
fapi2::buffer<uint64_t> l_boilerplate_arr1;
@@ -950,14 +1042,13 @@ inline instruction_t<T> self_refresh_entry_command( const fapi2::Target<fapi2::T
// From DDR4 Spec table 17:
// All other bits from the command truth table are 'V', for valid (1 or 0)
- return instruction_t<T>(i_target, i_rank, l_boilerplate_arr0, l_boilerplate_arr1);
+ return instruction_t<T>(i_rank, l_boilerplate_arr0, l_boilerplate_arr1);
}
///
/// @brief Setup self-refresh exit using NOP command instruction
/// @tparam T the target type of the chiplet which executes the CCS instruction
/// @tparam TT the CCS traits of the chiplet which executes the CCS instruction
-/// @param[in] i_target the DIMM this instruction is headed for
/// @param[in] i_rank the rank on this dimm
/// @param[in] i_idle the idle time to the next command (default to 0)
/// @return the self-refresh exit command CCS instruction
@@ -965,8 +1056,7 @@ inline instruction_t<T> self_refresh_entry_command( const fapi2::Target<fapi2::T
/// @note THIS IS FOR DDR4 NON-LRDIMM ONLY RIGHT NOW
///
template< fapi2::TargetType T, typename TT = ccsTraits<T> >
-inline instruction_t<T> self_refresh_exit_command( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
- const uint64_t i_rank, const uint16_t i_idle = 0 )
+inline instruction_t<T> self_refresh_exit_command( const uint64_t i_rank, const uint16_t i_idle = 0 )
{
fapi2::buffer<uint64_t> l_boilerplate_arr0;
fapi2::buffer<uint64_t> l_boilerplate_arr1;
@@ -988,7 +1078,7 @@ inline instruction_t<T> self_refresh_exit_command( const fapi2::Target<fapi2::TA
// From DDR4 Spec table 17:
// All other bits from the command truth table are 'V', for valid (1 or 0)
- return instruction_t<T>(i_target, i_rank, l_boilerplate_arr0, l_boilerplate_arr1);
+ return instruction_t<T>(i_rank, l_boilerplate_arr0, l_boilerplate_arr1);
}
//
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs_load_ddr4.H b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs_load_ddr4.H
index 0d7b2d018..bd8277daa 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs_load_ddr4.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs_load_ddr4.H
@@ -308,7 +308,7 @@ fapi2::ReturnCode mrs_engine( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_ta
const uint64_t i_delay_in_cycles,
std::vector< ccs::instruction_t<T> >& io_inst )
{
- ccs::instruction_t<T> l_inst_a_side = ccs::mrs_command<T>(i_target, i_rank, i_data.iv_mrs);
+ ccs::instruction_t<T> l_inst_a_side = ccs::mrs_command<T>(i_rank, i_data.iv_mrs);
ccs::instruction_t<T> l_inst_b_side;
bool l_is_a17 = false;
@@ -1914,7 +1914,7 @@ fapi2::ReturnCode mpr_read( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_targ
// Right now we only have support for RD and RDA
// Unclear if we want the API select the type of read command right now
// Note the auto precharge is ignored with MPR mode on so we just do a read cmd
- ccs::instruction_t<T> l_inst = ccs::rd_command<T> (i_target, i_rank, i_mpr_loc);
+ ccs::instruction_t<T> l_inst = ccs::rd_command<T> (i_rank, i_mpr_loc);
// In MPR Mode:
// Reads (back-to-back) from Page 0 may use tCCD_S or tCCD_L timing between read commands
@@ -1959,7 +1959,7 @@ fapi2::ReturnCode precharge_all( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i
const uint64_t i_rank,
std::vector< ccs::instruction_t<T> >& io_inst )
{
- ccs::instruction_t<T> l_inst = ccs::precharge_all_command<T> (i_target, i_rank);
+ ccs::instruction_t<T> l_inst = ccs::precharge_all_command<T> (i_rank);
// From the DDR4 Spec tRP is the precharge command period
uint8_t l_delay = 0;
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/nvdimm_utils.C b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/nvdimm_utils.C
index 0374da3dc..b35c5084f 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/nvdimm_utils.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/nvdimm_utils.C
@@ -527,9 +527,9 @@ fapi2::ReturnCode post_restore_zqcal( const fapi2::Target<fapi2::TARGET_TYPE_MCA
for ( const auto r : l_ranks)
{
FAPI_DBG("precharge_all_command for %s", mss::c_str(d));
- l_program.iv_instructions.push_back( ccs::precharge_all_command<TARGET_TYPE_MCBIST>(d, r, l_trp[0]) );
+ l_program.iv_instructions.push_back( ccs::precharge_all_command<TARGET_TYPE_MCBIST>(r, l_trp[0]) );
FAPI_DBG("zqcal_command for %s", mss::c_str(d));
- l_program.iv_instructions.push_back( ccs::zqcl_command<TARGET_TYPE_MCBIST>(d, r, mss::tzqinit()) );
+ l_program.iv_instructions.push_back( ccs::zqcl_command<TARGET_TYPE_MCBIST>(r, mss::tzqinit()) );
}
}// dimms
@@ -661,7 +661,7 @@ fapi2::ReturnCode preload_epow_sequence( const fapi2::Target<fapi2::TARGET_TYPE_
// Precharge all command
// All CKE = high, all CSn = low, Reset_n = high, wait tRP
- l_inst = ccs::precharge_all_command<TARGET_TYPE_MCBIST>(l_dimms[0], 0, l_trp);
+ l_inst = ccs::precharge_all_command<TARGET_TYPE_MCBIST>(0, l_trp);
l_inst.arr0.insertFromRight<TT::ARR0_DDR_CSN_0_1, TT::ARR0_DDR_CSN_0_1_LEN>(CS_N_ACTIVE);
l_inst.arr0.insertFromRight<TT::ARR0_DDR_CSN_2_3, TT::ARR0_DDR_CSN_2_3_LEN>(CS_N_ACTIVE);
l_inst.arr0.setBit<TT::ARR0_DDR_RESETN>();
@@ -670,7 +670,7 @@ fapi2::ReturnCode preload_epow_sequence( const fapi2::Target<fapi2::TARGET_TYPE_
// Self-refresh entry command
// All CKE = low, all CSn = low, Reset_n = high, wait tCKSRE
- l_inst = ccs::self_refresh_entry_command<TARGET_TYPE_MCBIST>(l_dimms[0], 0, mss::tcksre(l_dimms[0]));
+ l_inst = ccs::self_refresh_entry_command<TARGET_TYPE_MCBIST>(0, mss::tcksre(l_dimms[0]));
l_inst.arr0.insertFromRight<TT::ARR0_DDR_CSN_0_1, TT::ARR0_DDR_CSN_0_1_LEN>(CS_N_ACTIVE);
l_inst.arr0.insertFromRight<TT::ARR0_DDR_CSN_2_3, TT::ARR0_DDR_CSN_2_3_LEN>(CS_N_ACTIVE);
l_inst.arr0.insertFromRight<TT::ARR0_DDR_CKE, TT::ARR0_DDR_CKE_LEN>(mss::CKE_LOW);
@@ -680,7 +680,7 @@ fapi2::ReturnCode preload_epow_sequence( const fapi2::Target<fapi2::TARGET_TYPE_
// Push in an empty instruction for RESETn
// All CKE = low, all CSn = high (default), Reset_n = low
- l_inst = ccs::instruction_t<TARGET_TYPE_MCBIST>(l_dimms[0]);
+ l_inst = ccs::instruction_t<TARGET_TYPE_MCBIST>();
FAPI_INF("Assert RESETn arr0 = 0x%016lx , arr1 = 0x%016lx", l_inst.arr0, l_inst.arr1);
l_program.iv_instructions.push_back(l_inst);
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/zqcal.C b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/zqcal.C
index 844765f44..6e53bddd8 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/zqcal.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/zqcal.C
@@ -69,7 +69,7 @@ fapi2::ReturnCode setup_dram_zqcal( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>
FAPI_TRY( mss::tdllk(i_target, tDLLK) );
// Note: this isn't general - assumes Nimbus via MCBIST instruction here BRS
- l_inst = ccs::zqcl_command<TARGET_TYPE_MCBIST>(i_target, i_rank);
+ l_inst = ccs::zqcl_command<TARGET_TYPE_MCBIST>(i_rank);
// Doubling tZQ to better margin per lab request
{
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/phy/mss_lrdimm_training.H b/src/import/chips/p9/procedures/hwp/memory/lib/phy/mss_lrdimm_training.H
index fb9362680..c7d92d98a 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/phy/mss_lrdimm_training.H
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/phy/mss_lrdimm_training.H
@@ -122,8 +122,7 @@ inline fapi2::ReturnCode add_mpr_pattern_writes(const fapi2::Target<fapi2::TARGE
FAPI_TRY(l_swizzled_pattern.extract(l_pattern, l_ba * PATTERN_LEN, PATTERN_LEN, ADDR_START), "%s ba%u",
mss::c_str(i_target), l_ba);
{
- auto l_wr = mss::ccs::wr_command<fapi2::TARGET_TYPE_MCBIST>( i_target,
- i_rank,
+ auto l_wr = mss::ccs::wr_command<fapi2::TARGET_TYPE_MCBIST>( i_rank,
l_ba,
MPR_WR_BG,
l_pattern);
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 e61edfc78..db61b8afb 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
@@ -211,6 +211,9 @@ enum ffdc_function_codes
// LR training function
DWL_CALL_OUT = 130,
MREP_CALL_OUT = 131,
+
+
+ CCS_INST_CONFIGURE_RANK = 132,
};
// Static consts describing the bits used in the cal_step_enable attribute
diff --git a/src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit.C b/src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit.C
index 795107bfb..559593111 100644
--- a/src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit.C
+++ b/src/import/chips/p9/procedures/hwp/memory/p9_mss_draminit.C
@@ -60,7 +60,6 @@ extern "C"
{
fapi2::buffer<uint64_t> l_data;
- mss::ccs::instruction_t<TARGET_TYPE_MCBIST> l_inst;
mss::ccs::instruction_t<TARGET_TYPE_MCBIST> l_des = mss::ccs::des_command<TARGET_TYPE_MCBIST>();
mss::ccs::program<TARGET_TYPE_MCBIST> l_program;
OpenPOWER on IntegriCloud