Skip to content

Commit ae49a21

Browse files
Li Mengdcrowell77
authored andcommitted
Adds new algorithm for DWL
Change-Id: I76d8ac491dc2a383aec3d60f393fb290d40a0b68 Original-Change-Id: Icc6321c9ed690bd67a640f2b0ea317f562a37fcb Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/69339 Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Tested-by: HWSV CI <hwsv-ci+hostboot@us.ibm.com> Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Tested-by: Hostboot CI <hostboot-ci+hostboot@us.ibm.com> Reviewed-by: Louis Stermole <stermole@us.ibm.com> Reviewed-by: STEPHEN GLANCY <sglancy@us.ibm.com> Reviewed-by: Jennifer A. Stofer <stofer@us.ibm.com> Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/104160 Reviewed-by: Daniel M Crowell <dcrowell@us.ibm.com> Tested-by: Daniel M Crowell <dcrowell@us.ibm.com>
1 parent a40f39c commit ae49a21

File tree

4 files changed

+143
-211
lines changed

4 files changed

+143
-211
lines changed

src/import/chips/p9/procedures/hwp/memory/lib/phy/mss_dwl.C

Lines changed: 42 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@
3939
#include <p9_mc_scom_addresses_fld.H>
4040

4141
#include <lib/phy/mss_lrdimm_training.H>
42-
#include <lib/phy/mss_lrdimm_training_helper.H>
4342
#include <lib/phy/mss_dwl.H>
4443
#include <lib/phy/mss_training.H>
4544
#include <lib/dimm/rank.H>
@@ -61,7 +60,6 @@ namespace training
6160

6261
namespace lrdimm
6362
{
64-
6563
///
6664
/// @brief Configures the given rank into WR LVL mode
6765
/// @param[in] i_target DIMM target on which to operate
@@ -178,7 +176,7 @@ fapi_try_exit:
178176
/// @brief Sets DWL Delay value
179177
/// @param[in] i_target the DIMM target
180178
/// @param[in] i_rank the rank to operate on - drives the function space select
181-
/// @param[in] delay value /64 Tck - MREP delay value
179+
/// @param[in] delay value /64 Tck - DWL delay value
182180
/// @return FAPI2_RC_SUCCESS if okay
183181
/// @note Sets DA setting for buffer control word (F[3:0]BC2x, F[3:0]BC3x)
184182
///
@@ -227,101 +225,6 @@ fapi_try_exit:
227225
return fapi2::current_err;
228226
}
229227

230-
///
231-
/// @brief Processes the results for a given DWL run
232-
/// @param[in] i_target the target on which the code is operating
233-
/// @param[in] i_rank rank for test
234-
/// @param[in] i_buffer the buffer associated with the data
235-
/// @param[in] i_nibble the nibble associated with the data
236-
/// @param[in] i_result the results for the current nibble
237-
/// @param[in] i_delay the current delay
238-
/// @param[in,out] io_recorder the recorder on which to process the data
239-
/// @return FAPI2_RC_SUCCESS if okay
240-
///
241-
fapi2::ReturnCode dwl::process_results( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
242-
const uint64_t i_rank,
243-
const uint8_t i_buffer,
244-
const uint8_t i_nibble,
245-
const uint8_t i_result,
246-
const uint8_t i_delay,
247-
recorder& io_recorder) const
248-
{
249-
// If we have a 0 value, then set seen 0
250-
if(i_result == 0x00)
251-
{
252-
io_recorder.iv_seen0 = true;
253-
}
254-
255-
// If we have a F value, then start processing looking for a 0->1 transition
256-
else if(i_result == 0x0f)
257-
{
258-
io_recorder.iv_seen1 = true;
259-
260-
// If we have seen a 0 and have not recorded a transition
261-
// Then note this as our 0->1 transition
262-
if(io_recorder.iv_seen0 && io_recorder.iv_delay == 0)
263-
{
264-
io_recorder.iv_delay = i_delay;
265-
FAPI_DBG("DWL %s rank%u buffer%u nibble%u has seen a 0->1 transition at 0x%02x",
266-
mss::c_str(i_target), i_rank, i_buffer, i_nibble, i_delay);
267-
}
268-
}
269-
270-
// Otherwise, note that this data is invalid.
271-
// Note it via via debug and set our "non-zero and non-one data" flag
272-
else
273-
{
274-
io_recorder.iv_invalid_data_count++;
275-
FAPI_DBG("DWL %s rank%u buffer%u nibble%u has seen invalid data at delay 0x%02x data:0x%02x - count %u",
276-
mss::c_str(i_target), i_rank, i_buffer, i_nibble, i_delay, i_result, io_recorder.iv_invalid_data_count);
277-
}
278-
279-
return fapi2::FAPI2_RC_SUCCESS;
280-
}
281-
282-
///
283-
/// @brief Processes the results for a given DWL run
284-
/// @param[in] i_target the MCA target on which to operate
285-
/// @param[in] i_rank rank for test
286-
/// @param[in] i_delay the current delay
287-
/// @param[in,out] io_recorders the recorders on which to process the data
288-
/// @return FAPI2_RC_SUCCESS if okay
289-
///
290-
fapi2::ReturnCode dwl::process_results( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
291-
const uint64_t i_rank,
292-
const uint8_t i_delay,
293-
std::vector<std::pair<recorder, recorder>>& io_recorders) const
294-
{
295-
data_response l_data;
296-
uint8_t l_buffer = 0;
297-
298-
FAPI_TRY(l_data.read(i_target), "%s failed to read MREP data response delay:0x%02x", mss::c_str(i_target), i_delay);
299-
300-
// Note: we want to update the value of the results recorder, so no const
301-
for(auto& l_recorder : io_recorders)
302-
{
303-
// All beats should be the same, until proven otherwise, just use beat 0
304-
constexpr uint64_t DEFAULT_BEAT = 0;
305-
const fapi2::buffer<uint8_t> l_buffer_result(l_data.iv_buffer_beat[l_buffer][DEFAULT_BEAT]);
306-
307-
FAPI_DBG("DWL %s rank%u delay:0x%02x buffer:%u saw data of 0x%02x",
308-
mss::c_str(i_target), i_rank, i_delay, l_buffer, l_data.iv_buffer_beat[l_buffer][DEFAULT_BEAT]);
309-
310-
uint8_t l_nibble_result = 0;
311-
l_buffer_result.extractToRight<0, BITS_PER_NIBBLE>(l_nibble_result);
312-
FAPI_TRY(process_results(i_target, i_rank, l_buffer, 0, l_nibble_result, i_delay, l_recorder.first));
313-
314-
l_buffer_result.extractToRight<BITS_PER_NIBBLE, BITS_PER_NIBBLE>(l_nibble_result);
315-
FAPI_TRY(process_results(i_target, i_rank, l_buffer, 1, l_nibble_result, i_delay, l_recorder.second));
316-
317-
++l_buffer;
318-
}
319-
320-
fapi_try_exit:
321-
// If we are here then we FAPI_ASSERT'ed out
322-
return fapi2::current_err;
323-
}
324-
325228
///
326229
/// @brief Creates the nibble flags for the invalid data callout
327230
/// @param[in] i_target the DIMM target on which to operate
@@ -333,7 +236,7 @@ fapi_try_exit:
333236
///
334237
uint32_t dwl::flag_invalid_data( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
335238
const uint8_t i_rank,
336-
const std::vector<std::pair<recorder, recorder>>& i_recorders,
239+
const std::vector<std::pair<mrep_dwl_recorder, mrep_dwl_recorder>>& i_recorders,
337240
uint64_t& o_invalid_count) const
338241
{
339242
o_invalid_count = 0;
@@ -357,8 +260,8 @@ uint32_t dwl::flag_invalid_data( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i
357260

358261
// Updates the bitmap
359262
o_invalid_count += l_recorder.first.iv_invalid_data_count + l_recorder.second.iv_invalid_data_count;
360-
append_nibble_flags(l_recorder.first.iv_invalid_data_count != recorder::CLEAN,
361-
l_recorder.second.iv_invalid_data_count != recorder::CLEAN,
263+
append_nibble_flags(l_recorder.first.iv_invalid_data_count != mrep_dwl_recorder::CLEAN,
264+
l_recorder.second.iv_invalid_data_count != mrep_dwl_recorder::CLEAN,
362265
l_per_nibble_flags);
363266

364267
l_buffer++;
@@ -377,7 +280,7 @@ uint32_t dwl::flag_invalid_data( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i
377280
///
378281
fapi2::ReturnCode dwl::callout_invalid_data( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
379282
const uint8_t i_rank,
380-
const std::vector<std::pair<recorder, recorder>>& i_recorders) const
283+
const std::vector<std::pair<mrep_dwl_recorder, mrep_dwl_recorder>>& i_recorders) const
381284
{
382285
// Per nibble invalid data - bitmap
383286
// A bitmap is used to simplify the error callouts
@@ -409,7 +312,7 @@ fapi_try_exit:
409312
///
410313
uint32_t dwl::flag_no_transition( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
411314
const uint8_t i_rank,
412-
const std::vector<std::pair<recorder, recorder>>& i_recorders) const
315+
const std::vector<std::pair<mrep_dwl_recorder, mrep_dwl_recorder>>& i_recorders) const
413316
{
414317
uint8_t l_buffer = 0;
415318

@@ -450,7 +353,7 @@ uint32_t dwl::flag_no_transition( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>&
450353
///
451354
fapi2::ReturnCode dwl::callout_no_transition( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
452355
const uint8_t i_rank,
453-
const std::vector<std::pair<recorder, recorder>>& i_recorders) const
356+
const std::vector<std::pair<mrep_dwl_recorder, mrep_dwl_recorder>>& i_recorders) const
454357
{
455358
// Per nibble weird data and no transition flags - bitmap
456359
// A bitmap is used to simplify the error callouts
@@ -475,9 +378,9 @@ fapi_try_exit:
475378
/// @param[in] i_recorders the recorders on which to process the data
476379
/// @return FAPI2_RC_SUCCESS if okay
477380
///
478-
fapi2::ReturnCode dwl::analyze_results( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
479-
const uint8_t i_rank,
480-
const std::vector<std::pair<recorder, recorder>>& i_recorders) const
381+
fapi2::ReturnCode dwl::check_errors( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
382+
const uint8_t i_rank,
383+
const std::vector<std::pair<mrep_dwl_recorder, mrep_dwl_recorder>>& i_recorders) const
481384
{
482385
FAPI_TRY(callout_no_transition(i_target, i_rank, i_recorders));
483386
FAPI_TRY(callout_invalid_data(i_target, i_rank, i_recorders));
@@ -490,14 +393,14 @@ fapi_try_exit:
490393
/// @brief Write the results to buffer generate PBA commands
491394
/// @param[in] i_target the DIMM target
492395
/// @param[in] i_rank the rank number
493-
/// @param[in] i_recorders a vector of the MREP result
396+
/// @param[in] i_recorders a vector of the DWL result
494397
/// @param[out] o_container the PBA commands structure
495398
/// @return FAPI2_RC_SUCCESS if and only if ok
496399
/// @note a little helper to allow us to unit test that we generate the PBA commands ok
497400
///
498401
fapi2::ReturnCode dwl::write_result_to_buffers_helper( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
499402
const uint8_t i_rank,
500-
const std::vector<std::pair<recorder, recorder>>& i_recorders,
403+
const std::vector<std::pair<mrep_dwl_recorder, mrep_dwl_recorder>>& i_recorders,
501404
mss::ddr4::pba::commands& o_container) const
502405
{
503406
const auto& l_mca = mss::find_target<fapi2::TARGET_TYPE_MCA>(i_target);
@@ -563,7 +466,7 @@ fapi_try_exit:
563466
///
564467
fapi2::ReturnCode dwl::write_result_to_buffers( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
565468
const uint8_t i_rank,
566-
const std::vector<std::pair<recorder, recorder>>& i_recorders) const
469+
const std::vector<std::pair<mrep_dwl_recorder, mrep_dwl_recorder>>& i_recorders) const
567470
{
568471
mss::ddr4::pba::commands l_container;
569472

@@ -575,7 +478,7 @@ fapi2::ReturnCode dwl::write_result_to_buffers( const fapi2::Target<fapi2::TARGE
575478
"%s rank%u failed generating PBA commands",
576479
mss::c_str(i_target), i_rank);
577480

578-
// Issue the PBA to set the final MREP results
481+
// Issue the PBA to set the final DWL results
579482
FAPI_TRY(mss::ddr4::pba::execute_commands(l_container));
580483

581484
fapi_try_exit:
@@ -599,7 +502,7 @@ fapi2::ReturnCode dwl::run( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_targe
599502
const auto& l_dimms = mss::find_targets<fapi2::TARGET_TYPE_DIMM>(i_target);
600503

601504
FAPI_TRY(mss::rank::get_ranks_in_pair( i_target, i_rp, l_ranks),
602-
"Failed get_ranks_in_pair in mrep::run %s",
505+
"Failed get_ranks_in_pair in dwl::run %s",
603506
mss::c_str(i_target));
604507

605508
// Loops over all ranks within this rank pair
@@ -617,7 +520,9 @@ fapi2::ReturnCode dwl::run( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_targe
617520

618521
// Vector represents the number of LRDIMM buffers
619522
// The pair represents the two nibbles that we need to calibrate within the buffer
620-
std::vector<std::pair<recorder, recorder>> l_results_recorder(MAX_LRDIMM_BUFFERS);
523+
std::vector<std::pair<mrep_dwl_recorder, mrep_dwl_recorder>> l_results_recorder(MAX_LRDIMM_BUFFERS);
524+
//Loop through all of our delays multiple times to reduce noise issues
525+
std::vector<mrep_dwl_result> l_loop_results(MREP_DWL_LOOP_TIMES);
621526

622527
// 1) Puts the DRAM into WR LVL mode
623528
FAPI_TRY(dram_wr_lvl(l_dimm, l_rank, mss::states::ON), "%s failed set_buffer_training",
@@ -629,19 +534,23 @@ fapi2::ReturnCode dwl::run( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_targe
629534
// 3) Puts the buffer into WR LVL mode
630535
FAPI_TRY(set_buffer_training(l_dimm, ddr4::DWL), "%s failed set_buffer_training", mss::c_str(l_dimm));
631536

632-
// Loop through all of our delays
633-
for(uint8_t l_delay = 0; l_delay < MAX_DELAY; ++l_delay)
537+
for(auto& l_loop_result : l_loop_results)
634538
{
635-
// 4) Set the DWL l_delay -> host issues BCW's
636-
FAPI_TRY(set_delay(l_dimm, l_rank, l_delay), "%s failed set_delay rank%u delay%u", mss::c_str(l_dimm), l_rank, l_delay);
637-
638-
// 5) Do an NTTM mode read -> forces the logic to read out the data
639-
FAPI_TRY(execute_nttm_mode_read(i_target));
640-
641-
// 6) Processes the results for this delay and updates the recorder
642-
FAPI_TRY(process_results(i_target, l_rank, l_delay, l_results_recorder), "%s failed process_results rank%u delay%u",
643-
mss::c_str(l_dimm), l_rank, l_delay);
644-
} //l_delay loop
539+
// Loop through all of our delays
540+
for(uint8_t l_delay = 0; l_delay < MREP_DWL_MAX_DELAY; ++l_delay)
541+
{
542+
// 4) Set the DWL l_delay -> host issues BCW's
543+
FAPI_TRY(set_delay(l_dimm, l_rank, l_delay), "%s failed set_delay rank%u delay%u", mss::c_str(l_dimm), l_rank, l_delay);
544+
545+
// 5) Do an NTTM mode read -> forces the logic to read out the data
546+
FAPI_TRY(execute_nttm_mode_read(i_target));
547+
548+
// 6) Get the results for this delay and updates result and the recorder
549+
FAPI_TRY(get_result(l_dimm, mss::cal_steps::DWL, l_delay, l_loop_result, l_results_recorder),
550+
"%s failed get_result rank%u delay%u",
551+
mss::c_str(l_dimm), l_rank, l_delay);
552+
} //l_delay loop
553+
}
645554

646555
// 7) Takes the buffer out of WR LVL mode
647556
FAPI_TRY(set_buffer_training(l_dimm, ddr4::NORMAL), "%s failed set_buffer_training", mss::c_str(l_dimm));
@@ -650,11 +559,16 @@ fapi2::ReturnCode dwl::run( const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_targe
650559
FAPI_TRY(dram_wr_lvl(l_dimm, l_rank, mss::states::OFF), "%s failed set_buffer_training",
651560
mss::c_str(l_dimm));
652561

653-
// 9) Analyzes the final results and does some error checking
654-
FAPI_TRY(analyze_results(l_dimm, l_rank, l_results_recorder), "%s failed error_check rank:%u", mss::c_str(l_dimm),
562+
// 9) Analyze loop results
563+
FAPI_TRY( analyze_result(l_dimm, mss::cal_steps::DWL, l_loop_results, l_results_recorder),
564+
"%s failed analyze_dwl_result rank%u",
565+
mss::c_str(l_dimm), l_rank);
566+
567+
// 10) Checks for errors
568+
FAPI_TRY(check_errors(l_dimm, l_rank, l_results_recorder), "%s failed error_check rank:%u", mss::c_str(l_dimm),
655569
l_rank);
656570

657-
// 10) Write final values into the buffers -> host issues BCW's in PBA mode (values are calculated in step 7)
571+
// 11) Write final values into the buffers -> host issues BCW's in PBA mode (values are calculated in step 7)
658572
FAPI_TRY( write_result_to_buffers(l_dimm, l_rank, l_results_recorder), "%s failed write_result_to_buffers rank%u",
659573
mss::c_str(l_dimm), l_rank);
660574
}//l_rank loop

0 commit comments

Comments
 (0)