summaryrefslogtreecommitdiffstats
path: root/src/usr/hwpf/hwp/dram_training
diff options
context:
space:
mode:
Diffstat (limited to 'src/usr/hwpf/hwp/dram_training')
-rw-r--r--src/usr/hwpf/hwp/dram_training/dram_training.C4
-rw-r--r--src/usr/hwpf/hwp/dram_training/makefile2
-rw-r--r--src/usr/hwpf/hwp/dram_training/mem_pll_setup/cen_mem_pll_initf.C30
-rw-r--r--src/usr/hwpf/hwp/dram_training/memory_errors.xml156
-rw-r--r--src/usr/hwpf/hwp/dram_training/mss_ddr_phy_reset/mss_ddr_phy_reset.C539
-rw-r--r--src/usr/hwpf/hwp/dram_training/mss_ddr_phy_reset/mss_termination_control.C1408
-rw-r--r--src/usr/hwpf/hwp/dram_training/mss_ddr_phy_reset/mss_termination_control.H269
-rwxr-xr-xsrc/usr/hwpf/hwp/dram_training/mss_draminit/mss_draminit.C361
-rw-r--r--src/usr/hwpf/hwp/dram_training/mss_draminit_mc/mss_draminit_mc.C141
-rw-r--r--src/usr/hwpf/hwp/dram_training/mss_draminit_training/mss_draminit_training.C1550
-rw-r--r--src/usr/hwpf/hwp/dram_training/mss_funcs.C126
-rw-r--r--src/usr/hwpf/hwp/dram_training/mss_funcs.H79
-rw-r--r--src/usr/hwpf/hwp/dram_training/mss_scominit/mss_scominit.C203
-rw-r--r--src/usr/hwpf/hwp/dram_training/mss_scominit/mss_scominit.H18
-rw-r--r--src/usr/hwpf/hwp/dram_training/mss_unmask_errors.C2743
-rw-r--r--src/usr/hwpf/hwp/dram_training/mss_unmask_errors.H275
16 files changed, 7230 insertions, 674 deletions
diff --git a/src/usr/hwpf/hwp/dram_training/dram_training.C b/src/usr/hwpf/hwp/dram_training/dram_training.C
index 083786e64..95a1a7327 100644
--- a/src/usr/hwpf/hwp/dram_training/dram_training.C
+++ b/src/usr/hwpf/hwp/dram_training/dram_training.C
@@ -535,7 +535,7 @@ void* call_mss_ddr_phy_reset( void *io_pArgs )
// Cast to a FAPI type of target.
const fapi::Target l_fapi_mba_target(
- TARGET_TYPE_MEMBUF_CHIP,
+ TARGET_TYPE_MBA_CHIPLET,
reinterpret_cast<void *>
(const_cast<TARGETING::Target*>(l_mba_target)) );
@@ -707,7 +707,7 @@ void* call_mss_draminit_training( void *io_pArgs )
// Cast to a FAPI type of target.
const fapi::Target l_fapi_mba_target(
- TARGET_TYPE_MEMBUF_CHIP,
+ TARGET_TYPE_MBA_CHIPLET,
reinterpret_cast<void *>
(const_cast<TARGETING::Target*>(l_mba_target)) );
diff --git a/src/usr/hwpf/hwp/dram_training/makefile b/src/usr/hwpf/hwp/dram_training/makefile
index e2ff8c7de..121e8677b 100644
--- a/src/usr/hwpf/hwp/dram_training/makefile
+++ b/src/usr/hwpf/hwp/dram_training/makefile
@@ -52,9 +52,11 @@ EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/dram_training/mem_pll_setup
OBJS = dram_training.o \
mss_draminit.o \
mss_funcs.o \
+ mss_unmask_errors.o \
mss_draminit_mc.o \
mss_draminit_training.o \
mss_ddr_phy_reset.o \
+ mss_termination_control.o \
cen_mem_startclocks.o \
mss_scominit.o \
cen_mem_pll_initf.o \
diff --git a/src/usr/hwpf/hwp/dram_training/mem_pll_setup/cen_mem_pll_initf.C b/src/usr/hwpf/hwp/dram_training/mem_pll_setup/cen_mem_pll_initf.C
index 784577ac3..21dcbdb7c 100644
--- a/src/usr/hwpf/hwp/dram_training/mem_pll_setup/cen_mem_pll_initf.C
+++ b/src/usr/hwpf/hwp/dram_training/mem_pll_setup/cen_mem_pll_initf.C
@@ -20,7 +20,7 @@
/* Origin: 30 */
/* */
/* IBM_PROLOG_END_TAG */
-// $Id: cen_mem_pll_initf.C,v 1.2 2012/08/27 16:05:20 mfred Exp $
+// $Id: cen_mem_pll_initf.C,v 1.3 2012/11/07 23:22:44 mfred Exp $
// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/centaur/working/procedures/ipl/fapi/cen_mem_pll_initf.C,v $
//------------------------------------------------------------------------------
// *! (C) Copyright International Business Machines Corp. 2012
@@ -88,7 +88,7 @@ const uint64_t CLK_REGION_FOR_SETPULSE = 0x0010040000000000ull;
// The supported frequencies are 800, 1066, 1333, 1600, 1866, and 2133 MHz (These are the DDR frequencies and the PLL output B frequencies.)
-// Here are the bit definitions for the Analog PLL controller:
+// Here are the bit definitions for the Analog PLL controller: (Checked with values from T.Diemoz Nov.7,2012)
//
// Bits Purpose Value to be used for OutB=1600MHz (when using real HW PLL)
// ------- -------------- ------------------------
@@ -104,7 +104,7 @@ const uint64_t CLK_REGION_FOR_SETPULSE = 0x0010040000000000ull;
// 46 to 54 mult 011000000 (put different values here for different freqs)
// 55 to 56 outsel 00
// 57 to 58 phasedet_tune 10
-// 59 fbksel 1
+// 59 fbksel 0
// 60 to 63 rangea 0001 (put different values here for different freqs)
// 64 to 67 rangeb 0011 (put different values here for different freqs)
// 68 refdiv 0
@@ -148,32 +148,32 @@ const uint64_t MEM_PLL_CNTRL2_SIM_FREQ_1600 = 0x0F; // Temp value: Put F int
// HARDWARE-ONLY PLL SETTINGS:
//------------------------------
// TODO adjust this HW setting for PLL OutputB = 800 Mhz
-const uint64_t MEM_PLL_CNTRL0_FREQ_800 = 0x128000000A018051ull;
+const uint64_t MEM_PLL_CNTRL0_FREQ_800 = 0x128000000A018041ull;
const uint64_t MEM_PLL_CNTRL1_FREQ_800 = 0x3000000200000000ull;
const uint64_t MEM_PLL_CNTRL2_FREQ_800 = 0x00;
// TODO adjust this HW setting for PLL OutputB = 1066 Mhz
-const uint64_t MEM_PLL_CNTRL0_FREQ_1066 = 0x128000000A018051ull;
+const uint64_t MEM_PLL_CNTRL0_FREQ_1066 = 0x128000000A018041ull;
const uint64_t MEM_PLL_CNTRL1_FREQ_1066 = 0x3000000200000000ull;
const uint64_t MEM_PLL_CNTRL2_FREQ_1066 = 0x00;
-// HW Setting for PLL OutputB = 1333 Mhz
-const uint64_t MEM_PLL_CNTRL0_FREQ_1333 = 0x128000000A028051ull;
+// HW Setting for PLL OutputB = 1333 Mhz (Checked with values from T.Diemoz Nov.7,2012)
+const uint64_t MEM_PLL_CNTRL0_FREQ_1333 = 0x128000000A028041ull;
const uint64_t MEM_PLL_CNTRL1_FREQ_1333 = 0x3000000200000000ull;
const uint64_t MEM_PLL_CNTRL2_FREQ_1333 = 0x00;
-// HW Setting for PLL OutputB = 1600 Mhz
-const uint64_t MEM_PLL_CNTRL0_FREQ_1600 = 0x128000000A018051ull;
+// HW Setting for PLL OutputB = 1600 Mhz (Checked with values from T.Diemoz Nov.7,2012)
+const uint64_t MEM_PLL_CNTRL0_FREQ_1600 = 0x128000000A018041ull;
const uint64_t MEM_PLL_CNTRL1_FREQ_1600 = 0x3000000200000000ull;
const uint64_t MEM_PLL_CNTRL2_FREQ_1600 = 0x00;
-// HW Setting for PLL OutputB = 1866 Mhz
-const uint64_t MEM_PLL_CNTRL0_FREQ_1866 = 0x128000000A038055ull;
+// HW Setting for PLL OutputB = 1866 Mhz (Checked with values from T.Diemoz Nov.7,2012)
+const uint64_t MEM_PLL_CNTRL0_FREQ_1866 = 0x128000000A038045ull;
const uint64_t MEM_PLL_CNTRL1_FREQ_1866 = 0xB000000200000000ull;
const uint64_t MEM_PLL_CNTRL2_FREQ_1866 = 0x00;
// TODO adjust this HW setting for PLL OutputB = 2133 Mhz
-const uint64_t MEM_PLL_CNTRL0_FREQ_2133 = 0x128000000A018051ull;
+const uint64_t MEM_PLL_CNTRL0_FREQ_2133 = 0x128000000A018041ull;
const uint64_t MEM_PLL_CNTRL1_FREQ_2133 = 0x3000000200000000ull;
const uint64_t MEM_PLL_CNTRL2_FREQ_2133 = 0x00;
@@ -265,12 +265,14 @@ fapi::ReturnCode cen_mem_pll_initf(const fapi::Target & i_target)
// The supported frequencies are 800, 1066, 1333, 1600, 1866, and 2133 MHz (These are the DDR frequencies and the PLL output B frequencies.)
if (mss_freq == 800)
{
+FAPI_ERR("PLL settings not specified for this frequency. Defaulting to 1600MHz..");
rc_ecmd |= pll_data.setDoubleWord( 0, MEM_PLL_CNTRL0_FREQ_800 );
rc_ecmd |= pll_data.setDoubleWord( 1, MEM_PLL_CNTRL1_FREQ_800 );
rc_ecmd |= pll_data.setByte( 16, MEM_PLL_CNTRL2_FREQ_800 );
}
else if (mss_freq == 1066)
{
+FAPI_ERR("PLL settings not specified for this frequency. Defaulting to 1600MHz..");
rc_ecmd |= pll_data.setDoubleWord( 0, MEM_PLL_CNTRL0_FREQ_1066 );
rc_ecmd |= pll_data.setDoubleWord( 1, MEM_PLL_CNTRL1_FREQ_1066 );
rc_ecmd |= pll_data.setByte( 16, MEM_PLL_CNTRL2_FREQ_1066 );
@@ -295,6 +297,7 @@ fapi::ReturnCode cen_mem_pll_initf(const fapi::Target & i_target)
}
else if (mss_freq == 2133)
{
+FAPI_ERR("PLL settings not specified for this frequency. Defaulting to 1600MHz..");
rc_ecmd |= pll_data.setDoubleWord( 0, MEM_PLL_CNTRL0_FREQ_2133 );
rc_ecmd |= pll_data.setDoubleWord( 1, MEM_PLL_CNTRL1_FREQ_2133 );
rc_ecmd |= pll_data.setByte( 16, MEM_PLL_CNTRL2_FREQ_2133 );
@@ -490,6 +493,9 @@ fapi::ReturnCode cen_mem_pll_initf(const fapi::Target & i_target)
This section is automatically updated by CVS when you check in this file.
Be sure to create CVS comments when you commit so that they can be included here.
$Log: cen_mem_pll_initf.C,v $
+Revision 1.3 2012/11/07 23:22:44 mfred
+Updated MEM PLL settings for HW with values from Tim Diemoz.
+
Revision 1.2 2012/08/27 16:05:20 mfred
committing minor updates as suggested by FW review.
diff --git a/src/usr/hwpf/hwp/dram_training/memory_errors.xml b/src/usr/hwpf/hwp/dram_training/memory_errors.xml
index 8a3811b8d..98b56aa52 100644
--- a/src/usr/hwpf/hwp/dram_training/memory_errors.xml
+++ b/src/usr/hwpf/hwp/dram_training/memory_errors.xml
@@ -1,25 +1,25 @@
-<!-- IBM_PROLOG_BEGIN_TAG
- This is an automatically generated prolog.
-
- $Source: src/usr/hwpf/hwp/dram_training/memory_errors.xml $
-
- IBM CONFIDENTIAL
-
- COPYRIGHT International Business Machines Corp. 2012
-
- p1
-
- Object Code Only (OCO) source materials
- Licensed Internal Code Source Materials
- IBM HostBoot Licensed Internal Code
-
- The source code for this program is not published or other-
- wise divested of its trade secrets, irrespective of what has
- been deposited with the U.S. Copyright Office.
-
- Origin: 30
-
- IBM_PROLOG_END_TAG -->
+<!-- IBM_PROLOG_BEGIN_TAG -->
+<!-- This is an automatically generated prolog. -->
+<!-- -->
+<!-- $Source: src/usr/hwpf/hwp/dram_training/memory_errors.xml $ -->
+<!-- -->
+<!-- IBM CONFIDENTIAL -->
+<!-- -->
+<!-- COPYRIGHT International Business Machines Corp. 2012 -->
+<!-- -->
+<!-- p1 -->
+<!-- -->
+<!-- Object Code Only (OCO) source materials -->
+<!-- Licensed Internal Code Source Materials -->
+<!-- IBM HostBoot Licensed Internal Code -->
+<!-- -->
+<!-- The source code for this program is not published or otherwise -->
+<!-- divested of its trade secrets, irrespective of what has been -->
+<!-- deposited with the U.S. Copyright Office. -->
+<!-- -->
+<!-- Origin: 30 -->
+<!-- -->
+<!-- IBM_PROLOG_END_TAG -->
<hwpErrors>
<!-- DO NOT EDIT THIS FILE DIRECTLY PLEASE UPDATE THE ODS FILE AND FOLLOW THE INSTRUCTION TAB -->
<!-- PLEASE SEE MARK BELLOWS (BELLOWS.IBM.COM) OR OTHERS ON MEMORY TEAM FOR HELP -->
@@ -96,6 +96,11 @@
</hwpError>
<hwpError>
+ <rc>RC_MSS_INIT3_FSISTATUS_FAIL</rc>
+ <description>Failed clock region check on FSI2PIB Status Reg bit(31).</description>
+</hwpError>
+
+ <hwpError>
<rc>RC_MSS_PLL_LOCK_TIMEOUT</rc>
<description>Timed out waiting for PLL locks in FSI2PIB Status Reg bits(24,25). </description>
</hwpError>
@@ -321,6 +326,113 @@
<description>Less than 2 MBA's returned by fapiGetChildChiplets</description>
</hwpError>
+ <hwpError>
+ <rc>RC_MSS_SLEW_CAL_ERROR</rc>
+ <description>Slew calibration error occurred.</description>
+</hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_INVALID_FREQ</rc>
+ <description>MSS_FREQ attribute equals 0.</description>
+</hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_INVALID_DRAM_GEN</rc>
+ <description>DRAM_GEN attribute is not valid; equals 0 for empty.</description>
+</hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_IMP_INPUT_ERROR</rc>
+ <description>Impedance is invalid for driver/receiver type.</description>
+</hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_INVALID_FN_INPUT_ERROR</rc>
+ <description>An input to FN call is out of range.</description>
+</hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_MCBIST_TIMEOUT_ERROR</rc>
+ <description>Timeout on MCBIST configuration register polling.</description>
+</hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_MCBIST_ERROR</rc>
+ <description>MCBIST operation failed</description>
+</hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_PORT_INPUT_ERROR</rc>
+ <description>TBD</description>
+</hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_DRIVER_IMP_INPUT_ERROR</rc>
+ <description>TBD</description>
+</hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_SLEW_INPUT_ERROR</rc>
+ <description>TBD</description>
+</hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_WR_DRAM_VREF_INPUT_ERROR</rc>
+ <description>TBD</description>
+</hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_READ_CEN_VREF_INPUT_ERROR</rc>
+ <description>TBD</description>
+</hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_RECEIVER_IMP_INPUT_ERROR</rc>
+ <description>TBD</description>
+</hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_VOLT_TOLERATED_VOLTAGE_VIOLATION</rc>
+ <description>One or more DIMMs classified non-functional has a tolerated voltage below selected voltage.</description>
+ <!-- Deconfigure MASTER_CHIP -->
+ <deconfigure><target>MASTER_CHIP</target></deconfigure>
+</hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_DRAMINIT_TRAINING_INIT_CAL_STALLED</rc>
+ <description>One or more Rank Pairs Stalled Init Cal within Draminit_training</description>
+</hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_DRAMINIT_TRAINING_INIT_CAL_FAILED</rc>
+ <description>One or more Rank Pairs Failed Init Cal within Draminit_training</description>
+</hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_DIMM_POWER_CURVE_DATA_LAB</rc>
+ <description>DIMM power curve data is lab data not MSL</description>
+</hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_DIMM_POWER_CURVE_DATA_INVALID</rc>
+ <description>DIMM power curve data is invalid</description>
+</hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_DIMM_NOT_FOUND_IN_POWER_TABLE</rc>
+ <description>Unable to find matching entry in DIMM power table</description>
+</hwpError>
+
+ <hwpError>
+ <rc>RC_MSS_NOT_ENOUGH_AVAILABLE_DIMM_POWER</rc>
+ <description>Unable to find throttle setting that has DIMM power underneath the limit</description>
+</hwpError>
+
+<hwpError>
+ <rc>RC_MSS_INPUT_ERROR</rc>
+ <description>Invalid input </description>
+</hwpError>
+
<!-- DO NOT EDIT THIS FILE DIRECTLY PLEASE UPDATE THE ODS FILE AND FOLLOW THE INSTRUCTION TAB -->
<!-- PLEASE SEE MARK BELLOWS (BELLOWS.IBM.COM) OR OTHERS ON MEMORY TEAM FOR HELP -->
</hwpErrors>
diff --git a/src/usr/hwpf/hwp/dram_training/mss_ddr_phy_reset/mss_ddr_phy_reset.C b/src/usr/hwpf/hwp/dram_training/mss_ddr_phy_reset/mss_ddr_phy_reset.C
index 4032787f5..a6429eb1c 100644
--- a/src/usr/hwpf/hwp/dram_training/mss_ddr_phy_reset/mss_ddr_phy_reset.C
+++ b/src/usr/hwpf/hwp/dram_training/mss_ddr_phy_reset/mss_ddr_phy_reset.C
@@ -1,27 +1,26 @@
-/* IBM_PROLOG_BEGIN_TAG
- * This is an automatically generated prolog.
- *
- * $Source: src/usr/hwpf/hwp/dram_training/mss_ddr_phy_reset/mss_ddr_phy_reset.C $
- *
- * IBM CONFIDENTIAL
- *
- * COPYRIGHT International Business Machines Corp. 2012
- *
- * p1
- *
- * Object Code Only (OCO) source materials
- * Licensed Internal Code Source Materials
- * IBM HostBoot Licensed Internal Code
- *
- * The source code for this program is not published or other-
- * wise divested of its trade secrets, irrespective of what has
- * been deposited with the U.S. Copyright Office.
- *
- * Origin: 30
- *
- * IBM_PROLOG_END_TAG
- */
-// $Id: mss_ddr_phy_reset.C,v 1.11 2012/07/27 16:43:25 bellows Exp $
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/hwpf/hwp/dram_training/mss_ddr_phy_reset/mss_ddr_phy_reset.C $ */
+/* */
+/* IBM CONFIDENTIAL */
+/* */
+/* COPYRIGHT International Business Machines Corp. 2012 */
+/* */
+/* p1 */
+/* */
+/* Object Code Only (OCO) source materials */
+/* Licensed Internal Code Source Materials */
+/* IBM HostBoot Licensed Internal Code */
+/* */
+/* The source code for this program is not published or otherwise */
+/* divested of its trade secrets, irrespective of what has been */
+/* deposited with the U.S. Copyright Office. */
+/* */
+/* Origin: 30 */
+/* */
+/* IBM_PROLOG_END_TAG */
+// $Id: mss_ddr_phy_reset.C,v 1.17 2012/12/03 15:49:27 mfred Exp $
// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/centaur/working/procedures/ipl/fapi/mss_ddr_phy_reset.C,v $
//------------------------------------------------------------------------------
// *! (C) Copyright International Business Machines Corp. 2011
@@ -45,6 +44,9 @@
#include <fapi.H>
#include <cen_scom_addresses.H>
#include <mss_ddr_phy_reset.H>
+#include <mss_termination_control.H>
+#include <mss_unmask_errors.H>
+#include <dimmBadDqBitmapFuncs.H>
// Constants
const uint64_t DELAY_100NS = 100; // general purpose 100 ns delay for HW mode (2000 sim cycles if simclk = 20ghz)
@@ -64,12 +66,48 @@ extern "C" {
using namespace fapi;
- // prototype of function called in phy reset
+// prototypes of functions called in phy reset
ReturnCode mss_deassert_force_mclk_low (const Target& i_target);
-
+ReturnCode mss_ddr_phy_reset_cloned(const fapi::Target & i_target);
fapi::ReturnCode mss_ddr_phy_reset(const fapi::Target & i_target)
{
+
+ // Target is centaur.mba
+
+ fapi::ReturnCode rc;
+ fapi::ReturnCode slewcal_rc;
+
+ rc = mss_ddr_phy_reset_cloned(i_target);
+
+ slewcal_rc = mss_slew_cal(i_target);
+
+ // If mss_ddr_phy_reset returns an error
+ // then log the error from mss_slew_cal (if any) and pass the error from mss_ddr_phy_reset
+ // If only mss_slew_cal returns an error
+ // then move that error to RC and pass it along
+ if ((slewcal_rc) && (rc))
+ {
+ FAPI_ERR(" mss_slew_cal failed! rc = 0x%08X (creator = %d)", uint32_t(slewcal_rc), slewcal_rc.getCreator());
+ fapiLogError(slewcal_rc);
+ }
+ else if (slewcal_rc)
+ {
+ rc = slewcal_rc;
+ }
+
+ // If mss_unmask_ddrphy_errors gets it's own bad rc,
+ // it will commit the passed in rc (if non-zero), and return it's own bad rc.
+ // Else if mss_unmask_ddrphy_errors runs clean,
+ // it will just return the passed in rc.
+ rc = mss_unmask_ddrphy_errors(i_target, rc);
+
+ return rc;
+}
+
+
+fapi::ReturnCode mss_ddr_phy_reset_cloned(const fapi::Target & i_target)
+{
// Target is centaur.mba
fapi::ReturnCode rc;
@@ -77,26 +115,35 @@ fapi::ReturnCode mss_ddr_phy_reset(const fapi::Target & i_target)
uint32_t poll_count = 0;
uint32_t done_polling = 0;
uint8_t is_simulation = 0;
- ecmdDataBufferBase i_data, j_data, k_data, l_data;
+ ecmdDataBufferBase i_data(64);
+ ecmdDataBufferBase dp_p0_lock_data(64);
+ ecmdDataBufferBase dp_p1_lock_data(64);
+ ecmdDataBufferBase ad_p0_lock_data(64);
+ ecmdDataBufferBase ad_p1_lock_data(64);
+ uint8_t l_dqBitmap[DIMM_DQ_RANK_BITMAP_SIZE]; // 10 byte array of bad bits
+ uint8_t valid_dimms = 0;
+ uint8_t valid_dimm[2][2];
+ uint8_t num_ranks_per_dimm[2][2];
+ uint8_t l_port = 0;
+ uint8_t l_dimm = 0;
+ uint8_t l_rank = 0;
+ uint8_t new_error = 0;
+ uint8_t P0_DP0_reg_error = 0;
+ uint8_t P0_DP1_reg_error = 0;
+ uint8_t P0_DP2_reg_error = 0;
+ uint8_t P0_DP3_reg_error = 0;
+ uint8_t P0_DP4_reg_error = 0;
+ uint8_t P1_DP0_reg_error = 0;
+ uint8_t P1_DP1_reg_error = 0;
+ uint8_t P1_DP2_reg_error = 0;
+ uint8_t P1_DP3_reg_error = 0;
+ uint8_t P1_DP4_reg_error = 0;
FAPI_INF("********* mss_ddr_phy_reset start *********");
do
{
- rc_ecmd |= i_data.setBitLength(64);
- rc_ecmd |= j_data.setBitLength(64);
- rc_ecmd |= k_data.setBitLength(64);
- rc_ecmd |= l_data.setBitLength(64);
- if (rc_ecmd)
- {
- FAPI_ERR("Error 0x%x setting ecmd data buffer bit length.", rc_ecmd);
- rc.setEcmdError(rc_ecmd);
- break;
- }
-
-
-
//
// Here are the specific instructions from section 14.7.3 of the Centaur Chip Specification:
//
@@ -114,12 +161,12 @@ fapi::ReturnCode mss_ddr_phy_reset(const fapi::Target & i_target)
// PLL Lock cannot happen if mclk low is asserted
// this procedure was moved from draminit to:
// Deassert Force_mclk_low signal
- // see CQ 216395
+ // see CQ 216395 (HW217109)
rc = mss_deassert_force_mclk_low(i_target);
if(rc)
{
FAPI_ERR(" deassert_force_mclk_low Failed rc = 0x%08X (creator = %d)", uint32_t(rc), rc.getCreator());
- return rc;
+ break;
}
@@ -164,8 +211,8 @@ fapi::ReturnCode mss_ddr_phy_reset(const fapi::Target & i_target)
break;
}
-
-
+
+
//
// 3. For DD0: Deassert dfi_reset_all (GP4 bit 5 = "0")
// For DD1: Deassert mcbist_ddr_dfi_reset_recover = "0" (CCS_MODEQ(25) SCOM Addr: 0x030106A7 0x03010EA7)
@@ -193,13 +240,13 @@ fapi::ReturnCode mss_ddr_phy_reset(const fapi::Target & i_target)
//
- // 4. Write 0x0008 to PC IO PVT N/P FET driver control registers to assert ZCTL reset
- // and reset the internal impedance controller.(SCOM Addr: 0x8000C0140301143F, 0x8000C0140301183F, 0x8001C0140301143F, 0x8001C0140301183F)
- FAPI_DBG("Step 4: Write 0x0008 to PC IO PVT N/P FET driver control registers to assert ZCTL reset.\n");
- rc_ecmd |= i_data.setDoubleWord(0, 0x0000000000000008ull);
+ // 4. Write 0x0010 to PC IO PVT N/P FET driver control registers to assert ZCTL reset and enable the internal impedance controller.
+ // (SCOM Addr: 0x8000C0140301143F, 0x8000C0140301183F, 0x8001C0140301143F, 0x8001C0140301183F)
+ FAPI_DBG("Step 4: Write 0x0010 to PC IO PVT N/P FET driver control registers to assert ZCTL reset.\n");
+ rc_ecmd |= i_data.setDoubleWord(0, 0x0000000000000010ull);
if (rc_ecmd)
{
- FAPI_ERR("Error 0x%x setting up ecmd data buffer to write 0x0008 into PC_IO_PVT_FET_CONTROL regs.", rc_ecmd);
+ FAPI_ERR("Error 0x%x setting up ecmd data buffer to write 0x0010 into PC_IO_PVT_FET_CONTROL regs.", rc_ecmd);
rc.setEcmdError(rc_ecmd);
break;
}
@@ -215,17 +262,17 @@ fapi::ReturnCode mss_ddr_phy_reset(const fapi::Target & i_target)
FAPI_ERR("Error writing DPHY01_DDRPHY_PC_IO_PVT_FET_CONTROL_P1 register.");
break;
}
-
-
-
+
+
+
//
- // 5. Write 0x0000 to PC IO PVT N/P FET driver control registers to deassert ZCTL reset
- // (SCOM Addr: 0x8000C0140301143F, 0x8000C0140301183F, 0x8001C0140301143F, 0x8001C0140301183F)
- FAPI_DBG("Step 5: Write 0x0000 to PC IO PVT N/P FET driver control registers to deassert ZCTL reset.\n");
- rc_ecmd |= i_data.setDoubleWord(0, 0x0000000000000000ull);
+ // 5. Write 0x0018 to PC IO PVT N/P FET driver control registers to deassert ZCTL reset while impedance controller is still enabled.
+ // (SCOM Addr: 0x8000C0140301143F, 0x8000C0140301183F, 0x8001C0140301143F, 0x8001C0140301183F)
+ FAPI_DBG("Step 5: Write 0x0018 to PC IO PVT N/P FET driver control registers to deassert ZCTL reset.\n");
+ rc_ecmd |= i_data.setDoubleWord(0, 0x0000000000000018ull);
if (rc_ecmd)
{
- FAPI_ERR("Error 0x%x setting up ecmd data buffer to write 0x0000 into PC_IO_PVT_FET_CONTROL regs.", rc_ecmd);
+ FAPI_ERR("Error 0x%x setting up ecmd data buffer to write 0x0018 into PC_IO_PVT_FET_CONTROL regs.", rc_ecmd);
rc.setEcmdError(rc_ecmd);
break;
}
@@ -241,13 +288,39 @@ fapi::ReturnCode mss_ddr_phy_reset(const fapi::Target & i_target)
FAPI_ERR("Error writing DPHY01_DDRPHY_PC_IO_PVT_FET_CONTROL_P1 register.");
break;
}
-
-
-
+
+
+
+ //
+ // 6. Write 0x0008 to PC IO PVT N/P FET driver control registers to deassert the impedance controller.
+ // (SCOM Addr: 0x8000C0140301143F, 0x8000C0140301183F, 0x8001C0140301143F, 0x8001C0140301183F)
+ FAPI_DBG("Step 6: Write 0x0008 to PC IO PVT N/P FET driver control registers to deassert the impedance controller.\n");
+ rc_ecmd |= i_data.setDoubleWord(0, 0x0000000000000008ull);
+ if (rc_ecmd)
+ {
+ FAPI_ERR("Error 0x%x setting up ecmd data buffer to write 0x0008 into PC_IO_PVT_FET_CONTROL regs.", rc_ecmd);
+ rc.setEcmdError(rc_ecmd);
+ break;
+ }
+ rc = fapiPutScom( i_target, DPHY01_DDRPHY_PC_IO_PVT_FET_CONTROL_P0_0x8000C0140301143F, i_data);
+ if (rc)
+ {
+ FAPI_ERR("Error writing DPHY01_DDRPHY_PC_IO_PVT_FET_CONTROL_P0 register.");
+ break;
+ }
+ rc = fapiPutScom( i_target, DPHY01_DDRPHY_PC_IO_PVT_FET_CONTROL_P1_0x8001C0140301143F, i_data);
+ if (rc)
+ {
+ FAPI_ERR("Error writing DPHY01_DDRPHY_PC_IO_PVT_FET_CONTROL_P1 register.");
+ break;
+ }
+
+
+
//
- // 6. Write 0x4000 into the PC Resets Registers. This deasserts the PLL_RESET and leaves the SYSCLK_RESET bit active
+ // 7. Write 0x4000 into the PC Resets Registers. This deasserts the PLL_RESET and leaves the SYSCLK_RESET bit active
// (SCOM Addr: 0x8000C00E0301143F, 0x8001C00E0301143F, 0x8000C00E0301183F, 0x8001C00E0301183F)
- FAPI_DBG("Step 6: Write 0x4000 into the PC Resets Regs. This deasserts the PLL_RESET and leaves the SYSCLK_RESET bit active.\n");
+ FAPI_DBG("Step 7: Write 0x4000 into the PC Resets Regs. This deasserts the PLL_RESET and leaves the SYSCLK_RESET bit active.\n");
rc_ecmd |= i_data.setDoubleWord(0, 0x0000000000004000ull);
if (rc_ecmd)
{
@@ -267,15 +340,17 @@ fapi::ReturnCode mss_ddr_phy_reset(const fapi::Target & i_target)
FAPI_ERR("Error writing DPHY01_DDRPHY_PC_RESETS_P1 register.");
break;
}
-
-
-
+
+
+
//
- // 7. Wait at least 1 millisecond to allow the PLLs to lock. Otherwise, poll the PC DP18 PLL Lock Status
+ // 8. Wait at least 1 millisecond to allow the PLLs to lock. Otherwise, poll the PC DP18 PLL Lock Status
// and the PC AD32S PLL Lock Status to determine if all PLLs have locked.
// PC DP18 PLL Lock Status should be 0xF800: (SCOM Addr: 0x8000C0000301143F, 0x8001C0000301143F, 0x8000C0000301183F, 0x8001C0000301183F)
// PC AD32S PLL Lock Status should be 0xC000: (SCOM Addr: 0x8000C0010301143F, 0x8001C0010301143F, 0x8000C0010301183F, 0x8001C0010301183F)
- FAPI_DBG("Step 7: Poll until DP18 and AD32S PLLs have locked....\n");
+ //------------------------
+ // 7a - Poll for lock bits
+ FAPI_DBG("Step 8: Poll until DP18 and AD32S PLLs have locked....\n");
do
{
rc = fapiDelay(DELAY_1US, DELAY_20000SIMCYCLES); // wait 20000 simcycles (in sim mode) OR 1 usec (in hw mode)
@@ -285,74 +360,92 @@ fapi::ReturnCode mss_ddr_phy_reset(const fapi::Target & i_target)
break;
}
done_polling = 1;
- rc = fapiGetScom( i_target, DPHY01_DDRPHY_PC_DP18_PLL_LOCK_STATUS_P0_0x8000C0000301143F, i_data);
+ rc = fapiGetScom( i_target, DPHY01_DDRPHY_PC_DP18_PLL_LOCK_STATUS_P0_0x8000C0000301143F, dp_p0_lock_data);
if (rc)
{
FAPI_ERR("Error reading DPHY01_DDRPHY_PC_DP18_PLL_LOCK_STATUS_P0 register.");
break;
}
- if ( i_data.getHalfWord(3) != DP18_PLL_EXP_LOCK_STATUS ) done_polling = 0;
- rc = fapiGetScom( i_target, DPHY01_DDRPHY_PC_DP18_PLL_LOCK_STATUS_P1_0x8001C0000301143F, j_data);
+ if ( dp_p0_lock_data.getHalfWord(3) != DP18_PLL_EXP_LOCK_STATUS ) done_polling = 0;
+ rc = fapiGetScom( i_target, DPHY01_DDRPHY_PC_DP18_PLL_LOCK_STATUS_P1_0x8001C0000301143F, dp_p1_lock_data);
if (rc)
{
FAPI_ERR("Error reading DPHY01_DDRPHY_PC_DP18_PLL_LOCK_STATUS_P1 register.");
break;
}
- if ( j_data.getHalfWord(3) != DP18_PLL_EXP_LOCK_STATUS ) done_polling = 0;
- rc = fapiGetScom( i_target, DPHY01_DDRPHY_PC_AD32S_PLL_LOCK_STATUS_P0_0x8000C0010301143F, k_data);
+ if ( dp_p1_lock_data.getHalfWord(3) != DP18_PLL_EXP_LOCK_STATUS ) done_polling = 0;
+ rc = fapiGetScom( i_target, DPHY01_DDRPHY_PC_AD32S_PLL_LOCK_STATUS_P0_0x8000C0010301143F, ad_p0_lock_data);
if (rc)
{
FAPI_ERR("Error reading DPHY01_DDRPHY_PC_AD32S_PLL_LOCK_STATUS_P0 register.");
break;
}
- if ( k_data.getHalfWord(3) != AD32S_PLL_EXP_LOCK_STATUS ) done_polling = 0;
- rc = fapiGetScom( i_target, DPHY01_DDRPHY_PC_AD32S_PLL_LOCK_STATUS_P1_0x8001C0010301143F, l_data);
+ if ( ad_p0_lock_data.getHalfWord(3) != AD32S_PLL_EXP_LOCK_STATUS ) done_polling = 0;
+ rc = fapiGetScom( i_target, DPHY01_DDRPHY_PC_AD32S_PLL_LOCK_STATUS_P1_0x8001C0010301143F, ad_p1_lock_data);
if (rc)
{
FAPI_ERR("Error reading DPHY01_DDRPHY_PC_AD32S_PLL_LOCK_STATUS_P1 register.");
break;
}
- if ( l_data.getHalfWord(3) != AD32S_PLL_EXP_LOCK_STATUS ) done_polling = 0;
+ if ( ad_p1_lock_data.getHalfWord(3) != AD32S_PLL_EXP_LOCK_STATUS ) done_polling = 0;
poll_count++;
} while ((done_polling == 0) && (poll_count < MAX_POLL_LOOPS)); // Poll until PLLs are locked.
if (rc) break; // Go to end of proc if error found inside polling loop.
if (poll_count == MAX_POLL_LOOPS)
{
- if ( i_data.getHalfWord(3) != DP18_PLL_EXP_LOCK_STATUS )
+ //-------------------------------
+ // 7b - Check Port 0 DP lock bits
+ if ( dp_p0_lock_data.getHalfWord(3) != DP18_PLL_EXP_LOCK_STATUS )
{
- FAPI_ERR("DP18 0x0C000 PLL failed to lock! Lock Status = %04X",i_data.getHalfWord(3));
+ FAPI_ERR("One or more DP18 port 0 (0x0C000) PLL failed to lock! Lock Status = %04X",dp_p0_lock_data.getHalfWord(3));
FAPI_SET_HWP_ERROR(rc, RC_MSS_DP18_0_PLL_FAILED_TO_LOCK);
- break;
+ if ( dp_p0_lock_data.isBitClear(48) ) { FAPI_ERR("Port 0 DP 0 PLL failed to lock!");}
+ if ( dp_p0_lock_data.isBitClear(49) ) { FAPI_ERR("Port 0 DP 1 PLL failed to lock!");}
+ if ( dp_p0_lock_data.isBitClear(50) ) { FAPI_ERR("Port 0 DP 2 PLL failed to lock!");}
+ if ( dp_p0_lock_data.isBitClear(51) ) { FAPI_ERR("Port 0 DP 3 PLL failed to lock!");}
+ if ( dp_p0_lock_data.isBitClear(52) ) { FAPI_ERR("Port 0 DP 4 PLL failed to lock!");}
+ // break; // Don't break. Keep going to initialize any other channels that might be good.
}
- if ( j_data.getHalfWord(3) != DP18_PLL_EXP_LOCK_STATUS )
+ //-------------------------------
+ // 7c - Check Port 1 DP lock bits
+ if ( dp_p1_lock_data.getHalfWord(3) != DP18_PLL_EXP_LOCK_STATUS )
{
- FAPI_ERR("DP18 0x1C000 PLL failed to lock! Lock Status = %04X",j_data.getHalfWord(3));
+ FAPI_ERR("One or more DP18 port 1 (0x1C000) PLL failed to lock! Lock Status = %04X",dp_p1_lock_data.getHalfWord(3));
FAPI_SET_HWP_ERROR(rc, RC_MSS_DP18_1_PLL_FAILED_TO_LOCK);
- break;
+ if ( dp_p1_lock_data.isBitClear(48) ) { FAPI_ERR("Port 1 DP 0 PLL failed to lock!");}
+ if ( dp_p1_lock_data.isBitClear(49) ) { FAPI_ERR("Port 1 DP 1 PLL failed to lock!");}
+ if ( dp_p1_lock_data.isBitClear(50) ) { FAPI_ERR("Port 1 DP 2 PLL failed to lock!");}
+ if ( dp_p1_lock_data.isBitClear(51) ) { FAPI_ERR("Port 1 DP 3 PLL failed to lock!");}
+ if ( dp_p1_lock_data.isBitClear(52) ) { FAPI_ERR("Port 1 DP 4 PLL failed to lock!");}
+ // break; // Don't break. Keep going to initialize any channels that might be good.
}
- if ( k_data.getHalfWord(3) != AD32S_PLL_EXP_LOCK_STATUS )
+ //-------------------------------
+ // 7d - Check Port 0 AD lock bits
+ if ( ad_p0_lock_data.getHalfWord(3) != AD32S_PLL_EXP_LOCK_STATUS )
{
- FAPI_ERR("AD32S 0x0C001 PLL failed to lock! Lock Status = %04X",k_data.getHalfWord(3));
+ FAPI_ERR("One or more AD32S port 0 (0x0C001) PLL failed to lock! Lock Status = %04X",ad_p0_lock_data.getHalfWord(3));
FAPI_SET_HWP_ERROR(rc, RC_MSS_AD32S_0_PLL_FAILED_TO_LOCK);
break;
}
- if ( l_data.getHalfWord(3) != AD32S_PLL_EXP_LOCK_STATUS )
+ //-------------------------------
+ // 7e - Check Port 1 AD lock bits
+ if ( ad_p1_lock_data.getHalfWord(3) != AD32S_PLL_EXP_LOCK_STATUS )
{
- FAPI_ERR("AD32S 0x1C001 PLL failed to lock! Lock Status = %04X",l_data.getHalfWord(3));
+ FAPI_ERR("One or more AD32S port 1 (0x1C001) PLL failed to lock! Lock Status = %04X",ad_p1_lock_data.getHalfWord(3));
FAPI_SET_HWP_ERROR(rc, RC_MSS_AD32S_1_PLL_FAILED_TO_LOCK);
break;
}
}
else
{
- FAPI_INF("DP18 and AD32S PLLs are now locked.");
+ FAPI_INF("AD32S PLLs are now locked. DP18 PLLs should also be locked.");
}
-
-
-
+
+
+
//
- // 8.Write '8024'x into the ADR SysClk Phase Rotator Control Registers and into the DP18 SysClk Phase Rotator Control Registers.
+ // 9.Write '8024'x into the ADR SysClk Phase Rotator Control Registers and into the DP18 SysClk Phase Rotator Control Registers.
// This takes the dphy_nclk/SysClk alignment circuit out of reset and puts the dphy_nclk/SysClk alignment circuit into the Continuous Update Mode.
// ADR SysClk PR Control Registers : (SCOM Addr: 0x800080320301143F, 0x800084320301143F, 0x800180320301143F, 0x800184320301143F,
// 0x800080320301183F, 0x800084320301183F, 0x800180320301183F, 0x800184320301183F)
@@ -360,7 +453,7 @@ fapi::ReturnCode mss_ddr_phy_reset(const fapi::Target & i_target)
// 0x800000070301183F, 0x800004070301183F, 0x800008070301183F, 0x80000C070301183F, 0x800010070301183F,
// 0x800100070301143F, 0x800104070301143F, 0x800108070301143F, 0x80010C070301143F, 0x800110070301143F,
// 0x800100070301183F, 0x800104070301183F, 0x800108070301183F, 0x80010C070301183F, 0x800110070301183F)
- FAPI_DBG("Step 8: Write '8024'x into the ADR SysClk Phase Rotator Control Regs and the DP18 SysClk Phase Rotator Control Regs.\n");
+ FAPI_DBG("Step 9: Write '8024'x into the ADR SysClk Phase Rotator Control Regs and the DP18 SysClk Phase Rotator Control Regs.\n");
rc_ecmd |= i_data.setDoubleWord(0, 0x0000000000008024ull);
if (rc_ecmd)
{
@@ -392,72 +485,75 @@ fapi::ReturnCode mss_ddr_phy_reset(const fapi::Target & i_target)
FAPI_ERR("Error writing DPHY01_DDRPHY_ADR_SYSCLK_CNTL_PR_P1_ADR32S1 register.");
break;
}
+
+
+
rc = fapiPutScom( i_target, DPHY01_DDRPHY_DP18_SYSCLK_PR_P0_0_0x800000070301143F, i_data);
if (rc)
{
FAPI_ERR("Error writing DPHY01_DDRPHY_DP18_SYSCLK_PR_P0_0 register.");
- break;
+ P0_DP0_reg_error = 1;
}
rc = fapiPutScom( i_target, DPHY01_DDRPHY_DP18_SYSCLK_PR_P1_0_0x800100070301143F, i_data);
if (rc)
{
FAPI_ERR("Error writing DPHY01_DDRPHY_DP18_SYSCLK_PR_P1_0 register.");
- break;
+ P1_DP0_reg_error = 1;
}
rc = fapiPutScom( i_target, DPHY01_DDRPHY_DP18_SYSCLK_PR_P0_1_0x800004070301143F, i_data);
if (rc)
{
FAPI_ERR("Error writing DPHY01_DDRPHY_DP18_SYSCLK_PR_P0_1 register.");
- break;
+ P0_DP1_reg_error = 1;
}
rc = fapiPutScom( i_target, DPHY01_DDRPHY_DP18_SYSCLK_PR_P1_1_0x800104070301143F, i_data);
if (rc)
{
FAPI_ERR("Error writing DPHY01_DDRPHY_DP18_SYSCLK_PR_P1_1 register.");
- break;
+ P1_DP1_reg_error = 1;
}
rc = fapiPutScom( i_target, DPHY01_DDRPHY_DP18_SYSCLK_PR_P0_2_0x800008070301143F, i_data);
if (rc)
{
FAPI_ERR("Error writing DPHY01_DDRPHY_DP18_SYSCLK_PR_P0_2 register.");
- break;
+ P0_DP2_reg_error = 1;
}
rc = fapiPutScom( i_target, DPHY01_DDRPHY_DP18_SYSCLK_PR_P1_2_0x800108070301143F, i_data);
if (rc)
{
FAPI_ERR("Error writing DPHY01_DDRPHY_DP18_SYSCLK_PR_P1_2 register.");
- break;
+ P1_DP2_reg_error = 1;
}
rc = fapiPutScom( i_target, DPHY01_DDRPHY_DP18_SYSCLK_PR_P0_3_0x80000C070301143F, i_data);
if (rc)
{
FAPI_ERR("Error writing DPHY01_DDRPHY_DP18_SYSCLK_PR_P0_3 register.");
- break;
+ P0_DP3_reg_error = 1;
}
rc = fapiPutScom( i_target, DPHY01_DDRPHY_DP18_SYSCLK_PR_P1_3_0x80010C070301143F, i_data);
if (rc)
{
FAPI_ERR("Error writing DPHY01_DDRPHY_DP18_SYSCLK_PR_P1_3 register.");
- break;
+ P1_DP3_reg_error = 1;
}
rc = fapiPutScom( i_target, DPHY01_DDRPHY_DP18_SYSCLK_PR_P0_4_0x800010070301143F, i_data);
if (rc)
{
FAPI_ERR("Error writing DPHY01_DDRPHY_DP18_SYSCLK_PR_P0_4 register.");
- break;
+ P0_DP4_reg_error = 1;
}
rc = fapiPutScom( i_target, DPHY01_DDRPHY_DP18_SYSCLK_PR_P1_4_0x800110070301143F, i_data);
if (rc)
{
FAPI_ERR("Error writing DPHY01_DDRPHY_DP18_SYSCLK_PR_P1_4 register.");
- break;
+ P1_DP4_reg_error = 1;
}
-
-
-
+
+
+
//
- // 9.Wait at least 5932 memory clock cycles to allow the clock alignment circuit to perform initial alignment.
- FAPI_DBG("Step 9: Wait at least 5932 memory clock cycles to allow the clock alignment circuit to perform initial alignment.\n");
+ // 10.Wait at least 5932 memory clock cycles to allow the clock alignment circuit to perform initial alignment.
+ FAPI_DBG("Step 10: Wait at least 5932 memory clock cycles to allow the clock alignment circuit to perform initial alignment.\n");
rc = fapiDelay(DELAY_100US, DELAY_2000000SIMCYCLES); // wait 2000000 simcycles (in sim mode) OR 100 usec (in hw mode)
if (rc)
{
@@ -465,12 +561,12 @@ fapi::ReturnCode mss_ddr_phy_reset(const fapi::Target & i_target)
break;
}
-
-
+
+
//
- // 10.Write 0x0000 into the PC Resets Register. This deasserts the SysClk Reset
+ // 11.Write 0x0000 into the PC Resets Register. This deasserts the SysClk Reset
// (SCOM Addr: 0x8000C00E0301143F, 0x8001C00E0301143F, 0x8000C00E0301183F, 0x8001C00E0301183F)
- FAPI_DBG("Step 10: Write 0x0000 into the PC Resets Register. This deasserts the SysClk Reset.\n");
+ FAPI_DBG("Step 11: Write 0x0000 into the PC Resets Register. This deasserts the SysClk Reset.\n");
rc_ecmd |= i_data.setDoubleWord(0, 0x0000000000000000ull);
if (rc_ecmd)
{
@@ -490,11 +586,11 @@ fapi::ReturnCode mss_ddr_phy_reset(const fapi::Target & i_target)
FAPI_ERR("Error writing DPHY01_DDRPHY_PC_RESETS_P1 register.");
break;
}
-
-
-
+
+
+
//
- // 11.Write '8020'x into the ADR SysClk Phase Rotator Control Registers and into the DP18 SysClk Phase Rotator Control Registers.
+ // 12.Write '8020'x into the ADR SysClk Phase Rotator Control Registers and into the DP18 SysClk Phase Rotator Control Registers.
// This takes the dphy_nclk/SysClk alignment circuit out of Continuous Update Mode.
// ADR SysClk PR Control Registers : (SCOM Addr: 0x800080320301143F, 0x800084320301143F, 0x800180320301143F, 0x800184320301143F,
// 0x800080320301183F, 0x800084320301183F, 0x800180320301183F, 0x800184320301183F)
@@ -502,7 +598,7 @@ fapi::ReturnCode mss_ddr_phy_reset(const fapi::Target & i_target)
// 0x800000070301183F, 0x800004070301183F, 0x800008070301183F, 0x80000C070301183F, 0x800010070301183F,
// 0x800100070301143F, 0x800104070301143F, 0x800108070301143F, 0x80010C070301143F, 0x800110070301143F,
// 0x800100070301183F, 0x800104070301183F, 0x800108070301183F, 0x80010C070301183F, 0x800110070301183F)
- FAPI_DBG("Step 11: Write '8020'x into the ADR SysClk Phase Rotator Control Regs and the DP18 SysClk Phase Rotator Control Regs.\n");
+ FAPI_DBG("Step 12: Write '8020'x into the ADR SysClk Phase Rotator Control Regs and the DP18 SysClk Phase Rotator Control Regs.\n");
rc_ecmd |= i_data.setDoubleWord(0, 0x0000000000008020ull);
if (rc_ecmd)
{
@@ -534,65 +630,68 @@ fapi::ReturnCode mss_ddr_phy_reset(const fapi::Target & i_target)
FAPI_ERR("Error writing DPHY01_DDRPHY_ADR_SYSCLK_CNTL_PR_P1_ADR32S1 register.");
break;
}
+
+
+
rc = fapiPutScom( i_target, DPHY01_DDRPHY_DP18_SYSCLK_PR_P0_0_0x800000070301143F, i_data);
if (rc)
{
FAPI_ERR("Error writing DPHY01_DDRPHY_DP18_SYSCLK_PR_P0_0 register.");
- break;
+ P0_DP0_reg_error = 1;
}
rc = fapiPutScom( i_target, DPHY01_DDRPHY_DP18_SYSCLK_PR_P1_0_0x800100070301143F, i_data);
if (rc)
{
FAPI_ERR("Error writing DPHY01_DDRPHY_DP18_SYSCLK_PR_P1_0 register.");
- break;
+ P1_DP0_reg_error = 1;
}
rc = fapiPutScom( i_target, DPHY01_DDRPHY_DP18_SYSCLK_PR_P0_1_0x800004070301143F, i_data);
if (rc)
{
FAPI_ERR("Error writing DPHY01_DDRPHY_DP18_SYSCLK_PR_P0_1 register.");
- break;
+ P0_DP1_reg_error = 1;
}
rc = fapiPutScom( i_target, DPHY01_DDRPHY_DP18_SYSCLK_PR_P1_1_0x800104070301143F, i_data);
if (rc)
{
FAPI_ERR("Error writing DPHY01_DDRPHY_DP18_SYSCLK_PR_P1_1 register.");
- break;
+ P1_DP1_reg_error = 1;
}
rc = fapiPutScom( i_target, DPHY01_DDRPHY_DP18_SYSCLK_PR_P0_2_0x800008070301143F, i_data);
if (rc)
{
FAPI_ERR("Error writing DPHY01_DDRPHY_DP18_SYSCLK_PR_P0_2 register.");
- break;
+ P0_DP2_reg_error = 1;
}
rc = fapiPutScom( i_target, DPHY01_DDRPHY_DP18_SYSCLK_PR_P1_2_0x800108070301143F, i_data);
if (rc)
{
FAPI_ERR("Error writing DPHY01_DDRPHY_DP18_SYSCLK_PR_P1_2 register.");
- break;
+ P1_DP2_reg_error = 1;
}
rc = fapiPutScom( i_target, DPHY01_DDRPHY_DP18_SYSCLK_PR_P0_3_0x80000C070301143F, i_data);
if (rc)
{
FAPI_ERR("Error writing DPHY01_DDRPHY_DP18_SYSCLK_PR_P0_3 register.");
- break;
+ P0_DP3_reg_error = 1;
}
rc = fapiPutScom( i_target, DPHY01_DDRPHY_DP18_SYSCLK_PR_P1_3_0x80010C070301143F, i_data);
if (rc)
{
FAPI_ERR("Error writing DPHY01_DDRPHY_DP18_SYSCLK_PR_P1_3 register.");
- break;
+ P1_DP3_reg_error = 1;
}
rc = fapiPutScom( i_target, DPHY01_DDRPHY_DP18_SYSCLK_PR_P0_4_0x800010070301143F, i_data);
if (rc)
{
FAPI_ERR("Error writing DPHY01_DDRPHY_DP18_SYSCLK_PR_P0_4 register.");
- break;
+ P0_DP4_reg_error = 1;
}
rc = fapiPutScom( i_target, DPHY01_DDRPHY_DP18_SYSCLK_PR_P1_4_0x800110070301143F, i_data);
if (rc)
{
FAPI_ERR("Error writing DPHY01_DDRPHY_DP18_SYSCLK_PR_P1_4 register.");
- break;
+ P1_DP4_reg_error = 1;
}
@@ -607,7 +706,7 @@ fapi::ReturnCode mss_ddr_phy_reset(const fapi::Target & i_target)
}
if (is_simulation)
{
- FAPI_DBG("Step 11.1 (SIM ONLY): Write '8000'x into the ADR SysClk Phase Rotator Control Regs and the DP18 SysClk Phase Rotator Control Regs.\n");
+ FAPI_DBG("Step 12.1 (SIM ONLY): Write '8000'x into the ADR SysClk Phase Rotator Control Regs and the DP18 SysClk Phase Rotator Control Regs.\n");
rc_ecmd |= i_data.setDoubleWord(0, 0x0000000000008000ull);
if (rc_ecmd)
{
@@ -639,69 +738,72 @@ fapi::ReturnCode mss_ddr_phy_reset(const fapi::Target & i_target)
FAPI_ERR("Error writing DPHY01_DDRPHY_ADR_SYSCLK_CNTL_PR_P1_ADR32S1 register.");
break;
}
+
+
+
rc = fapiPutScom( i_target, DPHY01_DDRPHY_DP18_SYSCLK_PR_P0_0_0x800000070301143F, i_data);
if (rc)
{
FAPI_ERR("Error writing DPHY01_DDRPHY_DP18_SYSCLK_PR_P0_0 register.");
- break;
+ P0_DP0_reg_error = 1;
}
rc = fapiPutScom( i_target, DPHY01_DDRPHY_DP18_SYSCLK_PR_P1_0_0x800100070301143F, i_data);
if (rc)
{
FAPI_ERR("Error writing DPHY01_DDRPHY_DP18_SYSCLK_PR_P1_0 register.");
- break;
+ P1_DP0_reg_error = 1;
}
rc = fapiPutScom( i_target, DPHY01_DDRPHY_DP18_SYSCLK_PR_P0_1_0x800004070301143F, i_data);
if (rc)
{
FAPI_ERR("Error writing DPHY01_DDRPHY_DP18_SYSCLK_PR_P0_1 register.");
- break;
+ P0_DP1_reg_error = 1;
}
rc = fapiPutScom( i_target, DPHY01_DDRPHY_DP18_SYSCLK_PR_P1_1_0x800104070301143F, i_data);
if (rc)
{
FAPI_ERR("Error writing DPHY01_DDRPHY_DP18_SYSCLK_PR_P1_1 register.");
- break;
+ P1_DP1_reg_error = 1;
}
rc = fapiPutScom( i_target, DPHY01_DDRPHY_DP18_SYSCLK_PR_P0_2_0x800008070301143F, i_data);
if (rc)
{
FAPI_ERR("Error writing DPHY01_DDRPHY_DP18_SYSCLK_PR_P0_2 register.");
- break;
+ P0_DP2_reg_error = 1;
}
rc = fapiPutScom( i_target, DPHY01_DDRPHY_DP18_SYSCLK_PR_P1_2_0x800108070301143F, i_data);
if (rc)
{
FAPI_ERR("Error writing DPHY01_DDRPHY_DP18_SYSCLK_PR_P1_2 register.");
- break;
+ P1_DP2_reg_error = 1;
}
rc = fapiPutScom( i_target, DPHY01_DDRPHY_DP18_SYSCLK_PR_P0_3_0x80000C070301143F, i_data);
if (rc)
{
FAPI_ERR("Error writing DPHY01_DDRPHY_DP18_SYSCLK_PR_P0_3 register.");
- break;
+ P0_DP3_reg_error = 1;
}
rc = fapiPutScom( i_target, DPHY01_DDRPHY_DP18_SYSCLK_PR_P1_3_0x80010C070301143F, i_data);
if (rc)
{
FAPI_ERR("Error writing DPHY01_DDRPHY_DP18_SYSCLK_PR_P1_3 register.");
- break;
+ P1_DP3_reg_error = 1;
}
rc = fapiPutScom( i_target, DPHY01_DDRPHY_DP18_SYSCLK_PR_P0_4_0x800010070301143F, i_data);
if (rc)
{
FAPI_ERR("Error writing DPHY01_DDRPHY_DP18_SYSCLK_PR_P0_4 register.");
- break;
+ P0_DP4_reg_error = 1;
}
rc = fapiPutScom( i_target, DPHY01_DDRPHY_DP18_SYSCLK_PR_P1_4_0x800110070301143F, i_data);
if (rc)
{
FAPI_ERR("Error writing DPHY01_DDRPHY_DP18_SYSCLK_PR_P1_4 register.");
- break;
+ P1_DP4_reg_error = 1;
}
-
-
- FAPI_DBG("Step 11.2 (SIM ONLY): Write '8080'x into the ADR SysClk Phase Rotator Control Regs and the DP18 SysClk Phase Rotator Control Regs.\n");
+
+
+ FAPI_DBG("Step 12.2 (SIM ONLY): Write '8080'x into the ADR SysClk Phase Rotator Control Regs and the DP18 SysClk Phase Rotator Control Regs.\n");
rc_ecmd |= i_data.setDoubleWord(0, 0x0000000000008080ull);
if (rc_ecmd)
{
@@ -733,72 +835,75 @@ fapi::ReturnCode mss_ddr_phy_reset(const fapi::Target & i_target)
FAPI_ERR("Error writing DPHY01_DDRPHY_ADR_SYSCLK_CNTL_PR_P1_ADR32S1 register.");
break;
}
+
+
+
rc = fapiPutScom( i_target, DPHY01_DDRPHY_DP18_SYSCLK_PR_P0_0_0x800000070301143F, i_data);
if (rc)
{
FAPI_ERR("Error writing DPHY01_DDRPHY_DP18_SYSCLK_PR_P0_0 register.");
- break;
+ P0_DP0_reg_error = 1;
}
rc = fapiPutScom( i_target, DPHY01_DDRPHY_DP18_SYSCLK_PR_P1_0_0x800100070301143F, i_data);
if (rc)
{
FAPI_ERR("Error writing DPHY01_DDRPHY_DP18_SYSCLK_PR_P1_0 register.");
- break;
+ P1_DP0_reg_error = 1;
}
rc = fapiPutScom( i_target, DPHY01_DDRPHY_DP18_SYSCLK_PR_P0_1_0x800004070301143F, i_data);
if (rc)
{
FAPI_ERR("Error writing DPHY01_DDRPHY_DP18_SYSCLK_PR_P0_1 register.");
- break;
+ P0_DP1_reg_error = 1;
}
rc = fapiPutScom( i_target, DPHY01_DDRPHY_DP18_SYSCLK_PR_P1_1_0x800104070301143F, i_data);
if (rc)
{
FAPI_ERR("Error writing DPHY01_DDRPHY_DP18_SYSCLK_PR_P1_1 register.");
- break;
+ P1_DP1_reg_error = 1;
}
rc = fapiPutScom( i_target, DPHY01_DDRPHY_DP18_SYSCLK_PR_P0_2_0x800008070301143F, i_data);
if (rc)
{
FAPI_ERR("Error writing DPHY01_DDRPHY_DP18_SYSCLK_PR_P0_2 register.");
- break;
+ P0_DP2_reg_error = 1;
}
rc = fapiPutScom( i_target, DPHY01_DDRPHY_DP18_SYSCLK_PR_P1_2_0x800108070301143F, i_data);
if (rc)
{
FAPI_ERR("Error writing DPHY01_DDRPHY_DP18_SYSCLK_PR_P1_2 register.");
- break;
+ P1_DP2_reg_error = 1;
}
rc = fapiPutScom( i_target, DPHY01_DDRPHY_DP18_SYSCLK_PR_P0_3_0x80000C070301143F, i_data);
if (rc)
{
FAPI_ERR("Error writing DPHY01_DDRPHY_DP18_SYSCLK_PR_P0_3 register.");
- break;
+ P0_DP3_reg_error = 1;
}
rc = fapiPutScom( i_target, DPHY01_DDRPHY_DP18_SYSCLK_PR_P1_3_0x80010C070301143F, i_data);
if (rc)
{
FAPI_ERR("Error writing DPHY01_DDRPHY_DP18_SYSCLK_PR_P1_3 register.");
- break;
+ P1_DP3_reg_error = 1;
}
rc = fapiPutScom( i_target, DPHY01_DDRPHY_DP18_SYSCLK_PR_P0_4_0x800010070301143F, i_data);
if (rc)
{
FAPI_ERR("Error writing DPHY01_DDRPHY_DP18_SYSCLK_PR_P0_4 register.");
- break;
+ P0_DP4_reg_error = 1;
}
rc = fapiPutScom( i_target, DPHY01_DDRPHY_DP18_SYSCLK_PR_P1_4_0x800110070301143F, i_data);
if (rc)
{
FAPI_ERR("Error writing DPHY01_DDRPHY_DP18_SYSCLK_PR_P1_4 register.");
- break;
+ P1_DP4_reg_error = 1;
}
}
-
+
//
- // 12.Wait at least 32 memory clock cycles.
- FAPI_DBG("Step 12: Wait at least 32 memory clock cycles.\n");
+ // 13.Wait at least 32 memory clock cycles.
+ FAPI_DBG("Step 13: Wait at least 32 memory clock cycles.\n");
rc = fapiDelay(DELAY_100NS, DELAY_2000SIMCYCLES); // wait 2000 simcycles (in sim mode) OR 100 nS (in hw mode)
if (rc)
{
@@ -806,17 +911,17 @@ fapi::ReturnCode mss_ddr_phy_reset(const fapi::Target & i_target)
break;
}
-
-
+
+
//
- // 13.Write 0x0010 to PC IO PVT N/P FET driver control register to enable internal ZQ calibration.
+ // 14.Write 0x0018 to PC IO PVT N/P FET driver control register to enable internal ZQ calibration.
// This step takes approximately 2112 (64 * 33) memory clock cycles.
// (SCOM Addr: 0x8000C0140301143F, 0x8000C0140301183F, 0x8001C0140301143F, 0x8001C0140301183F)
- FAPI_DBG("Step 13: Write 0x0010 to PC IO PVT N/P FET driver control register to enable internal ZQ calibration.\n");
- rc_ecmd |= i_data.setDoubleWord(0, 0x0000000000000010ull);
+ FAPI_DBG("Step 14: Write 0x0018 to PC IO PVT N/P FET driver control register to enable internal ZQ calibration.\n");
+ rc_ecmd |= i_data.setDoubleWord(0, 0x0000000000000018ull);
if (rc_ecmd)
{
- FAPI_ERR("Error 0x%x setting up ecmd data buffer to write 0x0010 into the PC_IO_PVT_FET_CONTROL registers.", rc_ecmd);
+ FAPI_ERR("Error 0x%x setting up ecmd data buffer to write 0x0018 into the PC_IO_PVT_FET_CONTROL registers.", rc_ecmd);
rc.setEcmdError(rc_ecmd);
break;
}
@@ -835,12 +940,111 @@ fapi::ReturnCode mss_ddr_phy_reset(const fapi::Target & i_target)
+
+
+ //
+ // Now do some error checking and mark bad channels
+ // Check to see if there were any register access problems on DP registers, or corresponding PLLs that did not lock.
+ // If so, mark the DP pairs as bad.
+
+ // Loop through only valid (functional) dimms.
+ // For each valid dimm, loop through all the ranks belonging to that dimm.
+ // If there was either a register access error, or if the PLL did not lock, then mark the DP pair as bad.
+ // Do this by setting the dqBitmap attribute for all dimms and ranks associated with that PLL or register.
+ // Read the dqBitmap first, so that you do not clear values that may already be set.
+ // (Some DP channels may already be marked as bad.)
+
+ // Find out which dimms are functional
+ rc = FAPI_ATTR_GET(ATTR_MSS_EFF_DIMM_FUNCTIONAL_VECTOR, &i_target, valid_dimms);
+ if (rc)
+ {
+ FAPI_ERR("Failed to get attribute: ATTR_MSS_EFF_DIMM_FUNCTIONAL_VECTOR");
+ break;
+ }
+ valid_dimm[0][0] = (valid_dimms & 0x80);
+ valid_dimm[0][1] = (valid_dimms & 0x40);
+ valid_dimm[1][0] = (valid_dimms & 0x08);
+ valid_dimm[1][1] = (valid_dimms & 0x04);
+
+ // Find out how many ranks are on each dimm
+ rc = FAPI_ATTR_GET( ATTR_EFF_NUM_RANKS_PER_DIMM, &i_target, num_ranks_per_dimm);
+ if (rc)
+ {
+ FAPI_ERR("Failed to get attribute: ATTR_EFF_NUM_RANKS_PER_DIMM.");
+ break;
+ }
+
+
+ // Loop through each PORT (0,1)
+ for(l_port=0; l_port<1; l_port++ )
+ {
+ // Loop through each DIMM:(0,1)
+ for(l_dimm=0; l_dimm<DIMM_DQ_MAX_MBAPORT_DIMMS; l_dimm++ )
+ {
+ if (valid_dimm[l_port][l_dimm])
+ {
+ // Ok, this DIMM is functional. So loop through the RANKs of this dimm.
+ for(l_rank=0; l_rank<num_ranks_per_dimm[l_port][l_dimm]; l_rank++ )
+ {
+ // Get the bad DQ Bitmap for l_port, l_dimm, l_rank
+ rc = dimmGetBadDqBitmap(i_target,
+ l_port,
+ l_dimm,
+ l_rank,
+ l_dqBitmap);
+ if (rc)
+ {
+ FAPI_ERR("Error from dimmGetBadDqBitmap");
+ break;
+ }
+
+ // Mark the bad bits for each register that had problems or PLL that did not lock
+ new_error = 0;
+ if ( l_port == 0 )
+ {
+ if (( P0_DP0_reg_error == 1 ) || ( dp_p0_lock_data.isBitClear(48) )) { l_dqBitmap[0] = 0xff; l_dqBitmap[1] = 0xff; new_error = 1; }
+ if (( P0_DP1_reg_error == 1 ) || ( dp_p0_lock_data.isBitClear(49) )) { l_dqBitmap[2] = 0xff; l_dqBitmap[3] = 0xff; new_error = 1; }
+ if (( P0_DP2_reg_error == 1 ) || ( dp_p0_lock_data.isBitClear(50) )) { l_dqBitmap[4] = 0xff; l_dqBitmap[5] = 0xff; new_error = 1; }
+ if (( P0_DP3_reg_error == 1 ) || ( dp_p0_lock_data.isBitClear(51) )) { l_dqBitmap[6] = 0xff; l_dqBitmap[7] = 0xff; new_error = 1; }
+ if (( P0_DP4_reg_error == 1 ) || ( dp_p0_lock_data.isBitClear(52) )) { l_dqBitmap[8] = 0xff; l_dqBitmap[9] = 0xff; new_error = 1; }
+ } else {
+ if (( P1_DP0_reg_error == 1 ) || ( dp_p1_lock_data.isBitClear(48) )) { l_dqBitmap[0] = 0xff; l_dqBitmap[1] = 0xff; new_error = 1; }
+ if (( P1_DP1_reg_error == 1 ) || ( dp_p1_lock_data.isBitClear(49) )) { l_dqBitmap[2] = 0xff; l_dqBitmap[3] = 0xff; new_error = 1; }
+ if (( P1_DP2_reg_error == 1 ) || ( dp_p1_lock_data.isBitClear(50) )) { l_dqBitmap[4] = 0xff; l_dqBitmap[5] = 0xff; new_error = 1; }
+ if (( P1_DP3_reg_error == 1 ) || ( dp_p1_lock_data.isBitClear(51) )) { l_dqBitmap[6] = 0xff; l_dqBitmap[7] = 0xff; new_error = 1; }
+ if (( P1_DP4_reg_error == 1 ) || ( dp_p1_lock_data.isBitClear(52) )) { l_dqBitmap[8] = 0xff; l_dqBitmap[9] = 0xff; new_error = 1; }
+ }
+
+ // If there are new errors, write back the bad DQ Bitmap for l_port, l_dimm, l_rank
+ if ( new_error == 1 )
+ {
+ rc = dimmSetBadDqBitmap(i_target,
+ l_port,
+ l_dimm,
+ l_rank,
+ l_dqBitmap);
+ if (rc)
+ {
+ FAPI_ERR("Error from dimmPutBadDqBitmap");
+ break;
+ }
+ }
+ } // End of loop over RANKs
+ if (rc) break; // Go to end of proc if error found inside loop.
+ }
+ } // End of loop over DIMMs
+ if (rc) break; // Go to end of proc if error found inside loop.
+ } // End of loop over PORTs
+
+
} while(0);
FAPI_INF("********* mss_ddr_phy_reset complete *********");
+
return rc;
}
+
// function moved from draminit because we need mclk low not asserted for pll locking
ReturnCode mss_deassert_force_mclk_low (const Target& i_target)
{
@@ -875,6 +1079,25 @@ This section is automatically updated by CVS when you check in this file.
Be sure to create CVS comments when you commit so that they can be included here.
$Log: mss_ddr_phy_reset.C,v $
+Revision 1.17 2012/12/03 15:49:27 mfred
+Fixed bug to allow exit from loops in case of error.
+
+Revision 1.16 2012/11/29 23:02:53 mfred
+Fix for ZQ_CAL workaround and support for partial set of dimms.
+
+Revision 1.15 2012/11/16 16:36:20 mfred
+Update code to return an error from mss_slew_cal, if any, unless there is an error from mss_ddr_phy_reset.
+
+Revision 1.14 2012/11/14 23:42:43 mfred
+Call mss_slew_cal after the ddr_phy_reset steps.
+
+Revision 1.13 2012/10/19 20:27:26 mfred
+Added support for sub-partial-good operation when only a subset of DPs are good.
+
+Revision 1.12 2012/09/06 15:01:46 gollub
+
+Calling mss_unmask_ddrphy_errors after mss_ddr_phy_reser_cloned.
+
Revision 1.11 2012/07/27 16:43:25 bellows
CQ216395 hardware needs force mclk low in phy reset procedure
diff --git a/src/usr/hwpf/hwp/dram_training/mss_ddr_phy_reset/mss_termination_control.C b/src/usr/hwpf/hwp/dram_training/mss_ddr_phy_reset/mss_termination_control.C
new file mode 100644
index 000000000..940fb703b
--- /dev/null
+++ b/src/usr/hwpf/hwp/dram_training/mss_ddr_phy_reset/mss_termination_control.C
@@ -0,0 +1,1408 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/hwpf/hwp/dram_training/mss_ddr_phy_reset/mss_termination_control.C $ */
+/* */
+/* IBM CONFIDENTIAL */
+/* */
+/* COPYRIGHT International Business Machines Corp. 2012 */
+/* */
+/* p1 */
+/* */
+/* Object Code Only (OCO) source materials */
+/* Licensed Internal Code Source Materials */
+/* IBM HostBoot Licensed Internal Code */
+/* */
+/* The source code for this program is not published or otherwise */
+/* divested of its trade secrets, irrespective of what has been */
+/* deposited with the U.S. Copyright Office. */
+/* */
+/* Origin: 30 */
+/* */
+/* IBM_PROLOG_END_TAG */
+// $Id: mss_termination_control.C,v 1.11 2012/12/06 19:16:38 sasethur Exp $
+/* File is created by SARAVANAN SETHURAMAN on Thur 29 Sept 2011. */
+
+//------------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2007
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//------------------------------------------------------------------------------
+// *! TITLE :mss_draminit_training_advanced.C
+// *! DESCRIPTION : Tools for centaur procedures
+// *! OWNER NAME : Saravanan Sethuraman email ID:saravanans@in.ibm.com
+// *! BACKUP NAME: Menlo Wuu email ID:menlowuu@us.ibm.com
+// #! ADDITIONAL COMMENTS :
+//
+// General purpose funcs
+
+//------------------------------------------------------------------------------
+// Don't forget to create CVS comments when you check in your changes!
+//------------------------------------------------------------------------------
+// CHANGE HISTORY:
+//------------------------------------------------------------------------------
+// Version:| Author: | Date: | Comment:
+//---------|----------|---------|-----------------------------------------------
+// 1.11 | sasethur |07-Dec-12| Updated for fw review comments
+// 1.10 | mwuu |28-Nov-12| Added changes suggested from FW team.
+// 1.9 | mwuu |20-Nov-12| Changed warning status to not cause error.
+// 1.8 | sasethur |19-Nov-12| Updated for fw review comments
+// 1.7 | mwuu |14-Nov-12| Switched some old attributes to new, added
+// Partial good support in slew_cal FN.
+// 1.6 | bellows |13-Nov-12| SI attribute Updates
+// 1.5 | mwuu |29-Oct-12| fixed config_drv_imp missed a '&'
+// 1.4 | mwuu |26-Oct-12| Added mss_slew_cal FN, not 100% complete
+// 1.3 | sasethur |26-Oct-12| Updated FW review comments - fapi::, const fapi:: Target
+// 1.2 | mwuu |17-Oct-12| Updated return codes to use common error, also
+// updates to the slew function
+// 1.1 | sasethur |15-Oct-12| Functions defined & moved from training adv,
+// Menlo upated slew function
+
+// Saravanan - Yet to update DRV_IMP new attribute enum change
+
+// Not supported
+// DDR4, DIMM Types
+//----------------------------------------------------------------------
+// Includes - FAPI
+//----------------------------------------------------------------------
+
+#include <fapi.H>
+
+//----------------------------------------------------------------------
+//Centaur functions
+//----------------------------------------------------------------------
+#include <mss_termination_control.H>
+#include <cen_scom_addresses.H>
+//#include <mss_draminit_training_advanced.H>
+
+/*------------------------------------------------------------------------------
+ * Function: config_drv_imp()
+ * This function will configure the Driver impedance values to the registers
+ *
+ * Parameters: target: mba; port: 0, 1
+ * Driver_imp: OHM24 = 24, OHM30 = 30, OHM34 = 34, OHM40 = 40
+ * ---------------------------------------------------------------------------*/
+
+fapi::ReturnCode config_drv_imp(const fapi::Target & i_target_mba, uint8_t i_port, uint8_t i_drv_imp_dq_dqs)
+{
+
+ ecmdDataBufferBase data_buffer(64);
+ fapi::ReturnCode rc;
+ fapi::ReturnCode rc_buff;
+ uint32_t rc_num = 0;
+ uint8_t enslice_drv = 0xFF;
+ uint8_t enslice_ffedrv = 0xF;
+ uint8_t i = 0;
+
+ //Driver impedance settings are per PORT basis
+
+ if (i_port > 1)
+ {
+ FAPI_ERR("Driver impedance port input(%u) out of bounds", i_port);
+ FAPI_SET_HWP_ERROR(rc, RC_MSS_INVALID_FN_INPUT_ERROR);
+ return rc;
+ }
+ for(i=0; i< MAX_DRV_IMP; i++)
+ {
+ if (drv_imp_array[i] == i_drv_imp_dq_dqs)
+ {
+ switch (i)
+ {
+ case 0: //40 ohms
+ enslice_drv = 0x3C;
+ enslice_ffedrv =0xF;
+ break;
+ case 1: //34 ohms
+ enslice_drv = 0x7C;
+ enslice_ffedrv =0xF;
+ break;
+ case 2: //30 ohms
+ enslice_drv = 0x7E;
+ enslice_ffedrv = 0xF;
+ break;
+ case 3: //24 ohms
+ enslice_drv = 0xFF;
+ enslice_ffedrv = 0xF;
+ break;
+ }
+ break;
+ }
+ }
+
+ if (i_port == 0)
+ {
+ rc = fapiGetScom(i_target_mba,
+ DPHY01_DDRPHY_DP18_IO_TX_NFET_SLICE_P0_0_0x800000780301143F,
+ data_buffer); if(rc) return rc;
+ rc_num = data_buffer.insertFromRight(enslice_drv,48,8);
+ rc_num = rc_num | data_buffer.insertFromRight(enslice_ffedrv,56,4);
+ if (rc_num)
+ {
+ FAPI_ERR( "config_rd_vref: Error in setting up buffer ");
+ rc_buff.setEcmdError(rc_num);
+ return rc_buff;
+ }
+ rc = fapiPutScom(i_target_mba,
+ DPHY01_DDRPHY_DP18_IO_TX_NFET_SLICE_P0_0_0x800000780301143F,
+ data_buffer); if(rc) return rc;
+ rc = fapiPutScom(i_target_mba,
+ DPHY01_DDRPHY_DP18_IO_TX_NFET_SLICE_P0_1_0x800004780301143F,
+ data_buffer); if(rc) return rc;
+ rc = fapiPutScom(i_target_mba,
+ DPHY01_DDRPHY_DP18_IO_TX_NFET_SLICE_P0_2_0x800008780301143F,
+ data_buffer); if(rc) return rc;
+ rc = fapiPutScom(i_target_mba,
+ DPHY01_DDRPHY_DP18_IO_TX_NFET_SLICE_P0_3_0x80000C780301143F,
+ data_buffer); if(rc) return rc;
+ rc = fapiPutScom(i_target_mba,
+ DPHY01_DDRPHY_DP18_IO_TX_NFET_SLICE_P0_4_0x800010780301143F,
+ data_buffer); if(rc) return rc;
+ rc = fapiPutScom(i_target_mba,
+ DPHY01_DDRPHY_DP18_IO_TX_PFET_SLICE_P0_0_0x800000790301143F,
+ data_buffer); if(rc) return rc;
+ rc = fapiPutScom(i_target_mba,
+ DPHY01_DDRPHY_DP18_IO_TX_PFET_SLICE_P0_1_0x800004790301143F,
+ data_buffer); if(rc) return rc;
+ rc = fapiPutScom(i_target_mba,
+ DPHY01_DDRPHY_DP18_IO_TX_PFET_SLICE_P0_2_0x800008790301143F,
+ data_buffer); if(rc) return rc;
+ rc = fapiPutScom(i_target_mba,
+ DPHY01_DDRPHY_DP18_IO_TX_PFET_SLICE_P0_3_0x80000C790301143F,
+ data_buffer); if(rc) return rc;
+ rc = fapiPutScom(i_target_mba,
+ DPHY01_DDRPHY_DP18_IO_TX_PFET_SLICE_P0_4_0x800010790301143F,
+ data_buffer); if(rc) return rc;
+ }
+ else // Port = 1
+ {
+ rc = fapiGetScom(i_target_mba,
+ DPHY01_DDRPHY_DP18_IO_TX_NFET_SLICE_P1_0_0x800100780301143F,
+ data_buffer); if(rc) return rc;
+ rc_num = data_buffer.insertFromRight(enslice_drv,48,8);
+ rc_num = rc_num | data_buffer.insertFromRight(enslice_ffedrv,56,4);
+ if (rc_num)
+ {
+ FAPI_ERR( "config_rd_vref: Error in setting up buffer ");
+ rc_buff.setEcmdError(rc_num);
+ return rc_buff;
+ }
+ rc = fapiPutScom(i_target_mba,
+ DPHY01_DDRPHY_DP18_IO_TX_NFET_SLICE_P1_0_0x800100780301143F,
+ data_buffer); if(rc) return rc;
+ rc = fapiPutScom(i_target_mba,
+ DPHY01_DDRPHY_DP18_IO_TX_NFET_SLICE_P1_1_0x800104780301143F,
+ data_buffer); if(rc) return rc;
+ rc = fapiPutScom(i_target_mba,
+ DPHY01_DDRPHY_DP18_IO_TX_NFET_SLICE_P1_2_0x800108780301143F,
+ data_buffer); if(rc) return rc;
+ rc = fapiPutScom(i_target_mba,
+ DPHY01_DDRPHY_DP18_IO_TX_NFET_SLICE_P1_3_0x80010C780301143F,
+ data_buffer); if(rc) return rc;
+ rc = fapiPutScom(i_target_mba,
+ DPHY01_DDRPHY_DP18_IO_TX_NFET_SLICE_P1_4_0x800110780301143F,
+ data_buffer); if(rc) return rc;
+ rc = fapiPutScom(i_target_mba,
+ DPHY01_DDRPHY_DP18_IO_TX_PFET_SLICE_P1_0_0x800100790301143F,
+ data_buffer); if(rc) return rc;
+ rc = fapiPutScom(i_target_mba,
+ DPHY01_DDRPHY_DP18_IO_TX_PFET_SLICE_P1_1_0x800104790301143F,
+ data_buffer); if(rc) return rc;
+ rc = fapiPutScom(i_target_mba,
+ DPHY01_DDRPHY_DP18_IO_TX_PFET_SLICE_P1_2_0x800108790301143F,
+ data_buffer); if(rc) return rc;
+ rc = fapiPutScom(i_target_mba,
+ DPHY01_DDRPHY_DP18_IO_TX_PFET_SLICE_P1_3_0x80010C790301143F,
+ data_buffer); if(rc) return rc;
+ rc = fapiPutScom(i_target_mba,
+ DPHY01_DDRPHY_DP18_IO_TX_PFET_SLICE_P1_4_0x800110790301143F,
+ data_buffer); if(rc) return rc;
+ }
+ return rc;
+}
+
+
+/*------------------------------------------------------------------------------
+ * Function: config_rcv_imp()
+ * This function will configure the Receiver impedance values to the registers
+ *
+ * Parameters: target: mba; port: 0, 1
+ * receiver_imp:OHM15 = 15, OHM20 = 20, OHM30 = 30, OHM40 = 40, OHM48 = 48,
+ * OHM60 = 60, OHM80 = 80, OHM120 = 120, OHM160 = 160, OHM240 = 240
+ * ---------------------------------------------------------------------------*/
+
+fapi::ReturnCode config_rcv_imp(const fapi::Target & i_target_mba, uint8_t i_port, uint8_t i_rcv_imp_dq_dqs)
+{
+
+ ecmdDataBufferBase data_buffer(64);
+ fapi::ReturnCode rc;
+ fapi::ReturnCode rc_buff;
+ uint32_t rc_num = 0;
+ uint8_t enslicepterm = 0xFF;
+ uint8_t enslicepffeterm = 0;
+ uint8_t i = 0;
+
+ if (i_port > 1)
+ {
+ FAPI_ERR("Receiver impedance port input(%u) out of bounds", i_port);
+ FAPI_SET_HWP_ERROR(rc, RC_MSS_INVALID_FN_INPUT_ERROR);
+ return rc;
+ }
+
+
+ for(i=0; i< MAX_RCV_IMP; i++)
+ {
+ if (rcv_imp_array[i] == i_rcv_imp_dq_dqs)
+ {
+ switch (i)
+ {
+ case 0: //120 OHMS
+ enslicepterm = 0x10;
+ enslicepffeterm =0x0;
+ break;
+ case 1: //80 OHMS
+ enslicepterm = 0x10;
+ enslicepffeterm =0x2;
+ break;
+ case 2: //60 OHMS
+ enslicepterm = 0x18;
+ enslicepffeterm =0x0;
+ break;
+ case 3: //48 OHMS
+ enslicepterm = 0x18;
+ enslicepffeterm =0x2;
+ break;
+ case 4: //40 OHMS
+ enslicepterm = 0x18;
+ enslicepffeterm =0x6;
+ break;
+ case 5: //34 OHMS
+ enslicepterm = 0x38;
+ enslicepffeterm =0x2;
+ break;
+ case 6: //30 OHMS
+ enslicepterm = 0x3C;
+ enslicepffeterm =0x0;
+ break;
+ case 7: //20 OHMS
+ enslicepterm = 0x7E;
+ enslicepffeterm = 0x0;
+ break;
+ case 8: //15 OHMS
+ enslicepterm = 0xFF;
+ enslicepffeterm = 0x0;
+ break;
+ }
+ break;
+ }
+ }
+
+
+ if (i_port == 0)
+ {
+ rc = fapiGetScom(i_target_mba,
+ DPHY01_DDRPHY_DP18_IO_TX_NFET_TERM_P0_0_0x8000007A0301143F,
+ data_buffer); if(rc) return rc;
+ rc_num = data_buffer.insertFromRight(enslicepterm,48,8);
+ rc_num = rc_num | data_buffer.insertFromRight(enslicepffeterm,56,4);
+ if (rc_num)
+ {
+ FAPI_ERR( "config_drv_imp: Error in setting up buffer ");
+ rc_buff.setEcmdError(rc_num);
+ return rc_buff;
+ }
+ rc = fapiPutScom(i_target_mba,
+ DPHY01_DDRPHY_DP18_IO_TX_NFET_TERM_P0_0_0x8000007A0301143F,
+ data_buffer); if(rc) return rc;
+ rc = fapiPutScom(i_target_mba,
+ DPHY01_DDRPHY_DP18_IO_TX_NFET_TERM_P0_1_0x8000047A0301143F,
+ data_buffer); if(rc) return rc;
+ rc = fapiPutScom(i_target_mba,
+ DPHY01_DDRPHY_DP18_IO_TX_NFET_TERM_P0_2_0x8000087A0301143F,
+ data_buffer); if(rc) return rc;
+ rc = fapiPutScom(i_target_mba,
+ DPHY01_DDRPHY_DP18_IO_TX_NFET_TERM_P0_3_0x80000C7A0301143F,
+ data_buffer); if(rc) return rc;
+ rc = fapiPutScom(i_target_mba,
+ DPHY01_DDRPHY_DP18_IO_TX_NFET_TERM_P0_4_0x8000107A0301143F,
+ data_buffer); if(rc) return rc;
+ rc = fapiPutScom(i_target_mba,
+ DPHY01_DDRPHY_DP18_IO_TX_PFET_TERM_P0_0_0x8000007B0301143F,
+ data_buffer); if(rc) return rc;
+ rc = fapiPutScom(i_target_mba,
+ DPHY01_DDRPHY_DP18_IO_TX_PFET_TERM_P0_1_0x8000047B0301143F,
+ data_buffer); if(rc) return rc;
+ rc = fapiPutScom(i_target_mba,
+ DPHY01_DDRPHY_DP18_IO_TX_PFET_TERM_P0_2_0x8000087B0301143F,
+ data_buffer); if(rc) return rc;
+ rc = fapiPutScom(i_target_mba,
+ DPHY01_DDRPHY_DP18_IO_TX_PFET_TERM_P0_3_0x80000C7B0301143F,
+ data_buffer); if(rc) return rc;
+ rc = fapiPutScom(i_target_mba,
+ DPHY01_DDRPHY_DP18_IO_TX_PFET_TERM_P0_4_0x8000107B0301143F,
+ data_buffer); if(rc) return rc;
+ }
+ else
+ {
+ rc = fapiGetScom(i_target_mba,
+ DPHY01_DDRPHY_DP18_IO_TX_NFET_TERM_P1_0_0x8001007A0301143F,
+ data_buffer); if(rc) return rc;
+ rc_num = data_buffer.insertFromRight(enslicepterm,48,8);
+ rc_num = rc_num | data_buffer.insertFromRight(enslicepffeterm,56,4);
+ if (rc_num)
+ {
+ FAPI_ERR( "config_drv_imp: Error in setting up buffer ");
+ rc_buff.setEcmdError(rc_num);
+ return rc_buff;
+ }
+ rc = fapiPutScom(i_target_mba,
+ DPHY01_DDRPHY_DP18_IO_TX_NFET_TERM_P1_0_0x8001007A0301143F,
+ data_buffer); if(rc) return rc;
+ rc = fapiPutScom(i_target_mba,
+ DPHY01_DDRPHY_DP18_IO_TX_NFET_TERM_P1_1_0x8001047A0301143F,
+ data_buffer); if(rc) return rc;
+ rc = fapiPutScom(i_target_mba,
+ DPHY01_DDRPHY_DP18_IO_TX_NFET_TERM_P1_2_0x8001087A0301143F,
+ data_buffer); if(rc) return rc;
+ rc = fapiPutScom(i_target_mba,
+ DPHY01_DDRPHY_DP18_IO_TX_NFET_TERM_P1_3_0x80010C7A0301143F,
+ data_buffer); if(rc) return rc;
+ rc = fapiPutScom(i_target_mba,
+ DPHY01_DDRPHY_DP18_IO_TX_NFET_TERM_P1_4_0x8001107A0301143F,
+ data_buffer); if(rc) return rc;
+ rc = fapiPutScom(i_target_mba,
+ DPHY01_DDRPHY_DP18_IO_TX_PFET_TERM_P1_0_0x8001007B0301143F,
+ data_buffer); if(rc) return rc;
+ rc = fapiPutScom(i_target_mba,
+ DPHY01_DDRPHY_DP18_IO_TX_PFET_TERM_P1_1_0x8001047B0301143F,
+ data_buffer); if(rc) return rc;
+ rc = fapiPutScom(i_target_mba,
+ DPHY01_DDRPHY_DP18_IO_TX_PFET_TERM_P1_2_0x8001087B0301143F,
+ data_buffer); if(rc) return rc;
+ rc = fapiPutScom(i_target_mba,
+ DPHY01_DDRPHY_DP18_IO_TX_PFET_TERM_P1_3_0x80010C7B0301143F,
+ data_buffer); if(rc) return rc;
+ rc = fapiPutScom(i_target_mba,
+ DPHY01_DDRPHY_DP18_IO_TX_PFET_TERM_P1_4_0x8001107B0301143F,
+ data_buffer); if(rc) return rc;
+ }
+ return rc;
+}
+
+/*------------------------------------------------------------------------------
+ * Function: config_slew_rate()
+ * This function will configure the Slew rate values to the registers
+ *
+ * Parameters: target: mba; port: 0, 1
+ * i_slew_type: SLEW_TYPE_DATA=0, SLEW_TYPE_ADR_ADDR=1, SLEW_TYPE_ADR_CNTL=2
+ * i_slew_imp: OHM15=15, OHM20=20, OHM24=24, OHM30=30, OHM34=34, OHM40=40
+ * note: 15, 20, 30, 40 valid for ADR; 24, 30, 34, 40 valid for DATA
+ * i_slew_rate: SLEW_3V_NS=3, SLEW_4V_NS=4, SLEW_5V_NS=5, SLEW_6V_NS=6,
+ * SLEW_MAXV_NS=7 (note SLEW_MAXV_NS bypasses slew calibration.)
+ * ---------------------------------------------------------------------------*/
+fapi::ReturnCode config_slew_rate(const fapi::Target & i_target_mba,
+ const uint8_t i_port, const uint8_t i_slew_type, const uint8_t i_slew_imp,
+ const uint8_t i_slew_rate)
+{
+ fapi::ReturnCode rc;
+ fapi::ReturnCode rc_buff;
+ ecmdDataBufferBase data_buffer(64);
+ uint32_t rc_num = 0;
+ uint8_t slew_cal_value = 0;
+ uint8_t imp_idx = 255;
+ uint8_t slew_idx = 255;
+ // array for ATTR_MSS_SLEW_RATE_DATA/ADR [2][4][4]
+ // port,imp,slew_rat cal'd slew settings
+ uint8_t calibrated_slew_rate_table
+ [MAX_NUM_PORTS][MAX_NUM_IMP][MAX_NUM_CAL_SLEW_RATES]={{{0}}};
+
+ if (i_port >= MAX_NUM_PORTS)
+ {
+ FAPI_ERR("Slew port input(%u) out of bounds", i_port);
+ FAPI_SET_HWP_ERROR(rc, RC_MSS_INVALID_FN_INPUT_ERROR);
+ return rc;
+ }
+
+ if (i_slew_type >= MAX_NUM_SLEW_TYPES)
+ {
+ FAPI_ERR("Slew type input(%u) out of bounds, (>= %u)",
+ i_slew_type, MAX_NUM_SLEW_TYPES);
+ FAPI_SET_HWP_ERROR(rc, RC_MSS_INVALID_FN_INPUT_ERROR);
+ return rc;
+ }
+
+ switch (i_slew_rate) // get slew index
+ {
+ case SLEW_MAXV_NS: // max slew
+ FAPI_INF("Slew rate is set to MAX, using bypass mode");
+ slew_cal_value = 0; // slew cal value for bypass mode
+ break;
+ case SLEW_6V_NS:
+ slew_idx = 3;
+ break;
+ case SLEW_5V_NS:
+ slew_idx = 2;
+ break;
+ case SLEW_4V_NS:
+ slew_idx = 1;
+ break;
+ case SLEW_3V_NS:
+ slew_idx = 0;
+ break;
+ default:
+ FAPI_ERR("Slew rate input(%u) out of bounds", i_slew_rate);
+ FAPI_SET_HWP_ERROR(rc, RC_MSS_INVALID_FN_INPUT_ERROR);
+ return rc;
+ }
+
+ if (i_slew_type == SLEW_TYPE_DATA)
+ {
+ FAPI_INF("Setting data (dq/dqs) slew");
+ switch (i_slew_imp) // get impedance index for data
+ {
+ case OHM40:
+ imp_idx = 3;
+ break;
+ case OHM34:
+ imp_idx = 2;
+ break;
+ case OHM30:
+ imp_idx = 1;
+ break;
+ case OHM24:
+ imp_idx = 0;
+ break;
+ default: // OHM15 || OHM20 not valid for data
+ FAPI_ERR("Slew impedance input(%u) invalid "
+ "or out of bounds, index=%u", i_slew_imp, imp_idx);
+ FAPI_SET_HWP_ERROR(rc, RC_MSS_IMP_INPUT_ERROR);
+ return rc;
+ }
+
+ if (i_slew_rate != SLEW_MAXV_NS)
+ {
+ rc = FAPI_ATTR_GET(ATTR_MSS_SLEW_RATE_DATA, &i_target_mba,
+ calibrated_slew_rate_table); if(rc) return rc;
+
+ slew_cal_value =
+ calibrated_slew_rate_table[i_port][imp_idx][slew_idx];
+ }
+
+ FAPI_DBG("port%u type=%u imp_idx=%u slew_idx=%u cal_slew=%u",
+ i_port, i_slew_type, imp_idx, slew_idx, slew_cal_value);
+
+ if (slew_cal_value > MAX_SLEW_VALUE)
+ {
+ FAPI_ERR("!! Slew rate(0x%02x) unsupported, but continuining... !!",
+ slew_cal_value);
+ slew_cal_value = slew_cal_value & 0x0F;
+ }
+
+ if (i_port == 0) // port dq/dqs slew
+ {
+ rc = fapiGetScom(i_target_mba,
+ DPHY01_DDRPHY_DP18_IO_TX_CONFIG0_P0_0_0x800000750301143F,
+ data_buffer); if(rc) return rc;
+
+ rc_num = rc_num | data_buffer.insertFromRight(slew_cal_value, 56, 4);
+ if (rc_num)
+ {
+ FAPI_ERR("Error in setting up DATA slew buffer");
+ rc_buff.setEcmdError(rc_num);
+ return rc_buff;
+ }
+
+ rc = fapiPutScom(i_target_mba,
+ DPHY01_DDRPHY_DP18_IO_TX_CONFIG0_P0_0_0x800000750301143F,
+ data_buffer); if(rc) return rc;
+ rc = fapiPutScom(i_target_mba,
+ DPHY01_DDRPHY_DP18_IO_TX_CONFIG0_P0_1_0x800004750301143F,
+ data_buffer); if(rc) return rc;
+ rc = fapiPutScom(i_target_mba,
+ DPHY01_DDRPHY_DP18_IO_TX_CONFIG0_P0_2_0x800008750301143F,
+ data_buffer); if(rc) return rc;
+ rc = fapiPutScom(i_target_mba,
+ DPHY01_DDRPHY_DP18_IO_TX_CONFIG0_P0_3_0x80000C750301143F,
+ data_buffer); if(rc) return rc;
+ rc = fapiPutScom(i_target_mba,
+ DPHY01_DDRPHY_DP18_IO_TX_CONFIG0_P0_4_0x800010750301143F,
+ data_buffer); if(rc) return rc;
+ }
+ else // port 1 dq/dqs slew
+ {
+ rc = fapiGetScom(i_target_mba,
+ DPHY01_DDRPHY_DP18_IO_TX_CONFIG0_P1_0_0x800100750301143F,
+ data_buffer); if(rc) return rc;
+
+ rc_num = rc_num | data_buffer.insertFromRight(slew_cal_value,56,4);
+ if (rc_num)
+ {
+ FAPI_ERR( "Error in setting up DATA slew buffer");
+ rc_buff.setEcmdError(rc_num);
+ return rc_buff;
+ }
+
+ rc = fapiPutScom(i_target_mba,
+ DPHY01_DDRPHY_DP18_IO_TX_CONFIG0_P1_0_0x800100750301143F,
+ data_buffer); if(rc) return rc;
+ rc = fapiPutScom(i_target_mba,
+ DPHY01_DDRPHY_DP18_IO_TX_CONFIG0_P1_1_0x800104750301143F,
+ data_buffer); if(rc) return rc;
+ rc = fapiPutScom(i_target_mba,
+ DPHY01_DDRPHY_DP18_IO_TX_CONFIG0_P1_2_0x800108750301143F,
+ data_buffer); if(rc) return rc;
+ rc = fapiPutScom(i_target_mba,
+ DPHY01_DDRPHY_DP18_IO_TX_CONFIG0_P1_3_0x80010C750301143F,
+ data_buffer); if(rc) return rc;
+ rc = fapiPutScom(i_target_mba,
+ DPHY01_DDRPHY_DP18_IO_TX_CONFIG0_P1_4_0x800110750301143F,
+ data_buffer); if(rc) return rc;
+ }
+ }
+ else // Slew type = ADR
+ {
+ uint8_t adr_pos = 48; // SLEW_CTL0(48:51) of reg for ADR command slew
+
+ switch (i_slew_type) // get impedance index for data
+ {
+ case SLEW_TYPE_ADR_ADDR:
+ // CTL0 for command slew (A0:15, BA0:3, ACT, PAR, CAS, RAS, WE)
+ FAPI_INF("Setting ADR command/address slew in CTL0 register");
+ adr_pos = 48;
+ break;
+ case SLEW_TYPE_ADR_CNTL:
+ // CTL1 for control slew (CKE0:1, CKE4:5, ODT0:3, CSN0:3)
+ FAPI_INF("Setting ADR control slew in CTL1 register");
+ adr_pos = 52;
+ break;
+ case SLEW_TYPE_ADR_CLK:
+ // CTL2 for clock slew (CLK0:3)
+ FAPI_INF("Setting ADR clock slew in CTL2 register");
+ adr_pos = 56;
+ break;
+ case SLEW_TYPE_ADR_SPCKE:
+ // CTL3 for spare clock slew (CKE2:3)
+ FAPI_INF("Setting ADR Spare clock in CTL3 register");
+ adr_pos = 60;
+ break;
+ }
+ for(uint8_t i=0; i < MAX_NUM_IMP; i++) // find ADR imp index
+ {
+ if (adr_imp_array[i] == i_slew_imp)
+ {
+ imp_idx = i;
+ break;
+ }
+ }
+ if ((i_slew_imp == OHM24) || (i_slew_imp == OHM34) ||
+ (imp_idx >= MAX_NUM_IMP))
+ {
+ FAPI_ERR("Slew impedance input(%u) out of bounds", i_slew_imp);
+ FAPI_SET_HWP_ERROR(rc, RC_MSS_IMP_INPUT_ERROR);
+ return rc;
+ }
+
+ if (i_slew_rate == SLEW_MAXV_NS)
+ {
+ slew_cal_value = 0;
+ }
+ else
+ {
+ rc = FAPI_ATTR_GET(ATTR_MSS_SLEW_RATE_ADR, &i_target_mba,
+ calibrated_slew_rate_table); if(rc) return rc;
+
+ slew_cal_value =
+ calibrated_slew_rate_table[i_port][imp_idx][slew_idx];
+ }
+ FAPI_DBG("port%u type=%u slew_idx=%u imp_idx=%u cal_slew=%u",
+ i_port, i_slew_type, slew_idx, imp_idx, slew_cal_value);
+
+ if (slew_cal_value > MAX_SLEW_VALUE)
+ {
+ FAPI_ERR("!! Slew rate(0x%02x) unsupported, but continuing... !!",
+ slew_cal_value);
+ slew_cal_value = slew_cal_value & 0x0F;
+ }
+
+ if (i_port == 0)
+ {
+ rc = fapiGetScom(i_target_mba,
+ DPHY01_DDRPHY_ADR_IO_SLEW_CTL_VALUE_P0_ADR0_0x8000401A0301143F,
+ data_buffer); if(rc) return rc;
+
+ rc_num |= data_buffer.insertFromRight(slew_cal_value, adr_pos, 4);
+ if (rc_num)
+ {
+ FAPI_ERR( "Error in setting up ADR slew buffer");
+ rc_buff.setEcmdError(rc_num);
+ return rc_buff;
+ }
+
+ rc = fapiPutScom(i_target_mba,
+ DPHY01_DDRPHY_ADR_IO_SLEW_CTL_VALUE_P0_ADR0_0x8000401A0301143F,
+ data_buffer); if(rc) return rc;
+ rc = fapiPutScom(i_target_mba,
+ DPHY01_DDRPHY_ADR_IO_SLEW_CTL_VALUE_P0_ADR1_0x8000441A0301143F,
+ data_buffer); if(rc) return rc;
+ rc = fapiPutScom(i_target_mba,
+ DPHY01_DDRPHY_ADR_IO_SLEW_CTL_VALUE_P0_ADR2_0x8000481A0301143F,
+ data_buffer); if(rc) return rc;
+ rc = fapiPutScom(i_target_mba,
+ DPHY01_DDRPHY_ADR_IO_SLEW_CTL_VALUE_P0_ADR3_0x80004C1A0301143F,
+ data_buffer); if(rc) return rc;
+ }
+ else // port 1 ADR slew
+ {
+ rc = fapiGetScom(i_target_mba,
+ DPHY01_DDRPHY_ADR_IO_SLEW_CTL_VALUE_P1_ADR0_0x8001401A0301143F,
+ data_buffer); if(rc) return rc;
+
+ rc_num |= data_buffer.insertFromRight(slew_cal_value, adr_pos, 4);
+ if (rc_num)
+ {
+ FAPI_ERR( "Error in setting up ADR slew buffer");
+ rc_buff.setEcmdError(rc_num);
+ return rc_buff;
+ }
+ rc = fapiPutScom(i_target_mba,
+ DPHY01_DDRPHY_ADR_IO_SLEW_CTL_VALUE_P1_ADR0_0x8001401A0301143F,
+ data_buffer); if(rc) return rc;
+ rc = fapiPutScom(i_target_mba,
+ DPHY01_DDRPHY_ADR_IO_SLEW_CTL_VALUE_P1_ADR1_0x8001441A0301143F,
+ data_buffer); if(rc) return rc;
+ rc = fapiPutScom(i_target_mba,
+ DPHY01_DDRPHY_ADR_IO_SLEW_CTL_VALUE_P1_ADR2_0x8001481A0301143F,
+ data_buffer); if(rc) return rc;
+ rc = fapiPutScom(i_target_mba,
+ DPHY01_DDRPHY_ADR_IO_SLEW_CTL_VALUE_P1_ADR3_0x80014C1A0301143F,
+ data_buffer); if(rc) return rc;
+ }
+ }
+ return rc;
+}
+
+/*------------------------------------------------------------------------------
+ * Function: config_wr_dram_vref()
+ * This function configures PC_VREF_DRV_CONTROL registers to vary the DIMM VREF
+ *
+ * Parameters: target: mba; port: 0, 1
+ * Wr_dram_vref: VDD420 = 420, VDD425 = 425, VDD430 = 430, VDD435 = 435, VDD440 = 440,
+ * VDD445 = 445, VDD450 = 450, VDD455 = 455, VDD460 = 460, VDD465 = 465, VDD470 = 470,
+ * VDD475 = 475, VDD480 = 480, VDD485 = 485, VDD490 = 490, VDD495 = 495, VDD500 = 500,
+ * VDD505 = 505, VDD510 = 510, VDD515 = 515, VDD520 = 520, VDD525 = 525, VDD530 = 530,
+ * VDD535 = 535, VDD540 = 540, VDD545 = 545, VDD550 = 550, VDD555 = 555, VDD560 = 560,
+ * VDD565 = 565, VDD570 = 570, VDD575 = 575
+ * ---------------------------------------------------------------------------*/
+
+fapi::ReturnCode config_wr_dram_vref(const fapi::Target & i_target_mba, uint8_t i_port, uint32_t i_wr_dram_vref)
+{
+
+ ecmdDataBufferBase data_buffer(64);
+ fapi::ReturnCode rc, rc_buff;
+ uint32_t rc_num = 0;
+ uint32_t pcvref = 0;
+ uint32_t i = 0;
+
+ // For DDR3 vary from VDD*0.42 to VDD*575
+ // For DDR4 internal voltage is there this function is not required
+ if (i_port > 1)
+ {
+ FAPI_ERR("Write Vref port input(%u) out of bounds", i_port);
+ FAPI_SET_HWP_ERROR(rc, RC_MSS_INVALID_FN_INPUT_ERROR);
+ return rc;
+ }
+ for(i=0; i< MAX_WR_VREF; i++)
+ {
+ if (wr_vref_array[i] == i_wr_dram_vref)
+ {
+ pcvref = i;
+ break;
+ }
+ }
+
+ if (i_port == 0)
+ {
+ rc = fapiGetScom(i_target_mba, DPHY01_DDRPHY_PC_VREF_DRV_CONTROL_P0_0x8000C0150301143F, data_buffer); if(rc) return rc;
+ rc_num = rc_num | data_buffer.insertFromRight(pcvref,48,5);
+ rc_num = rc_num | data_buffer.insertFromRight(pcvref,53,5);
+ if (rc_num)
+ {
+ FAPI_ERR( "config_wr_vref: Error in setting up buffer ");
+ rc_buff.setEcmdError(rc_num);
+ return rc_buff;
+ }
+ rc = fapiPutScom(i_target_mba, DPHY01_DDRPHY_PC_VREF_DRV_CONTROL_P0_0x8000C0150301143F, data_buffer); if(rc) return rc;
+ }
+ else
+ {
+ rc = fapiGetScom(i_target_mba, DPHY01_DDRPHY_PC_VREF_DRV_CONTROL_P1_0x8001C0150301143F, data_buffer); if(rc) return rc;
+ rc_num = rc_num | data_buffer.insertFromRight(pcvref,48,5);
+ rc_num = rc_num | data_buffer.insertFromRight(pcvref,53,5);
+ if (rc_num)
+ {
+ FAPI_ERR( "config_wr_vref: Error in setting up buffer ");
+ rc_buff.setEcmdError(rc_num);
+ return rc_buff;
+ }
+ rc = fapiPutScom(i_target_mba, DPHY01_DDRPHY_PC_VREF_DRV_CONTROL_P1_0x8001C0150301143F, data_buffer); if(rc) return rc;
+ }
+ return rc;
+}
+/*------------------------------------------------------------------------------
+ * Function: config_rd_cen_vref()
+ * This function configures read vref registers to vary the CEN VREF
+ *
+ * Parameters: target: mba; port: 0, 1
+ * Rd_cen_Vref: 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
+ * DDR3 supports upto 61000
+ * ---------------------------------------------------------------------------*/
+
+fapi::ReturnCode config_rd_cen_vref (const fapi::Target & i_target_mba, uint8_t i_port, uint32_t i_rd_cen_vref)
+{
+
+ ecmdDataBufferBase data_buffer(64);
+ fapi::ReturnCode rc, rc_buff;
+ uint32_t rc_num = 0;
+ uint32_t rd_vref = 0;
+
+ if (i_port > 1)
+ {
+ FAPI_ERR("Read vref port input(%u) out of bounds", i_port);
+ FAPI_SET_HWP_ERROR(rc, RC_MSS_INVALID_FN_INPUT_ERROR);
+ return rc;
+ }
+ for(uint8_t i=0; i< MAX_RD_VREF; i++)
+ {
+ if (rd_cen_vref_array[i] == i_rd_cen_vref)
+ {
+ rd_vref = i;
+ break;
+ }
+ }
+
+ if (i_port == 0)
+ {
+ rc = fapiGetScom(i_target_mba,
+ DPHY01_DDRPHY_DP18_RX_PEAK_AMP_P0_0_0x800000060301143F,
+ data_buffer); if(rc) return rc;
+ rc_num = rc_num | data_buffer.insertFromRight(rd_vref,56,4);
+ if (rc_num)
+ {
+ FAPI_ERR( "config_rd_vref: Error in setting up buffer ");
+ rc_buff.setEcmdError(rc_num);
+ return rc_buff;
+ }
+ rc = fapiPutScom(i_target_mba,
+ DPHY01_DDRPHY_DP18_RX_PEAK_AMP_P0_0_0x800000060301143F,
+ data_buffer); if(rc) return rc;
+ rc = fapiPutScom(i_target_mba,
+ DPHY01_DDRPHY_DP18_RX_PEAK_AMP_P0_1_0x800004060301143F,
+ data_buffer); if(rc) return rc;
+ rc = fapiPutScom(i_target_mba,
+ DPHY01_DDRPHY_DP18_RX_PEAK_AMP_P0_2_0x800008060301143F,
+ data_buffer); if(rc) return rc;
+ rc = fapiPutScom(i_target_mba,
+ DPHY01_DDRPHY_DP18_RX_PEAK_AMP_P0_3_0x80000c060301143F,
+ data_buffer); if(rc) return rc;
+ rc = fapiPutScom(i_target_mba,
+ DPHY01_DDRPHY_DP18_RX_PEAK_AMP_P0_4_0x800010060301143F,
+ data_buffer); if(rc) return rc;
+ }
+ else
+ {
+ rc = fapiGetScom(i_target_mba,
+ DPHY01_DDRPHY_DP18_RX_PEAK_AMP_P1_0_0x800100060301143F,
+ data_buffer); if(rc) return rc;
+ rc_num = rc_num | data_buffer.insertFromRight(rd_vref,56,4);
+ if (rc_num)
+ {
+ FAPI_ERR( "config_rd_vref: Error in setting up buffer ");
+ rc_buff.setEcmdError(rc_num);
+ return rc_buff;
+ }
+ rc = fapiPutScom(i_target_mba,
+ DPHY01_DDRPHY_DP18_RX_PEAK_AMP_P1_0_0x800100060301143F,
+ data_buffer); if(rc) return rc;
+ rc = fapiPutScom(i_target_mba,
+ DPHY01_DDRPHY_DP18_RX_PEAK_AMP_P1_1_0x800104060301143F,
+ data_buffer); if(rc) return rc;
+ rc = fapiPutScom(i_target_mba,
+ DPHY01_DDRPHY_DP18_RX_PEAK_AMP_P1_2_0x800108060301143F,
+ data_buffer); if(rc) return rc;
+ rc = fapiPutScom(i_target_mba,
+ DPHY01_DDRPHY_DP18_RX_PEAK_AMP_P1_3_0x80010c060301143F,
+ data_buffer); if(rc) return rc;
+ rc = fapiPutScom(i_target_mba,
+ DPHY01_DDRPHY_DP18_RX_PEAK_AMP_P1_4_0x800110060301143F,
+ data_buffer); if(rc) return rc;
+ }
+ return rc;
+}
+/*------------------------------------------------------------------------------
+ * Function: mss_slew_cal()
+ * This function runs the slew calibration engine to configure MSS_SLEW_DATA/ADR
+ * attributes and calls config_slew_rate to set the slew rate in the registers.
+ *
+ * Parameters: target: mba;
+ * ---------------------------------------------------------------------------*/
+
+fapi::ReturnCode mss_slew_cal(const fapi::Target &i_target)
+{
+ fapi::ReturnCode rc;
+ uint32_t rc_ecmd = 0;
+ std::vector<fapi::ReturnCode> vector_rcs; // to capture rc's on port loop
+ uint32_t poll_count = 0;
+ uint8_t ports_valid = 0;
+ uint8_t is_sim = 0;
+
+ uint8_t freq_idx = 0; // freq index into lookup table
+ uint32_t ddr_freq = 0; // current ddr freq
+ uint8_t ddr_idx = 0; // ddr type index into lookup table
+ uint8_t ddr_type = 0; // ATTR_EFF_DRAM_GEN{0=invalid, 1=ddr3, 2=ddr4}
+
+ uint8_t cal_status = 0;
+ // bypass slew (MAX slew rate) not included since it is not calibrated.
+ // for output ATTR_MSS_SLEW_RATE_DATA(0),
+ // ATTR_MSS_SLEW_RATE_ADR(1), [port=2][imp=4][slew=4]
+ uint8_t calibrated_slew[2][MAX_NUM_PORTS][MAX_NUM_IMP]
+ [MAX_NUM_CAL_SLEW_RATES] = {{{{ 0 }}}};
+
+ fapi::Target l_target_centaur; // temporary target for parent
+
+ ecmdDataBufferBase ctl_reg(64);
+ ecmdDataBufferBase stat_reg(64);
+
+ // [ddr3/4][dq/adr][speed][impedance][slew_rate]
+ // note: Assumes standard voltage for DDR3(1.35V), DDR4(1.2V),
+ // little endian, if >=128, lab only debug.
+ //
+ // ddr_type(2) ddr3=0, ddr4=1
+ // data/adr(2) data(dq/dqs)=0, adr(cmd/cntl)=1
+ // speed(4) 1066=0, 1333=1, 1600=2, 1866=3
+ // imped(4) 24ohms=0, 30ohms=1, 34ohms=2, 40ohms=3 for DQ/DQS
+ // imped(4) 15ohms=0, 20ohms=1, 30ohms=2, 40ohms=3 for ADR driver
+ // slew(3) 3V/ns=0, 4V/ns=1, 5V/ns=2, 6V/ns=3
+ const uint8_t slew_table[2][2][4][4][4] = {
+// NOTE: bit 7 = unsupported slew, and actual value is in bits 4:0
+
+/* DDR3(0) */
+ { {
+ // dq/dqs(0)
+/* Imp. ________24ohms______..________30ohms______..________34ohms______..________40ohms______
+ Slew 3 4 5 6 3 4 5 6 3 4 5 6 3 4 5 6 (V/ns) */
+/*1066*/{{ 12, 9, 7, 134}, { 13, 9, 7, 133}, { 13, 10, 7, 134}, { 14, 10, 7, 132}},
+/*1333*/{{ 15, 11, 8, 135}, { 16, 12, 9, 135}, { 17, 12, 9, 135}, { 17, 12, 8, 133}},
+/*1600*/{{ 18, 13, 10, 136}, { 19, 14, 10, 136}, { 20, 15, 11, 136}, { 21, 14, 10, 134}},
+/*1866*/{{149, 143, 140, 138}, {151, 144, 140, 137}, {151, 145, 141, 138}, {152, 145, 139, 135}}
+ }, {
+ // adr(1),
+/* Imp. ________15ohms______..________20ohms______..________30ohms______..________40ohms______
+ Slew 3 4 5 6 3 4 5 6 3 4 5 6 3 4 5 6 (V/ns) */
+/*1066*/{{ 17, 13, 10, 8}, { 13, 11, 7, 6}, { 12, 8, 5, 131}, { 7, 4, 131, 131}},
+/*1333*/{{ 21, 16, 12, 10}, { 17, 12, 9, 7}, { 15, 10, 6, 132}, { 9, 5, 132, 132}},
+/*1600*/{{ 25, 19, 15, 12}, { 20, 14, 13, 8}, { 19, 12, 7, 133}, { 11, 6, 133, 133}},
+/*1866*/{{157, 150, 145, 142}, {151, 145, 141, 138}, {150, 142, 136, 134}, {141, 134, 134, 134}}
+ } },
+/* DDR4(1) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
+ { {
+ // dq/dqs(0)
+/* Imp. ________24ohms______..________30ohms______..________34ohms______..________40ohms______
+ Slew 3 4 5 6 3 4 5 6 3 4 5 6 3 4 5 6 (V/ns) */
+/*1066*/{{138, 135, 134, 133}, {139, 136, 134, 132}, {140, 136, 134, 132}, {140, 136, 132, 132}},
+/*1333*/{{139, 137, 135, 134}, {142, 138, 135, 133}, {143, 138, 135, 133}, {143, 138, 133, 132}},
+/*1600*/{{ 15, 11, 9, 135}, { 17, 11, 9, 135}, { 18, 13, 9, 134}, { 18, 11, 6, 133}},
+/*1866*/{{ 18, 13, 10, 137}, { 19, 13, 10, 136}, { 21, 15, 10, 135}, { 21, 13, 8, 134}}
+ }, {
+ // adr(1)
+/* Imp. ________15ohms______..________20ohms______..________30ohms______..________40ohms______
+ Slew 3 4 5 6 3 4 5 6 3 4 5 6 3 4 5 6 (V/ns) */
+/*1066*/{{142, 139, 136, 134}, {140, 136, 134, 133}, {138, 134, 131, 131}, {133, 131, 131, 131}},
+/*1333*/{{145, 142, 139, 136}, {143, 138, 135, 134}, {140, 135, 132, 132}, {134, 132, 132, 132}},
+/*1600*/{{ 21, 16, 13, 10}, { 18, 12, 9, 135}, { 15, 8, 133, 133}, { 7, 133, 133, 133}},
+/*1866*/{{ 24, 19, 15, 11}, { 21, 14, 10, 136}, { 17, 10, 134, 134}, { 9, 134, 134, 134}}
+ } }
+ };
+
+ // slew calibration control register
+ const uint64_t slew_cal_cntl[] = {
+ DPHY01_DDRPHY_ADR_SLEW_CAL_CNTL_P0_ADR32S0_0x800080390301143F, // port 0
+ DPHY01_DDRPHY_ADR_SLEW_CAL_CNTL_P1_ADR32S0_0x800180390301143F // port 1
+ };
+ // slew calibration status registers
+ const uint64_t slew_cal_stat[] = {
+ DPHY01_DDRPHY_ADR_SYSCLK_PR_VALUE_RO_P0_ADR32S0_0x800080340301143F,
+ DPHY01_DDRPHY_ADR_SYSCLK_PR_VALUE_RO_P1_ADR32S0_0x800180340301143F
+ };
+ const uint8_t ENABLE_BIT = 48;
+ const uint8_t START_BIT = 49;
+ const uint8_t BB_LOCK_BIT = 56;
+ // general purpose 100 ns delay for HW mode (2000 sim cycles if simclk = 20ghz)
+ const uint16_t DELAY_100NS = 100;
+ // normally 2000, but since cal doesn't work in SIM, setting to 1
+ const uint16_t DELAY_SIMCYCLES = 1;
+ const uint8_t MAX_POLL_LOOPS = 20;
+
+ // verify which ports are functional
+ rc = FAPI_ATTR_GET(ATTR_MSS_EFF_DIMM_FUNCTIONAL_VECTOR,
+ &i_target, ports_valid);
+ if (rc)
+ {
+ FAPI_ERR("Failed to get attribute: "
+ "ATTR_MSS_EFF_DIMM_FUNCTIONAL_VECTOR");
+ return rc;
+ }
+
+ // Check if in SIM
+ rc = FAPI_ATTR_GET(ATTR_IS_SIMULATION, NULL, is_sim);
+ if (rc)
+ {
+ FAPI_ERR("Failed to get attribute: ATTR_IS_SIMULATION");
+ return rc;
+ }
+ // Get DDR type (DDR3 or DDR4)
+ rc = FAPI_ATTR_GET(ATTR_EFF_DRAM_GEN, &i_target, ddr_type);
+ if (rc)
+ {
+ FAPI_ERR("Failed to get attribute: ATTR_EFF_DRAM_GEN");
+ return rc;
+ }
+ // ddr_type(2) ddr3=0, ddr4=1
+ if (ddr_type == fapi::ENUM_ATTR_EFF_DRAM_GEN_DDR4) { //type=2
+ ddr_idx = 1;
+ } else if (ddr_type == fapi::ENUM_ATTR_EFF_DRAM_GEN_DDR3) { //type=1
+ ddr_idx = 0;
+ } else { // EMPTY ?? how to handle?
+ FAPI_ERR("Invalid ATTR_DRAM_DRAM_GEN = %d, %s!", ddr_type,
+ i_target.toEcmdString());
+ FAPI_SET_HWP_ERROR(rc, RC_MSS_INVALID_DRAM_GEN);
+ return rc;
+ }
+
+ // get freq from parent
+ rc = fapiGetParentChip(i_target, l_target_centaur); if(rc) return rc;
+ rc = FAPI_ATTR_GET(ATTR_MSS_FREQ, &l_target_centaur, ddr_freq);
+ if(rc) return rc;
+
+ if (ddr_freq == 0) {
+ FAPI_ERR("Invalid ATTR_MSS_FREQ = %d on %s!", ddr_freq,
+ i_target.toEcmdString());
+ FAPI_SET_HWP_ERROR(rc, RC_MSS_INVALID_FREQ);
+ return rc;
+ }
+ // speed(4) 1066=0, 1333=1, 1600=2, 1866=3
+ if (ddr_freq > 1732) {
+ freq_idx= 3; // for 1866+
+ } else if ((ddr_freq > 1460) && (ddr_freq <= 1732)) {
+ freq_idx = 2; // for 1600
+ } else if ((ddr_freq > 1200) && (ddr_freq <= 1460)) {
+ freq_idx = 1; // for 1333
+ } else { // (ddr_freq <= 1200)
+ freq_idx = 0; // for 1066-
+ }
+
+ FAPI_INF("Enabling slew calibration engine... dram=DDR%i(%u), freq=%u(%u)",
+ (ddr_type+2), ddr_idx, ddr_freq, freq_idx);
+
+ vector_rcs.clear(); // clear rc vector
+ for (uint8_t l_port=0; l_port < MAX_NUM_PORTS; l_port++)
+ {
+ uint8_t port_val = (ports_valid & (0xF0 >> (4 * l_port)));
+
+ if (port_val == 0) {
+ FAPI_INF("WARNING: Port %u is invalid from "
+ "ATTR_MSS_EFF_DIMM_FUNCTIONAL_VECTOR, 0x%02x",
+ l_port, ports_valid);
+ }
+ // Step A: Configure ADR registers and MCLK detect (done in ddr_phy_reset)
+ // DPHY01_DDRPHY_ADR_SLEW_CAL_CNTL_P0_ADR32S0_0x800080390301143F + port
+ rc = fapiGetScom(i_target, slew_cal_cntl[l_port], ctl_reg);
+ if (rc)
+ {
+ FAPI_ERR("Error reading DDRPHY_ADR_SLEW_CAL_CNTL register.");
+ //return rc;
+ vector_rcs.push_back(rc);
+ continue;
+ }
+
+ rc_ecmd = ctl_reg.flushTo0();
+ rc_ecmd |= ctl_reg.setBit(ENABLE_BIT); // set enable (bit49) to 1
+ if (rc_ecmd)
+ {
+ FAPI_ERR("Error setting enable bit in ADR Slew calibration "
+ "control register.");
+ rc.setEcmdError(rc_ecmd);
+ //return rc;
+ vector_rcs.push_back(rc);
+ continue;
+ }
+
+ // DPHY01_DDRPHY_ADR_SLEW_CAL_CNTL_P0_ADR32S0_0x800080390301143F + port
+ rc = fapiPutScom(i_target, slew_cal_cntl[l_port], ctl_reg);
+ if (rc)
+ {
+ FAPI_ERR("Error enabling slew calibration engine in "
+ "DDRPHY_ADR_SLEW_CAL_CNTL register.");
+ //return rc;
+ vector_rcs.push_back(rc);
+ continue;
+ }
+
+ //---------------------------------------------------------------------/
+ // Step 1. Check for BB lock.
+ FAPI_INF("Wait for BB lock in status register, bit %u", BB_LOCK_BIT);
+ for (poll_count=0; poll_count < MAX_POLL_LOOPS; poll_count++)
+ {
+ rc = fapiDelay(DELAY_100NS, DELAY_SIMCYCLES);
+ if (rc) {
+ FAPI_ERR("Error executing fapiDelay of 100ns or 2000simcycles");
+ //return rc;
+ vector_rcs.push_back(rc);
+ continue;
+ }
+ // DPHY01_DDRPHY_ADR_SYSCLK_PR_VALUE_RO_P0_ADR32S0_0x800080340301143F + port
+ rc = fapiGetScom(i_target, slew_cal_stat[l_port], stat_reg);
+ if (rc)
+ {
+ FAPI_ERR("Error reading DDRPHY_ADR_SYSCLK_PR_VALUE_RO register "
+ "for BB_Lock.");
+ //return rc;
+ vector_rcs.push_back(rc);
+ continue;
+ }
+ FAPI_DBG("stat_reg = 0x%04x, count=%i",stat_reg.getHalfWord(3),
+ poll_count);
+
+ if (stat_reg.isBitSet(BB_LOCK_BIT)) break;
+ }
+
+ if (poll_count == MAX_POLL_LOOPS) {
+ FAPI_INF("Timeout on polling BB_Lock, continuing...");
+ }
+
+ //---------------------------------------------------------------------/
+ // Create calibrated slew settings
+ // dq/adr(2) dq/dqs=0, adr=1
+ // slew(4) 3V/ns=0, 4V/ns=1, 5V/ns=2, 6V/ns=3
+ for (uint8_t data_adr=0; data_adr < 2; data_adr++)
+ {
+ for (uint8_t imp=0; imp < MAX_NUM_IMP; imp++)
+ {
+ uint8_t cal_slew;
+
+ for (uint8_t slew=0; slew < MAX_NUM_CAL_SLEW_RATES; slew++)
+ {
+ cal_slew =
+ slew_table[ddr_idx][data_adr][freq_idx][imp][slew];
+
+ // set slew phase rotator from slew_table
+ // slew_table[ddr3/4][dq/adr][freq][impedance][slew_rate]
+ rc_ecmd |= ctl_reg.insertFromRight(cal_slew, 59, 5);
+
+ // Note: must be 2000 nclks+ after setting enable bit
+ rc_ecmd |= ctl_reg.setBit(START_BIT); // set start bit(48)
+ FAPI_DBG("%s Slew cntl_reg(48:63)=0x%04X, i_slew=%i,0x%02x "
+ "(59:63)", (data_adr ? "ADR" : "DATA"),
+ ctl_reg.getHalfWord(3), cal_slew, cal_slew);
+ if (rc_ecmd)
+ {
+ FAPI_ERR("Error setting start bit or cal input value.");
+ rc.setEcmdError(rc_ecmd);
+ //return rc;
+ vector_rcs.push_back(rc);
+ continue;
+ }
+
+ // DPHY01_DDRPHY_ADR_SLEW_CAL_CNTL_P0_ADR32S0_0x800080390301143F + port
+ FAPI_INF("Starting slew calibration, ddr_idx=%i, "
+ "data_adr=%i, imp=%i, slewrate=%i", ddr_idx, data_adr,
+ imp, (slew+3));
+ rc = fapiPutScom(i_target, slew_cal_cntl[l_port], ctl_reg);
+ if (rc)
+ {
+ FAPI_ERR("Error starting slew calibration.");
+ //return rc;
+ vector_rcs.push_back(rc);
+ continue;
+ }
+
+ // poll for calibration status done or timeout...
+ for (poll_count=0; poll_count < MAX_POLL_LOOPS;
+ poll_count++)
+ {
+ FAPI_INF("polling for calibration status, count=%i",
+ poll_count);
+ // DPHY01_DDRPHY_ADR_SYSCLK_PR_VALUE_RO_P0_ADR32S0_0x800080340301143F + port
+ rc = fapiGetScom(i_target, slew_cal_stat[l_port],
+ stat_reg);
+ if (rc)
+ {
+ FAPI_ERR("Error reading "
+ "DDRPHY_ADR_SYSCLK_PR_VALUE_RO "
+ "register for calibration status.");
+ //return rc;
+ vector_rcs.push_back(rc);
+ continue;
+ }
+ rc_ecmd = stat_reg.extractToRight(&cal_status, 58, 2);
+ if (rc_ecmd)
+ {
+ FAPI_ERR("Error getting calibration status bits");
+ rc.setEcmdError(rc_ecmd);
+ //return rc;
+ vector_rcs.push_back(rc);
+ continue;
+ }
+ FAPI_DBG("cal_status = %i",cal_status);
+ if (cal_status != 0)
+ break;
+ // wait (1020 mclks / MAX_POLL_LOOPS)
+ rc = fapiDelay(DELAY_100NS, DELAY_SIMCYCLES);
+ if(rc)
+ {
+ //return rc;
+ vector_rcs.push_back(rc);
+ continue;
+ }
+ }
+
+ if (cal_status == 3)
+ {
+ FAPI_INF("slew calibration completed successfully");
+
+ cal_slew = cal_slew & 0x80; // clear bits 6:0
+ rc_ecmd = stat_reg.extractPreserve(&cal_slew, 60, 4);
+ if (rc_ecmd)
+ {
+ FAPI_ERR("Error getting calibration output "
+ "slew value");
+ rc.setEcmdError(rc_ecmd);
+ //return rc;
+ vector_rcs.push_back(rc);
+ continue;
+ }
+ calibrated_slew[data_adr][l_port][imp][slew] = cal_slew;
+ }
+ else if (cal_status == 2)
+ {
+ FAPI_ERR("warning occurred during slew "
+ "calibration, continuing...");
+ }
+ else
+ {
+ if (cal_status == 1)
+ {
+ FAPI_ERR("error occurred during slew calibration");
+ }
+ else
+ {
+ FAPI_ERR("Slew calibration timed out");
+ }
+ FAPI_ERR("Slew calibration failed on %s slew: imp_idx="
+ "%d, slew_idx=%d, slew_table=0x%02X, "
+ "status=0x%04X on %s!",
+ (data_adr ? "ADR" : "DATA"), imp, slew,
+ cal_slew, stat_reg.getHalfWord(3),
+ i_target.toEcmdString());
+
+ if (is_sim) {
+ // Calibration fails in sim since bb_lock not
+ // possible in cycle simulator, putting initial
+ // to be cal'd value in output table
+ FAPI_INF("In SIM setting calibrated slew array");
+ calibrated_slew[data_adr][l_port][imp][slew] =
+ cal_slew;
+ }
+ else
+ {
+ FAPI_SET_HWP_ERROR(rc, RC_MSS_SLEW_CAL_ERROR);
+ //return rc;
+ vector_rcs.push_back(rc);
+ continue;
+ }
+ } // end error check
+ } // end slew
+ } // end imp
+ } // end data_adr
+
+ // disable calibration engine for port
+ ctl_reg.clearBit(ENABLE_BIT);
+ rc = fapiPutScom(i_target, slew_cal_cntl[l_port], ctl_reg);
+ if (rc)
+ {
+ FAPI_ERR("Error disabling slew calibration engine in "
+ "DDRPHY_ADR_SLEW_CAL_CNTL register.");
+ //return rc;
+ vector_rcs.push_back(rc);
+ }
+ } // end port loop
+
+ if (vector_rcs.size() != 0)
+ {
+ return vector_rcs.front(); // return first RC encountered
+ }
+ FAPI_INF("Setting output slew tables ATTR_MSS_SLEW_RATE_DATA/ADR");
+ // ATTR_MSS_SLEW_RATE_DATA [2][4][4] port, imped, slew_rate
+ rc = FAPI_ATTR_SET(ATTR_MSS_SLEW_RATE_DATA, &i_target, calibrated_slew[0]);
+ if (rc)
+ {
+ FAPI_ERR("Failed to set attribute: ATTR_MSS_SLEW_RATE_DATA");
+ return rc;
+ }
+ // ATTR_MSS_SLEW_RATE_ADR [2][4][4] port, imped, slew_rate
+ rc = FAPI_ATTR_SET(ATTR_MSS_SLEW_RATE_ADR, &i_target, calibrated_slew[1]);
+ if (rc)
+ {
+ FAPI_ERR("Failed to set attribute: ATTR_MSS_SLEW_RATE_ADR");
+ return rc;
+ }
+
+/******************************************************************************/
+ uint8_t slew_imp_val [MAX_NUM_SLEW_TYPES][2][MAX_NUM_PORTS]={{{0}}};
+ enum {
+ SLEW = 0,
+ IMP = 1,
+ };
+
+ // Get desired dq/dqs slew rate & impedance from attribute
+ rc = FAPI_ATTR_GET(ATTR_EFF_CEN_SLEW_RATE_DQ_DQS, &i_target,
+ slew_imp_val[SLEW_TYPE_DATA][SLEW]);
+ if (rc)
+ {
+ FAPI_ERR("Failed to get attribute: ATTR_EFF_CEN_SLEW_RATE_DQ_DQS");
+ return rc;
+ }
+ rc = FAPI_ATTR_GET(ATTR_EFF_CEN_DRV_IMP_DQ_DQS, &i_target,
+ slew_imp_val[SLEW_TYPE_DATA][IMP]);
+ if (rc)
+ {
+ FAPI_ERR("Failed to get attribute: ATTR_EFF_CEN_DRV_IMP_DQ_DQS");
+ return rc;
+ }
+ // convert enum value to actual ohms.
+ for (uint8_t j=0; j < MAX_NUM_PORTS; j++)
+ {
+ FAPI_INF("DQ_DQS IMP Attribute[%i] = %u", j,
+ slew_imp_val[SLEW_TYPE_DATA][IMP][j]);
+
+ switch (slew_imp_val[SLEW_TYPE_DATA][IMP][j])
+ {
+ case fapi::ENUM_ATTR_EFF_CEN_DRV_IMP_DQ_DQS_OHM24_FFE0:
+ slew_imp_val[SLEW_TYPE_DATA][IMP][j]=24;
+ break;
+ case fapi::ENUM_ATTR_EFF_CEN_DRV_IMP_DQ_DQS_OHM30_FFE0:
+ case fapi::ENUM_ATTR_EFF_CEN_DRV_IMP_DQ_DQS_OHM30_FFE480:
+ case fapi::ENUM_ATTR_EFF_CEN_DRV_IMP_DQ_DQS_OHM30_FFE240:
+ case fapi::ENUM_ATTR_EFF_CEN_DRV_IMP_DQ_DQS_OHM30_FFE160:
+ case fapi::ENUM_ATTR_EFF_CEN_DRV_IMP_DQ_DQS_OHM30_FFE120:
+ slew_imp_val[SLEW_TYPE_DATA][IMP][j]=30;
+ break;
+ case fapi::ENUM_ATTR_EFF_CEN_DRV_IMP_DQ_DQS_OHM34_FFE0:
+ case fapi::ENUM_ATTR_EFF_CEN_DRV_IMP_DQ_DQS_OHM34_FFE480:
+ case fapi::ENUM_ATTR_EFF_CEN_DRV_IMP_DQ_DQS_OHM34_FFE240:
+ case fapi::ENUM_ATTR_EFF_CEN_DRV_IMP_DQ_DQS_OHM34_FFE160:
+ case fapi::ENUM_ATTR_EFF_CEN_DRV_IMP_DQ_DQS_OHM34_FFE120:
+ slew_imp_val[SLEW_TYPE_DATA][IMP][j]=34;
+ break;
+ case fapi::ENUM_ATTR_EFF_CEN_DRV_IMP_DQ_DQS_OHM40_FFE0:
+ case fapi::ENUM_ATTR_EFF_CEN_DRV_IMP_DQ_DQS_OHM40_FFE480:
+ case fapi::ENUM_ATTR_EFF_CEN_DRV_IMP_DQ_DQS_OHM40_FFE240:
+ case fapi::ENUM_ATTR_EFF_CEN_DRV_IMP_DQ_DQS_OHM40_FFE160:
+ case fapi::ENUM_ATTR_EFF_CEN_DRV_IMP_DQ_DQS_OHM40_FFE120:
+ slew_imp_val[SLEW_TYPE_DATA][IMP][j]=40;
+ break;
+ }
+ FAPI_DBG("switched imp to value of %u",
+ slew_imp_val[SLEW_TYPE_DATA][IMP][j]);
+ }
+ // Get desired ADR control slew rate & impedance from attribute
+ rc = FAPI_ATTR_GET(ATTR_EFF_CEN_SLEW_RATE_CNTL, &i_target,
+ slew_imp_val[SLEW_TYPE_ADR_CNTL][SLEW]);
+ if (rc)
+ {
+ FAPI_ERR("Failed to get attribute: ATTR_EFF_CEN_SLEW_RATE_CNTL");
+ return rc;
+ }
+ rc = FAPI_ATTR_GET(ATTR_EFF_CEN_DRV_IMP_CNTL, &i_target,
+ slew_imp_val[SLEW_TYPE_ADR_CNTL][IMP]);
+ if (rc)
+ {
+ FAPI_ERR("Failed to get attribute: ATTR_EFF_CEN_DRV_IMP_CNTL");
+ return rc;
+ }
+ // Get desired ADR command slew rate & impedance from attribute
+ rc = FAPI_ATTR_GET(ATTR_EFF_CEN_SLEW_RATE_ADDR, &i_target,
+ slew_imp_val[SLEW_TYPE_ADR_ADDR][SLEW]);
+ if (rc)
+ {
+ FAPI_ERR("Failed to get attribute: ATTR_EFF_CEN_SLEW_RATE_ADDR");
+ return rc;
+ }
+ rc = FAPI_ATTR_GET(ATTR_EFF_CEN_DRV_IMP_ADDR, &i_target,
+ slew_imp_val[SLEW_TYPE_ADR_ADDR][IMP]);
+ if (rc)
+ {
+ FAPI_ERR("Failed to get attribute: ATTR_EFF_CEN_DRV_IMP_ADDR");
+ return rc;
+ }
+ // Get desired ADR clock slew rate & impedance from attribute
+ rc = FAPI_ATTR_GET(ATTR_EFF_CEN_SLEW_RATE_CLK, &i_target,
+ slew_imp_val[SLEW_TYPE_ADR_CLK][SLEW]);
+ if (rc)
+ {
+ FAPI_ERR("Failed to get attribute: ATTR_EFF_CEN_SLEW_RATE_CLK");
+ return rc;
+ }
+ rc = FAPI_ATTR_GET(ATTR_EFF_CEN_DRV_IMP_CLK, &i_target,
+ slew_imp_val[SLEW_TYPE_ADR_CLK][IMP]);
+ if (rc)
+ {
+ FAPI_ERR("Failed to get attribute: ATTR_EFF_CEN_DRV_IMP_CLK");
+ return rc;
+ }
+ // Get desired ADR Spare clock slew rate & impedance from attribute
+ rc = FAPI_ATTR_GET(ATTR_EFF_CEN_SLEW_RATE_SPCKE, &i_target,
+ slew_imp_val[SLEW_TYPE_ADR_SPCKE][SLEW]);
+ if (rc)
+ {
+ FAPI_ERR("Failed to get attribute: ATTR_EFF_CEN_SLEW_RATE_SPCKE");
+ return rc;
+ }
+ rc = FAPI_ATTR_GET(ATTR_EFF_CEN_DRV_IMP_SPCKE, &i_target,
+ slew_imp_val[SLEW_TYPE_ADR_SPCKE][IMP]);
+ if (rc)
+ {
+ FAPI_ERR("Failed to get attribute: ATTR_EFF_CEN_DRV_IMP_SPCKE");
+ return rc;
+ }
+
+ for (uint8_t l_port=0; l_port < MAX_NUM_PORTS; l_port++)
+ {
+ //uint8_t ports_mask = 0xF0; // bits 0:3 = port0, bits 4:7 = port1
+ uint8_t port_val = (ports_valid & (0xF0 >> (4 * l_port)));
+
+ if (port_val == 0)
+ {
+ FAPI_INF("WARNING: Port %u is invalid from "
+ "ATTR_MSS_EFF_DIMM_FUNCTIONAL_VECTOR, 0x%02x "
+ "skipping configuration of slew rate on this port",
+ l_port, ports_valid);
+ continue;
+ }
+ for (uint8_t slew_type=0; slew_type < MAX_NUM_SLEW_TYPES; slew_type++)
+ {
+ FAPI_DBG("slew_imp_val imp=%u, slew=%u",
+ slew_imp_val[slew_type][IMP][l_port],
+ slew_imp_val[slew_type][SLEW][l_port]);
+
+ config_slew_rate(i_target, l_port, slew_type,
+ slew_imp_val[slew_type][IMP][l_port],
+ slew_imp_val[slew_type][SLEW][l_port]);
+ }
+ }
+ return rc;
+}
diff --git a/src/usr/hwpf/hwp/dram_training/mss_ddr_phy_reset/mss_termination_control.H b/src/usr/hwpf/hwp/dram_training/mss_ddr_phy_reset/mss_termination_control.H
new file mode 100644
index 000000000..68e2b8fea
--- /dev/null
+++ b/src/usr/hwpf/hwp/dram_training/mss_ddr_phy_reset/mss_termination_control.H
@@ -0,0 +1,269 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/hwpf/hwp/dram_training/mss_ddr_phy_reset/mss_termination_control.H $ */
+/* */
+/* IBM CONFIDENTIAL */
+/* */
+/* COPYRIGHT International Business Machines Corp. 2012 */
+/* */
+/* p1 */
+/* */
+/* Object Code Only (OCO) source materials */
+/* Licensed Internal Code Source Materials */
+/* IBM HostBoot Licensed Internal Code */
+/* */
+/* The source code for this program is not published or otherwise */
+/* divested of its trade secrets, irrespective of what has been */
+/* deposited with the U.S. Copyright Office. */
+/* */
+/* Origin: 30 */
+/* */
+/* IBM_PROLOG_END_TAG */
+// $Id: mss_termination_control.H,v 1.9 2012/12/06 19:17:47 sasethur Exp $
+/* File is created by SARAVANAN SETHURAMAN on Thur Sept 28 2011. */
+
+//------------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2007
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//------------------------------------------------------------------------------
+// *! TITLE :mss_draminit_training_advanced.H
+// *! DESCRIPTION : Tools for centaur procedures
+// *! OWNER NAME : Saravanan sethuraman Email ID: saravanans@in.ibm.com
+// *! BACKUP NAME : Menlo Wuu Email ID: menlowuu@us.ibm.com
+// #! ADDITIONAL COMMENTS :
+//
+// General purpose funcs
+
+//------------------------------------------------------------------------------
+// Don't forget to create CVS comments when you check in your changes!
+//------------------------------------------------------------------------------
+// CHANGE HISTORY:
+//------------------------------------------------------------------------------
+// Version:| Author: | Date: | Comment:
+//---------|---------- |--------- |---------------------------------------------
+// 1.9 | 07-Dec-12 | sasethur | Updated for fw review comments
+// 1.8 | 16-Nov-12 | mwuu | Added typedef for external call of
+// mss_slew_cal F
+// 1.7 | 14-Nov-12 | mwuu | Changed "l_" variables to "i_" in
+// config_slew_rate FN
+// 1.6 | 14-Nov-12 | mwuu | Fixed revision numbering in comments
+// 1.5 | 14-Nov-12 | mwuu | Added additional slew rates, and new const
+// 1.4 | 26-Oct-12 | mwuu | Added additional slew types enums, need to
+// change MAX_NUM_SLEW_TYPES when attributes
+// updated.
+// 1.3 | 26-Oct-12 | sasethur | Updated FW review comments fapi::,
+// const fapi::Target
+// 1.2 | 17-Oct-12 | mwuu | updates to enum and consts
+// 1.1 | 28-Sep-12 | sasethur | First draft
+
+
+#ifndef MSS_TERMINATION_CONTROL_H
+#define MSS_TERMINATION_CONTROL_H
+//----------------------------------------------------------------------
+// Includes
+//----------------------------------------------------------------------
+#include <fapi.H>
+
+enum {
+ SLEW_TYPE_DATA = 0,
+ SLEW_TYPE_ADR_ADDR = 1,
+ SLEW_TYPE_ADR_CNTL = 2,
+ SLEW_TYPE_ADR_CLK = 3,
+ SLEW_TYPE_ADR_SPCKE = 4,
+
+ OHM15 = 15,
+ OHM20 = 20,
+ OHM24 = 24,
+ OHM30 = 30,
+ OHM34 = 34,
+ OHM40 = 40,
+
+ SLEW_3V_NS = 3,
+ SLEW_4V_NS = 4,
+ SLEW_5V_NS = 5,
+ SLEW_6V_NS = 6,
+ SLEW_MAXV_NS = 7,
+};
+
+const uint8_t MAX_NUM_PORTS = 2; // max number of ports
+const uint8_t MAX_NUM_SLEW_TYPES = 5; // data(dq/dqs), adr_cmd, adr_cntl, clk, spcke, used by slew_cal FN only
+const uint8_t MAX_NUM_IMP = 4; // number of impedances valid per slew type
+
+//Address shmoo is not done as a part of Training advanced, so the order matches
+//attribute enum
+const uint8_t adr_imp_array[] = {
+ 15,
+ 20,
+ 30,
+ 40,
+};
+
+// bypass slew (MAX slew rate) not included since it is not calibrated.
+const uint8_t MAX_NUM_CAL_SLEW_RATES = 4 ; // 3V/ns, 4V/ns, 5V/ns, 6V/n
+const uint8_t MAX_NUM_SLEW_RATES = 4; // 3V/ns, 4V/ns, 5V/ns, 6V/n, MAX?
+const uint8_t slew_rate_array[] = {
+// 7,
+ 6,
+ 5,
+ 4,
+ 3,
+};
+
+const uint8_t MAX_SLEW_VALUE = 15; // 4 bit value
+const uint8_t MAX_WR_VREF = 32;
+
+const uint32_t wr_vref_array[] = {
+ 420,
+ 425,
+ 430,
+ 435,
+ 440,
+ 445,
+ 450,
+ 455,
+ 460,
+ 465,
+ 470,
+ 475,
+ 480,
+ 485,
+ 490,
+ 495,
+ 500,
+ 505,
+ 510,
+ 515,
+ 520,
+ 525,
+ 530,
+ 535,
+ 540,
+ 545,
+ 550,
+ 555,
+ 560,
+ 565,
+ 570,
+ 575
+ };
+
+
+//The Array is re-arranged inorder to find the best Eye margin based on the
+//Fitness level - 500 is the best value
+const uint32_t wr_vref_array_fitness[] = {
+ 420,
+ 425,
+ 575,
+ 430,
+ 570,
+ 435,
+ 565,
+ 440,
+ 560,
+ 445,
+ 555,
+ 450,
+ 550,
+ 455,
+ 545,
+ 460,
+ 540,
+ 465,
+ 535,
+ 470,
+ 530,
+ 475,
+ 525,
+ 480,
+ 520,
+ 485,
+ 515,
+ 490,
+ 510,
+ 495,
+ 505,
+ 500
+ };
+
+const uint8_t MAX_RD_VREF = 16;
+const uint32_t rd_cen_vref_array[] = {
+ 40375,
+ 41750,
+ 43125,
+ 44500,
+ 45875,
+ 47250,
+ 48625,
+ 50000,
+ 51375,
+ 52750,
+ 54125,
+ 55500,
+ 56875,
+ 58250,
+ 59625,
+ 61000
+ };
+
+//The Array is re-arranged inorder to find the best Eye margin based on the
+//Fitness level - 50000 is the best value
+const uint32_t rd_cen_vref_array_fitness[] = {
+ 61000,
+ 59625,
+ 40375,
+ 58250,
+ 41750,
+ 56875,
+ 43125,
+ 55500,
+ 44500,
+ 54125,
+ 45875,
+ 52750,
+ 47250,
+ 51375,
+ 48625,
+ 50000
+ };
+
+//The Array is re-arranged inorder to find the best Eye margin based on the
+//Fitness level - 24 is the best value
+const uint8_t MAX_DRV_IMP = 4;
+const uint8_t drv_imp_array[] = {
+ 40,
+ 34,
+ 30,
+ 24
+ };
+
+//The Array is re-arranged inorder to find the best Eye margin based on the
+//Fitness level - 15 is the best value
+const uint8_t MAX_RCV_IMP = 9;
+const uint8_t rcv_imp_array[] = {
+ 120,
+ 80,
+ 60,
+ 48,
+ 40,
+ 34,
+ 30,
+ 20,
+ 15
+ };
+
+typedef fapi::ReturnCode (*mss_slew_cal_FP_t)(const fapi::Target & i_target_mba);
+
+extern "C"
+{
+fapi::ReturnCode config_wr_dram_vref(const fapi::Target & i_target_mba, uint8_t i_port, uint32_t l_wr_vref);
+fapi::ReturnCode config_rd_cen_vref(const fapi::Target & i_target_mba, uint8_t i_port, uint32_t l_rd_cen_vref);
+fapi::ReturnCode config_drv_imp(const fapi::Target & i_target_mba, uint8_t i_port, uint8_t l_drv_imp_dq_dqs);
+fapi::ReturnCode config_rcv_imp(const fapi::Target & i_target_mba, uint8_t i_port, uint8_t l_rcv_imp_dq_dqs);
+fapi::ReturnCode config_slew_rate(const fapi::Target & i_target_mba,
+ const uint8_t i_port, const uint8_t l_slew_type, const uint8_t l_slew_imp,
+ const uint8_t l_slew_rate);
+fapi::ReturnCode mss_slew_cal(const fapi::Target & i_target_mba);
+} // extern C
+#endif
diff --git a/src/usr/hwpf/hwp/dram_training/mss_draminit/mss_draminit.C b/src/usr/hwpf/hwp/dram_training/mss_draminit/mss_draminit.C
index 718a52bad..f01d83112 100755
--- a/src/usr/hwpf/hwp/dram_training/mss_draminit/mss_draminit.C
+++ b/src/usr/hwpf/hwp/dram_training/mss_draminit/mss_draminit.C
@@ -1,27 +1,26 @@
-/* IBM_PROLOG_BEGIN_TAG
- * This is an automatically generated prolog.
- *
- * $Source: src/usr/hwpf/hwp/dram_training/mss_draminit/mss_draminit.C $
- *
- * IBM CONFIDENTIAL
- *
- * COPYRIGHT International Business Machines Corp. 2012
- *
- * p1
- *
- * Object Code Only (OCO) source materials
- * Licensed Internal Code Source Materials
- * IBM HostBoot Licensed Internal Code
- *
- * The source code for this program is not published or other-
- * wise divested of its trade secrets, irrespective of what has
- * been deposited with the U.S. Copyright Office.
- *
- * Origin: 30
- *
- * IBM_PROLOG_END_TAG
- */
-// $Id: mss_draminit.C,v 1.35 2012/07/27 16:44:38 bellows Exp $
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/hwpf/hwp/dram_training/mss_draminit/mss_draminit.C $ */
+/* */
+/* IBM CONFIDENTIAL */
+/* */
+/* COPYRIGHT International Business Machines Corp. 2012 */
+/* */
+/* p1 */
+/* */
+/* Object Code Only (OCO) source materials */
+/* Licensed Internal Code Source Materials */
+/* IBM HostBoot Licensed Internal Code */
+/* */
+/* The source code for this program is not published or otherwise */
+/* divested of its trade secrets, irrespective of what has been */
+/* deposited with the U.S. Copyright Office. */
+/* */
+/* Origin: 30 */
+/* */
+/* IBM_PROLOG_END_TAG */
+// $Id: mss_draminit.C,v 1.43 2012/12/07 13:44:07 bellows Exp $
//------------------------------------------------------------------------------
// Don't forget to create CVS comments when you check in your changes!
//------------------------------------------------------------------------------
@@ -29,6 +28,14 @@
//------------------------------------------------------------------------------
// Version:| Author: | Date: | Comment:
//---------|----------|---------|-----------------------------------------------
+// 1.43 | bellows | 12/06/12| Fixed Review Comment
+// 1.42 | jdsloat | 12/02/12| SHADOW REG PRINT OUT FIX
+// 1.41 | jdsloat | 11/19/12| RCD Bit order fix.
+// 1.40 | jdsloat | 11/17/12| MPR operation bit (MRS3, ADDR2) fix
+// 1.39 | gollub | 9/05/12 | Calling mss_unmask_draminit_errors after mss_draminit_cloned
+// 1.38 | jdsloat | 8/29/12 | Fixed Shadow Regs with Regression
+// 1.37 | jdsloat | 8/28/12 | Revert back to 1.35.
+// 1.36 | jdsloat | 7/25/12 | Printing out contents of MRS shadow registers.
// 1.35 | bellows | 7/25/12 | CQ 216395 (move force mclk low deassert to phyreset, resetn toggle)
// 1.34 | bellows | 7/16/12 | added in Id tag
// 1.33 | jdsloat | 6/26/12 | Added rtt_nom rank by rank value.
@@ -82,16 +89,19 @@
//----------------------------------------------------------------------
#include <mss_funcs.H>
#include "cen_scom_addresses.H"
+#include <mss_unmask_errors.H>
//----------------------------------------------------------------------
// Constants
//----------------------------------------------------------------------
const uint8_t MAX_NUM_DIMMS = 2;
-const uint8_t MAX_NUM_PORTS = 2;
+const uint8_t MAX_NUM_PORTS = 2;
+const uint8_t MAX_NUM_RANK_PAIR = 4;
const uint8_t MRS0_BA = 0;
const uint8_t MRS1_BA = 1;
const uint8_t MRS2_BA = 2;
const uint8_t MRS3_BA = 3;
+const uint8_t INVALID = 255;
extern "C" {
@@ -103,6 +113,7 @@ ReturnCode mss_mrs_load( Target& i_target, uint32_t i_port_number, uint32_t& io_
ReturnCode mss_assert_resetn_drive_mem_clks( Target& i_target);
ReturnCode mss_deassert_force_mclk_low( Target& i_target);
ReturnCode mss_assert_resetn ( Target& i_target, uint8_t value);
+ReturnCode mss_draminit_cloned(Target& i_target);
const uint64_t DELAY_100NS = 100; // general purpose 100 ns delay for HW mode (2000 sim cycles if simclk = 20ghz)
const uint64_t DELAY_1US = 1000; // general purpose 1 usec delay for HW mode (20000 sim cycles if simclk = 20ghz)
@@ -114,13 +125,54 @@ const uint64_t DELAY_2000000SIMCYCLES = 2000000; // general purpose 2000000 s
ReturnCode mss_draminit(Target& i_target)
{
// Target is centaur.mba
+
+ ReturnCode rc;
+
+ rc = mss_draminit_cloned(i_target);
+
+ // If mss_unmask_draminit_errors gets it's own bad rc,
+ // it will commit the passed in rc (if non-zero), and return it's own bad rc.
+ // Else if mss_unmask_draminit_errors runs clean,
+ // it will just return the passed in rc.
+ rc = mss_unmask_draminit_errors(i_target, rc);
+
+ return rc;
+}
+
+ReturnCode mss_draminit_cloned(Target& i_target)
+{
+ // Target is centaur.mba
//
ReturnCode rc;
+ ReturnCode rc_buff;
+ uint32_t rc_num = 0;
uint32_t port_number;
uint32_t ccs_inst_cnt = 0;
uint8_t dram_gen;
- uint8_t dimm_type;
+ uint8_t dimm_type;
+ uint8_t rank_pair_group = 0;
+ ecmdDataBufferBase data_buffer_64(64);
+ ecmdDataBufferBase mrs0(16);
+ ecmdDataBufferBase mrs1(16);
+ ecmdDataBufferBase mrs2(16);
+ ecmdDataBufferBase mrs3(16);
+ uint16_t MRS0 = 0;
+ uint16_t MRS1 = 0;
+ uint16_t MRS2 = 0;
+ uint16_t MRS3 = 0;
+ uint8_t primary_ranks_array[4][2]; //primary_ranks_array[group][port]
+
+ //populate primary_ranks_arrays_array
+ rc = FAPI_ATTR_GET(ATTR_EFF_PRIMARY_RANK_GROUP0, &i_target, primary_ranks_array[0]);
+ if(rc) return rc;
+ rc = FAPI_ATTR_GET(ATTR_EFF_PRIMARY_RANK_GROUP1, &i_target, primary_ranks_array[1]);
+ if(rc) return rc;
+ rc = FAPI_ATTR_GET(ATTR_EFF_PRIMARY_RANK_GROUP2, &i_target, primary_ranks_array[2]);
+ if(rc) return rc;
+ rc = FAPI_ATTR_GET(ATTR_EFF_PRIMARY_RANK_GROUP3, &i_target, primary_ranks_array[3]);
+ if(rc) return rc;
+
rc = FAPI_ATTR_GET(ATTR_EFF_DRAM_GEN, &i_target, dram_gen);
if(rc) return rc;
@@ -214,6 +266,248 @@ ReturnCode mss_draminit(Target& i_target)
FAPI_INF("No Memory configured.");
}
+ // Cycle through Ports...
+ // Ports 0-1
+ for ( port_number = 0; port_number < MAX_NUM_PORTS; port_number++)
+ {
+
+ for ( rank_pair_group = 0; rank_pair_group < MAX_NUM_RANK_PAIR; rank_pair_group++)
+ {
+ //Check if rank group exists
+ if((primary_ranks_array[rank_pair_group][0] != INVALID) || (primary_ranks_array[rank_pair_group][1] != INVALID))
+ {
+
+ if (port_number == 0){
+ // Get contents of MRS Shadow Regs and Print it to output
+ if (rank_pair_group == 0)
+ {
+ rc = fapiGetScom(i_target, DPHY01_DDRPHY_PC_MR0_PRI_RP0_P0_0x8000C01C0301143F, data_buffer_64);
+ if(rc) return rc;
+ rc_num = rc_num | data_buffer_64.reverse();
+ rc_num = rc_num | mrs0.insert(data_buffer_64, 0, 16);
+ rc_num = rc_num | mrs0.extractPreserve(&MRS0, 0, 16, 0);
+ FAPI_INF( "PORT %d SHADOW REGISTER MRS 0 RP %d VALUE: 0x%04X", port_number, rank_pair_group, MRS0 );
+
+ rc = fapiGetScom(i_target, DPHY01_DDRPHY_PC_MR1_PRI_RP0_P0_0x8000C01D0301143F, data_buffer_64);
+ rc_num = rc_num | data_buffer_64.reverse();
+ rc_num = rc_num | mrs1.insert(data_buffer_64, 0, 16);
+ rc_num = rc_num | mrs1.extractPreserve(&MRS1, 0, 16, 0);
+ FAPI_INF( "PORT %d SHADOW REGISTER MRS 1 RP %d VALUE: 0x%04X", port_number, rank_pair_group, MRS1);
+
+ rc = fapiGetScom(i_target, DPHY01_DDRPHY_PC_MR2_PRI_RP0_P0_0x8000C01E0301143F, data_buffer_64);
+ rc_num = rc_num | data_buffer_64.reverse();
+ rc_num = rc_num | mrs2.insert(data_buffer_64, 0, 16);
+ rc_num = rc_num | mrs2.extractPreserve(&MRS2, 0, 16, 0);
+ FAPI_INF( "PORT %d SHADOW REGISTER MRS 2 RP %d VALUE: 0x%04X", port_number, rank_pair_group, MRS2);
+
+ rc = fapiGetScom(i_target, DPHY01_DDRPHY_PC_MR3_PRI_RP0_P0_0x8000C01F0301143F, data_buffer_64);
+ rc_num = rc_num | data_buffer_64.reverse();
+ rc_num = rc_num | mrs3.insert(data_buffer_64, 0, 16);
+ rc_num = rc_num | mrs3.extractPreserve(&MRS3, 0, 16, 0);
+ FAPI_INF( "PORT %d SHADOW REGISTER MRS 3 RP %d VALUE: 0x%04X", port_number, rank_pair_group, MRS3);
+
+ }
+ else if (rank_pair_group == 1)
+ {
+ rc = fapiGetScom(i_target, DPHY01_DDRPHY_PC_MR0_PRI_RP1_P0_0x8000C11C0301143F, data_buffer_64);
+ rc_num = rc_num | data_buffer_64.reverse();
+ rc_num = rc_num | mrs0.insert(data_buffer_64, 0, 16);
+ rc_num = rc_num | mrs0.extractPreserve(&MRS0, 0, 16, 0);
+ FAPI_INF( "PORT %d SHADOW REGISTER MRS 0 RP %d VALUE: 0x%04X", port_number, rank_pair_group, MRS0);
+
+ rc = fapiGetScom(i_target, DPHY01_DDRPHY_PC_MR1_PRI_RP1_P0_0x8000C11D0301143F, data_buffer_64);
+ rc_num = rc_num | data_buffer_64.reverse();
+ rc_num = rc_num | mrs1.insert(data_buffer_64, 0, 16);
+ rc_num = rc_num | mrs1.extractPreserve(&MRS1, 0, 16, 0);
+ FAPI_INF( "PORT %d SHADOW REGISTER MRS 1 RP %d VALUE: 0x%04X", port_number, rank_pair_group, MRS1);
+
+ rc = fapiGetScom(i_target, DPHY01_DDRPHY_PC_MR2_PRI_RP1_P0_0x8000C11E0301143F, data_buffer_64);
+ rc_num = rc_num | data_buffer_64.reverse();
+ rc_num = rc_num | mrs2.insert(data_buffer_64, 0, 16);
+ rc_num = rc_num | mrs2.extractPreserve(&MRS2, 0, 16, 0);
+ FAPI_INF( "PORT %d SHADOW REGISTER MRS 2 RP %d VALUE: 0x%04X", port_number, rank_pair_group, MRS2);
+
+ rc = fapiGetScom(i_target, DPHY01_DDRPHY_PC_MR3_PRI_RP1_P0_0x8000C11F0301143F, data_buffer_64);
+ rc_num = rc_num | data_buffer_64.reverse();
+ rc_num = rc_num | mrs3.insert(data_buffer_64, 0, 16);
+ rc_num = rc_num | mrs3.extractPreserve(&MRS3, 0, 16, 0);
+ FAPI_INF( "PORT %d SHADOW REGISTER MRS 3 RP %d VALUE: 0x%04X", port_number, rank_pair_group, MRS3);
+
+ }
+ else if (rank_pair_group == 2)
+ {
+ rc = fapiGetScom(i_target, DPHY01_DDRPHY_PC_MR0_PRI_RP2_P0_0x8000C21C0301143F, data_buffer_64);
+ rc_num = rc_num | data_buffer_64.reverse();
+ rc_num = rc_num | mrs0.insert(data_buffer_64, 0, 16);
+ rc_num = rc_num | mrs0.extractPreserve(&MRS0, 0, 16, 0);
+ FAPI_INF( "PORT %d SHADOW REGISTER MRS 0 RP %d VALUE: 0x%04X", port_number, rank_pair_group, MRS0);
+
+ rc = fapiGetScom(i_target, DPHY01_DDRPHY_PC_MR1_PRI_RP2_P0_0x8000C21D0301143F, data_buffer_64);
+ rc_num = rc_num | data_buffer_64.reverse();
+ rc_num = rc_num | mrs1.insert(data_buffer_64, 0, 16);
+ rc_num = rc_num | mrs1.extractPreserve(&MRS1, 0, 16, 0);
+ FAPI_INF( "PORT %d SHADOW REGISTER MRS 1 RP %d VALUE: 0x%04X", port_number, rank_pair_group, MRS1);
+
+ rc = fapiGetScom(i_target, DPHY01_DDRPHY_PC_MR2_PRI_RP2_P0_0x8000C21E0301143F, data_buffer_64);
+ rc_num = rc_num | data_buffer_64.reverse();
+ rc_num = rc_num | mrs2.insert(data_buffer_64, 0, 16);
+ rc_num = rc_num | mrs2.extractPreserve(&MRS2, 0, 16, 0);
+ FAPI_INF( "PORT %d SHADOW REGISTER MRS 2 RP %d VALUE: 0x%04X", port_number, rank_pair_group, MRS2);
+
+ rc = fapiGetScom(i_target, DPHY01_DDRPHY_PC_MR3_PRI_RP2_P0_0x8000C21F0301143F, data_buffer_64);
+ rc_num = rc_num | data_buffer_64.reverse();
+ rc_num = rc_num | mrs3.insert(data_buffer_64, 0, 16);
+ rc_num = rc_num | mrs3.extractPreserve(&MRS3, 0, 16, 0);
+ FAPI_INF( "PORT %d SHADOW REGISTER MRS 3 RP %d VALUE: 0x%04X", port_number, rank_pair_group, MRS3);
+ }
+ else if (rank_pair_group == 3)
+ {
+ rc = fapiGetScom(i_target, DPHY01_DDRPHY_PC_MR0_PRI_RP3_P0_0x8000C31C0301143F, data_buffer_64);
+ rc_num = rc_num | data_buffer_64.reverse();
+ rc_num = rc_num | mrs0.insert(data_buffer_64, 0, 16);
+ rc_num = rc_num | mrs0.extractPreserve(&MRS0, 0, 16, 0);
+ FAPI_INF( "PORT %d SHADOW REGISTER MRS 0 RP %d VALUE: 0x%04X", port_number, rank_pair_group, MRS0);
+
+ rc = fapiGetScom(i_target, DPHY01_DDRPHY_PC_MR1_PRI_RP3_P0_0x8000C31D0301143F, data_buffer_64);
+ rc_num = rc_num | data_buffer_64.reverse();
+ rc_num = rc_num | mrs1.insert(data_buffer_64, 0, 16);
+ rc_num = rc_num | mrs1.extractPreserve(&MRS1, 0, 16, 0);
+ FAPI_INF( "PORT %d SHADOW REGISTER MRS 1 RP %d VALUE: 0x%04X", port_number, rank_pair_group, MRS1);
+
+ rc = fapiGetScom(i_target, DPHY01_DDRPHY_PC_MR2_PRI_RP3_P0_0x8000C31E0301143F, data_buffer_64);
+ rc_num = rc_num | data_buffer_64.reverse();
+ rc_num = rc_num | mrs2.insert(data_buffer_64, 0, 16);
+ rc_num = rc_num | mrs2.extractPreserve(&MRS2, 0, 16, 0);
+ FAPI_INF( "PORT %d SHADOW REGISTER MRS 2 RP %d VALUE: 0x%04X", port_number, rank_pair_group, MRS2);
+
+ rc = fapiGetScom(i_target, DPHY01_DDRPHY_PC_MR3_PRI_RP3_P0_0x8000C31F0301143F, data_buffer_64);
+ rc_num = rc_num | data_buffer_64.reverse();
+ rc_num = rc_num | mrs3.insert(data_buffer_64, 0, 16);
+ rc_num = rc_num | mrs3.extractPreserve(&MRS3, 0, 16, 0);
+ FAPI_INF( "PORT %d SHADOW REGISTER MRS 3 RP %d VALUE: 0x%04X", port_number, rank_pair_group, MRS3);
+ }
+ }
+ else if (port_number == 1)
+ {
+ if (rank_pair_group == 0)
+ {
+ rc = fapiGetScom(i_target, DPHY01_DDRPHY_PC_MR0_PRI_RP0_P1_0x8001C01C0301143F, data_buffer_64);
+ rc_num = rc_num | data_buffer_64.reverse();
+ rc_num = rc_num | mrs0.insert(data_buffer_64, 0, 16);
+ rc_num = rc_num | mrs0.extractPreserve(&MRS0, 0, 16, 0);
+ FAPI_INF( "PORT %d SHADOW REGISTER MRS 0 RP %d VALUE: 0x%04X", port_number, rank_pair_group, MRS0 );
+
+ rc = fapiGetScom(i_target, DPHY01_DDRPHY_PC_MR1_PRI_RP0_P1_0x8001C01D0301143F, data_buffer_64);
+ rc_num = rc_num | data_buffer_64.reverse();
+ rc_num = rc_num | mrs1.insert(data_buffer_64, 0, 16);
+ rc_num = rc_num | mrs1.extractPreserve(&MRS1, 0, 16, 0);
+ FAPI_INF( "PORT %d SHADOW REGISTER MRS 1 RP %d VALUE: 0x%04X", port_number, rank_pair_group, MRS1);
+
+ rc = fapiGetScom(i_target, DPHY01_DDRPHY_PC_MR2_PRI_RP0_P1_0x8001C01E0301143F, data_buffer_64);
+ rc_num = rc_num | data_buffer_64.reverse();
+ rc_num = rc_num | mrs2.insert(data_buffer_64, 0, 16);
+ rc_num = rc_num | mrs2.extractPreserve(&MRS2, 0, 16, 0);
+ FAPI_INF( "PORT %d SHADOW REGISTER MRS 2 RP %d VALUE: 0x%04X", port_number, rank_pair_group, MRS2);
+
+ rc = fapiGetScom(i_target, DPHY01_DDRPHY_PC_MR3_PRI_RP0_P1_0x8001C01F0301143F, data_buffer_64);
+ rc_num = rc_num | data_buffer_64.reverse();
+ rc_num = rc_num | mrs3.insert(data_buffer_64, 0, 16);
+ rc_num = rc_num | mrs3.extractPreserve(&MRS3, 0, 16, 0);
+ FAPI_INF( "PORT %d SHADOW REGISTER MRS 3 RP %d VALUE: 0x%04X", port_number, rank_pair_group, MRS3);
+
+ }
+ else if (rank_pair_group == 1)
+ {
+ rc = fapiGetScom(i_target, DPHY01_DDRPHY_PC_MR0_PRI_RP1_P1_0x8001C11C0301143F, data_buffer_64);
+ rc_num = rc_num | data_buffer_64.reverse();
+ rc_num = rc_num | mrs0.insert(data_buffer_64, 0, 16);
+ rc_num = rc_num | mrs0.extractPreserve(&MRS0, 0, 16, 0);
+ FAPI_INF( "PORT %d SHADOW REGISTER MRS 0 RP %d VALUE: 0x%04X", port_number, rank_pair_group, MRS0);
+
+ rc = fapiGetScom(i_target, DPHY01_DDRPHY_PC_MR1_PRI_RP1_P1_0x8001C11D0301143F, data_buffer_64);
+ rc_num = rc_num | data_buffer_64.reverse();
+ rc_num = rc_num | mrs1.insert(data_buffer_64, 0, 16);
+ rc_num = rc_num | mrs1.extractPreserve(&MRS1, 0, 16, 0);
+ FAPI_INF( "PORT %d SHADOW REGISTER MRS 1 RP %d VALUE: 0x%04X", port_number, rank_pair_group, MRS1);
+
+ rc = fapiGetScom(i_target, DPHY01_DDRPHY_PC_MR2_PRI_RP1_P1_0x8001C11E0301143F, data_buffer_64);
+ rc_num = rc_num | data_buffer_64.reverse();
+ rc_num = rc_num | mrs2.insert(data_buffer_64, 0, 16);
+ rc_num = rc_num | mrs2.extractPreserve(&MRS2, 0, 16, 0);
+ FAPI_INF( "PORT %d SHADOW REGISTER MRS 2 RP %d VALUE: 0x%04X", port_number, rank_pair_group, MRS2);
+
+ rc = fapiGetScom(i_target, DPHY01_DDRPHY_PC_MR3_PRI_RP1_P1_0x8001C11F0301143F, data_buffer_64);
+ rc_num = rc_num | data_buffer_64.reverse();
+ rc_num = rc_num | mrs3.insert(data_buffer_64, 0, 16);
+ rc_num = rc_num | mrs3.extractPreserve(&MRS3, 0, 16, 0);
+ FAPI_INF( "PORT %d SHADOW REGISTER MRS 3 RP %d VALUE: 0x%04X", port_number, rank_pair_group, MRS3);
+
+ }
+ else if (rank_pair_group == 2)
+ {
+ rc = fapiGetScom(i_target, DPHY01_DDRPHY_PC_MR0_PRI_RP2_P1_0x8001C21C0301143F, data_buffer_64);
+ rc_num = rc_num | data_buffer_64.reverse();
+ rc_num = rc_num | mrs0.insert(data_buffer_64, 0, 16);
+ rc_num = rc_num | mrs0.extractPreserve(&MRS0, 0, 16, 0);
+ FAPI_INF( "PORT %d SHADOW REGISTER MRS 0 RP %d VALUE: 0x%04X", port_number, rank_pair_group, MRS0);
+
+ rc = fapiGetScom(i_target, DPHY01_DDRPHY_PC_MR1_PRI_RP2_P1_0x8001C21D0301143F, data_buffer_64);
+ rc_num = rc_num | data_buffer_64.reverse();
+ rc_num = rc_num | mrs1.insert(data_buffer_64, 0, 16);
+ rc_num = rc_num | mrs1.extractPreserve(&MRS1, 0, 16, 0);
+ FAPI_INF( "PORT %d SHADOW REGISTER MRS 1 RP %d VALUE: 0x%04X", port_number, rank_pair_group, MRS1);
+
+ rc = fapiGetScom(i_target, DPHY01_DDRPHY_PC_MR2_PRI_RP2_P1_0x8001C21E0301143F, data_buffer_64);
+ rc_num = rc_num | data_buffer_64.reverse();
+ rc_num = rc_num | mrs2.insert(data_buffer_64, 0, 16);
+ rc_num = rc_num | mrs2.extractPreserve(&MRS2, 0, 16, 0);
+ FAPI_INF( "PORT %d SHADOW REGISTER MRS 2 RP %d VALUE: 0x%04X", port_number, rank_pair_group, MRS2);
+
+ rc = fapiGetScom(i_target, DPHY01_DDRPHY_PC_MR3_PRI_RP2_P1_0x8001C21F0301143F, data_buffer_64);
+ rc_num = rc_num | data_buffer_64.reverse();
+ rc_num = rc_num | mrs3.insert(data_buffer_64, 0, 16);
+ rc_num = rc_num | mrs3.extractPreserve(&MRS3, 0, 16, 0);
+ FAPI_INF( "PORT %d SHADOW REGISTER MRS 3 RP %d VALUE: 0x%04X", port_number, rank_pair_group, MRS3);
+ }
+ else if (rank_pair_group == 3)
+ {
+ rc = fapiGetScom(i_target, DPHY01_DDRPHY_PC_MR0_PRI_RP3_P1_0x8001C31C0301143F, data_buffer_64);
+ rc_num = rc_num | data_buffer_64.reverse();
+ rc_num = rc_num | mrs0.insert(data_buffer_64, 0, 16);
+ rc_num = rc_num | mrs0.extractPreserve(&MRS0, 0, 16, 0);
+ FAPI_INF( "PORT %d SHADOW REGISTER MRS 0 RP %d VALUE: 0x%04X", port_number, rank_pair_group, MRS0);
+
+ rc = fapiGetScom(i_target, DPHY01_DDRPHY_PC_MR1_PRI_RP3_P1_0x8001C31D0301143F, data_buffer_64);
+ rc_num = rc_num | data_buffer_64.reverse();
+ rc_num = rc_num | mrs1.insert(data_buffer_64, 0, 16);
+ rc_num = rc_num | mrs1.extractPreserve(&MRS1, 0, 16, 0);
+ FAPI_INF( "PORT %d SHADOW REGISTER MRS 1 RP %d VALUE: 0x%04X", port_number, rank_pair_group, MRS1);
+
+ rc = fapiGetScom(i_target, DPHY01_DDRPHY_PC_MR2_PRI_RP3_P1_0x8001C31E0301143F, data_buffer_64);
+ rc_num = rc_num | data_buffer_64.reverse();
+ rc_num = rc_num | mrs2.insert(data_buffer_64, 0, 16);
+ rc_num = rc_num | mrs2.extractPreserve(&MRS2, 0, 16, 0);
+ FAPI_INF( "PORT %d SHADOW REGISTER MRS 2 RP %d VALUE: 0x%04X", port_number, rank_pair_group, MRS2);
+
+ rc = fapiGetScom(i_target, DPHY01_DDRPHY_PC_MR3_PRI_RP3_P1_0x8001C31F0301143F, data_buffer_64);
+ rc_num = rc_num | data_buffer_64.reverse();
+ rc_num = rc_num | mrs3.insert(data_buffer_64, 0, 16);
+ rc_num = rc_num | mrs3.extractPreserve(&MRS3, 0, 16, 0);
+ FAPI_INF( "PORT %d SHADOW REGISTER MRS 3 RP %d VALUE: 0x%04X", port_number, rank_pair_group, MRS3);
+ }
+
+ }
+ }
+ }
+ }
+
+ if (rc_num)
+ {
+ FAPI_ERR( "mss_draminit: Error setting up buffers");
+ rc_buff.setEcmdError(rc_num);
+ return rc_buff;
+ }
+
// TODO:
// This is Commented out because RCD Parity Check has not been written yet.
@@ -423,10 +717,10 @@ ReturnCode mss_rcd_load(
rc_num = rc_num | bank_3.insert(rcd_number, 2, 1, 28);
//control word values RCD0 = A3, RCD1 = A4, RCD2 = BA0, RCD3 = BA1
- rc_num = rc_num | address_16.insert(rcd_cntl_wrd_4, 3, 1, 0);
- rc_num = rc_num | address_16.insert(rcd_cntl_wrd_4, 4, 1, 1);
- rc_num = rc_num | bank_3.insert(rcd_cntl_wrd_4, 0, 1, 2);
- rc_num = rc_num | bank_3.insert(rcd_cntl_wrd_4, 1, 1, 3);
+ rc_num = rc_num | address_16.insert(rcd_cntl_wrd_4, 3, 1, 3);
+ rc_num = rc_num | address_16.insert(rcd_cntl_wrd_4, 4, 1, 2);
+ rc_num = rc_num | bank_3.insert(rcd_cntl_wrd_4, 0, 1, 1);
+ rc_num = rc_num | bank_3.insert(rcd_cntl_wrd_4, 1, 1, 0);
// Send out to the CCS array
rc_num = rc_num | num_idles_16.insertFromRight((uint32_t) 12, 0, 16);
@@ -482,6 +776,8 @@ ReturnCode mss_mrs_load(
ReturnCode rc_buff;
uint32_t rc_num = 0;
+ ecmdDataBufferBase data_buffer_64(64);
+
ecmdDataBufferBase address_16(16);
ecmdDataBufferBase bank_3(3);
ecmdDataBufferBase activate_1(1);
@@ -795,11 +1091,11 @@ ReturnCode mss_mrs_load(
if (mpr_op == ENUM_ATTR_EFF_MPR_MODE_ENABLE)
{
- mpr_op = 0x00;
+ mpr_op = 0xFF;
}
else if (mpr_op == ENUM_ATTR_EFF_MPR_MODE_DISABLE)
{
- mpr_op = 0xFF;
+ mpr_op = 0x00;
}
// Raise CKE high with NOPS, waiting min Reset CKE exit time (tXPR) - 400 cycles
@@ -1030,6 +1326,7 @@ ReturnCode mss_mrs_load(
}
}
}
+
return rc;
}
diff --git a/src/usr/hwpf/hwp/dram_training/mss_draminit_mc/mss_draminit_mc.C b/src/usr/hwpf/hwp/dram_training/mss_draminit_mc/mss_draminit_mc.C
index f08e71da8..e1d9537bc 100644
--- a/src/usr/hwpf/hwp/dram_training/mss_draminit_mc/mss_draminit_mc.C
+++ b/src/usr/hwpf/hwp/dram_training/mss_draminit_mc/mss_draminit_mc.C
@@ -1,27 +1,26 @@
-/* IBM_PROLOG_BEGIN_TAG
- * This is an automatically generated prolog.
- *
- * $Source: src/usr/hwpf/hwp/dram_training/mss_draminit_mc/mss_draminit_mc.C $
- *
- * IBM CONFIDENTIAL
- *
- * COPYRIGHT International Business Machines Corp. 2012
- *
- * p1
- *
- * Object Code Only (OCO) source materials
- * Licensed Internal Code Source Materials
- * IBM HostBoot Licensed Internal Code
- *
- * The source code for this program is not published or other-
- * wise divested of its trade secrets, irrespective of what has
- * been deposited with the U.S. Copyright Office.
- *
- * Origin: 30
- *
- * IBM_PROLOG_END_TAG
- */
-// $Id: mss_draminit_mc.C,v 1.24 2012/07/17 13:23:51 bellows Exp $
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/hwpf/hwp/dram_training/mss_draminit_mc/mss_draminit_mc.C $ */
+/* */
+/* IBM CONFIDENTIAL */
+/* */
+/* COPYRIGHT International Business Machines Corp. 2012 */
+/* */
+/* p1 */
+/* */
+/* Object Code Only (OCO) source materials */
+/* Licensed Internal Code Source Materials */
+/* IBM HostBoot Licensed Internal Code */
+/* */
+/* The source code for this program is not published or otherwise */
+/* divested of its trade secrets, irrespective of what has been */
+/* deposited with the U.S. Copyright Office. */
+/* */
+/* Origin: 30 */
+/* */
+/* IBM_PROLOG_END_TAG */
+// $Id: mss_draminit_mc.C,v 1.26 2012/09/11 14:35:22 jdsloat Exp $
//------------------------------------------------------------------------------
// *! (C) Copyright International Business Machines Corp. 2011
// *! All Rights Reserved -- Property of IBM
@@ -45,6 +44,7 @@
//------------------------------------------------------------------------------
// Version:| Author: | Date: | Comment:
//---------|----------|---------|-----------------------------------------------
+// 1.25 | jdsloat |11-SEP-12| Changed Periodic Cal to Execute via MBA regs depending upon the ZQ Cal and MEM Cal timer values; 0 = disabled
// 1.24 | bellows |16-JUL-12| added in Id tag
// 1.22 | bellows |13-JUL-12| Fixed periodic cal bit 61 being set. HW214829
// 1.20 | jdsloat |21-MAY-12| Typo fix, addresses moved to cen_scom_addresses.H, moved per cal settings to initfile
@@ -213,85 +213,54 @@ ReturnCode mss_enable_periodic_cal (Target& i_target)
ecmdDataBufferBase mba01_data_buffer_64_p0(64);
ecmdDataBufferBase mba01_data_buffer_64_p1(64);
- //Determine whether or not we want to do a particular type of calibration on the given ranks
- //ALL CALS CURRENTLY SET AS ON, ONLY CHECK RANK PAIRS PRESENT
- //***mba01 Setup
- rc_num = rc_num | mba01_data_buffer_64_p0.flushTo0();
- rc = fapiGetScom(i_target, DPHY01_DDRPHY_PC_PER_CAL_CONFIG_P0_0x8000C00B0301143F, mba01_data_buffer_64_p0);
- if(rc) return rc;
-
- rc_num = rc_num | mba01_data_buffer_64_p1.flushTo0();
- rc = fapiGetScom(i_target, DPHY01_DDRPHY_PC_PER_CAL_CONFIG_P1_0x8001C00B0301143F, mba01_data_buffer_64_p1);
- if(rc) return rc;
+ ecmdDataBufferBase data_buffer_64(64);
- uint8_t primary_rank_group0_array[2]; //[rank]
- rc = FAPI_ATTR_GET(ATTR_EFF_PRIMARY_RANK_GROUP0, &i_target, primary_rank_group0_array);
+ uint32_t memcal_iterval; // 00 = Disable
+ rc = FAPI_ATTR_GET(ATTR_EFF_MEMCAL_INTERVAL, &i_target, memcal_iterval);
if(rc) return rc;
- uint8_t primary_rank_group1_array[2]; //[rank]
- rc = FAPI_ATTR_GET(ATTR_EFF_PRIMARY_RANK_GROUP1, &i_target, primary_rank_group1_array);
+ uint32_t zq_cal_iterval; // 00 = Disable
+ rc = FAPI_ATTR_GET(ATTR_EFF_ZQCAL_INTERVAL, &i_target, zq_cal_iterval);
if(rc) return rc;
- uint8_t primary_rank_group2_array[2]; //[rank]
- rc = FAPI_ATTR_GET(ATTR_EFF_PRIMARY_RANK_GROUP2, &i_target, primary_rank_group2_array);
+ rc_num = rc_num | data_buffer_64.flushTo0();
+ rc = fapiGetScom(i_target, MBA01_MBA_CAL0Q_0x0301040F, data_buffer_64);
if(rc) return rc;
- uint8_t primary_rank_group3_array[2]; //[rank]
- rc = FAPI_ATTR_GET(ATTR_EFF_PRIMARY_RANK_GROUP3, &i_target, primary_rank_group3_array);
- if(rc) return rc;
+ FAPI_INF("+++ Enabling Periodic Calibration +++");
- if(primary_rank_group0_array[0] != 255)
+ if (zq_cal_iterval != 0)
{
- //Rank Group 0 Enabled
- rc_num = rc_num | mba01_data_buffer_64_p0.setBit(48);
+ //ZQ Cal Enabled
+ rc_num = rc_num | data_buffer_64.setBit(0);
+ FAPI_INF("+++ Periodic Calibration: ZQ Cal Enabled p0+++");
}
- if(primary_rank_group1_array[0] != 255)
+ else
{
- //Rank Group 1 Enabled
- rc_num = rc_num | mba01_data_buffer_64_p0.setBit(49);
+ //ZQ Cal Disabled
+ rc_num = rc_num | data_buffer_64.clearBit(0);
+ FAPI_INF("+++ Periodic Calibration: ZQ Cal Disabled p0+++");
}
- if(primary_rank_group2_array[0] != 255)
- {
- //Rank Group 2 Enabled
- rc_num = rc_num | mba01_data_buffer_64_p0.setBit(50);
- }
- if(primary_rank_group3_array[0] != 255)
- {
- //Rank Group 3 Enabled
- rc_num = rc_num | mba01_data_buffer_64_p0.setBit(51);
- }
- if(primary_rank_group0_array[1] != 255)
- {
- //Rank Group 0 Enabled
- rc_num = rc_num | mba01_data_buffer_64_p1.setBit(48);
- }
- if(primary_rank_group1_array[1] != 255)
- {
- //Rank Group 1 Enabled
- rc_num = rc_num | mba01_data_buffer_64_p1.setBit(49);
- }
- if(primary_rank_group2_array[1] != 255)
+
+ rc = fapiPutScom(i_target, MBA01_MBA_CAL0Q_0x0301040F, data_buffer_64);
+ if(rc) return rc;
+
+ rc_num = rc_num | data_buffer_64.flushTo0();
+ rc = fapiGetScom(i_target, MBA01_MBA_CAL1Q_0x03010410, data_buffer_64);
+ if (memcal_iterval != 0)
{
- //Rank Group 2 Enabled
- rc_num = rc_num | mba01_data_buffer_64_p1.setBit(50);
+ //Mem Cal Enabled
+ rc_num = rc_num | data_buffer_64.setBit(0);
+ FAPI_INF("+++ Periodic Calibration: Mem Cal Enabled p0+++");
}
- if(primary_rank_group3_array[1] != 255)
+ else
{
- //Rank Group 3 Enabled
- rc_num = rc_num | mba01_data_buffer_64_p1.setBit(51);
+ //Mem Cal Disabled
+ rc_num = rc_num | data_buffer_64.clearBit(0);
+ FAPI_INF("+++ Periodic Calibration: Mem Cal Disabled p0+++");
}
-
- //Start the periodic Cal
- // do not set bit 61 - HW214829
- // rc_num = rc_num | mba01_data_buffer_64_p1.setBit(61);
-
- //Write the mba_p01_PER_CAL_CFG_REG
- rc = fapiPutScom(i_target, DPHY01_DDRPHY_PC_PER_CAL_CONFIG_P0_0x8000C00B0301143F, mba01_data_buffer_64_p0);
- if(rc) return rc;
- FAPI_INF("+++ Periodic Calibration Enabled p0+++");
- rc = fapiPutScom(i_target, DPHY01_DDRPHY_PC_PER_CAL_CONFIG_P1_0x8001C00B0301143F, mba01_data_buffer_64_p1);
+ rc = fapiPutScom(i_target, MBA01_MBA_CAL1Q_0x03010410, data_buffer_64);
if(rc) return rc;
- FAPI_INF("+++ Periodic Calibration Enabled p1+++");
if (rc_num)
{
diff --git a/src/usr/hwpf/hwp/dram_training/mss_draminit_training/mss_draminit_training.C b/src/usr/hwpf/hwp/dram_training/mss_draminit_training/mss_draminit_training.C
index 59ef4df63..6c1e965fa 100644
--- a/src/usr/hwpf/hwp/dram_training/mss_draminit_training/mss_draminit_training.C
+++ b/src/usr/hwpf/hwp/dram_training/mss_draminit_training/mss_draminit_training.C
@@ -1,27 +1,26 @@
-/* IBM_PROLOG_BEGIN_TAG
- * This is an automatically generated prolog.
- *
- * $Source: src/usr/hwpf/hwp/dram_training/mss_draminit_training/mss_draminit_training.C $
- *
- * IBM CONFIDENTIAL
- *
- * COPYRIGHT International Business Machines Corp. 2012
- *
- * p1
- *
- * Object Code Only (OCO) source materials
- * Licensed Internal Code Source Materials
- * IBM HostBoot Licensed Internal Code
- *
- * The source code for this program is not published or other-
- * wise divested of its trade secrets, irrespective of what has
- * been deposited with the U.S. Copyright Office.
- *
- * Origin: 30
- *
- * IBM_PROLOG_END_TAG
- */
-// $Id: mss_draminit_training.C,v 1.29 2012/07/17 13:23:56 bellows Exp $
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/hwpf/hwp/dram_training/mss_draminit_training/mss_draminit_training.C $ */
+/* */
+/* IBM CONFIDENTIAL */
+/* */
+/* COPYRIGHT International Business Machines Corp. 2012 */
+/* */
+/* p1 */
+/* */
+/* Object Code Only (OCO) source materials */
+/* Licensed Internal Code Source Materials */
+/* IBM HostBoot Licensed Internal Code */
+/* */
+/* The source code for this program is not published or otherwise */
+/* divested of its trade secrets, irrespective of what has been */
+/* deposited with the U.S. Copyright Office. */
+/* */
+/* Origin: 30 */
+/* */
+/* IBM_PROLOG_END_TAG */
+// $Id: mss_draminit_training.C,v 1.43 2012/12/07 13:46:10 bellows Exp $
//------------------------------------------------------------------------------
// Don't forget to create CVS comments when you check in your changes!
//------------------------------------------------------------------------------
@@ -29,6 +28,21 @@
//------------------------------------------------------------------------------
// Version:| Author: | Date: | Comment:
//---------|----------|---------|------------------------------------------------
+// 1.42 | bellows |06-DEC-12| Fixed up review comments
+// 1.41 | jdsloat |02-DEC-12| Fixed RTT_NOM swap for Port 1
+// 1.40 | jdsloat |30-NOV-12| Temporarily comment Bad Bit Mask.
+// 1.39 | jdsloat |18-NOV-12| Fixed CAL_STEP to allow Zq Cal.
+// 1.38 | jdsloat |16-NOV-12| Fixed Error Place holder and port addressing with BBM
+// 1.37 | jdsloat |12-NOV-12| Fixed a bracket typo.
+// 1.36 | jdsloat |07-NOV-12| Changed procedure to proceed through ALL rank_pair, Ports before reporting
+// | | | error status for partial good support. Added Bad Bit Mask to disable regs function
+// | | | and disable regs to Bad Bit Mask function.
+// 1.35 | jdsloat |08-OCT-12| Changed Write to Read,Modify,Write of Phy Init Cal Config Reg
+// 1.34 | jdsloat |25-SEP-12| Bit 0 of Cal Step Attribute now offers an all at once option - bit 0 =1 if stepbystep
+// 1.33 | jdsloat |07-SEP-12| Broke init_cal down to step by step keyed off of CAL_STEP_ENABLE attribute
+// 1.32 | jdsloat |29-AUG-12| Fixed mss_rtt_nom_rtt_wr_swap and verified with regression
+// 1.31 | bellows |28-AUG-12| Revert back to 1.29 until regression pass again
+// 1.30 | jdsloat |23-AUG-12| Added mss_rtt_nom_rtt_wr_swap pre and post init_cal
// 1.29 | bellows |16-Jul-12| bellows | added in Id tag
// 1.28 | bellows |02-May-12| cal ranks are 4 bits, this needed to be adjusted
// 1.26 | asaetow |12-Apr-12| Added "if(rc) return rc;" at line 180.
@@ -77,12 +91,6 @@
// 1.2 | jdsloat |14-Jul-11| Proper call name fix
// 1.1 | jdsloat |22-Apr-11| Initial draft
-//TODO:
-//Enable appropriate init cal steps in PC Initial Calibration Config0 based on CAL_STEP attribute
-//Add error path when Cal fails
-//Enable complex training procedure based on DIMM_TYPE
-//Check BAD BYTE attribute with DISABLE DP18
-//Figure out DISABLE DP18 mapping for each physical byte.
//----------------------------------------------------------------------
// FAPI function Includes
@@ -95,9 +103,34 @@
//----------------------------------------------------------------------
#include <cen_scom_addresses.H>
#include <mss_funcs.H>
+#include <dimmBadDqBitmapFuncs.H>
//------------End My Includes-------------------------------------------
+//----------------------------------------------------------------------
+// Constants
+//----------------------------------------------------------------------
+const uint8_t MRS1_BA = 1;
+const uint8_t MRS2_BA = 2;
+
+#define MAX_PORTS 2
+#define MAX_PRI_RANKS 4
+#define TOTAL_BYTES 10
+#define BITS_PER_REG 16
+#define DP18_INSTANCES 5
+#define BITS_PER_PORT (BITS_PER_REG*DP18_INSTANCES)
+
+//----------------------------------------------------------------------
+// Enums
+//----------------------------------------------------------------------
+
+enum mss_draminit_training_result
+{
+ MSS_INIT_CAL_COMPLETE = 1,
+ MSS_INIT_CAL_PASS = 2,
+ MSS_INIT_CAL_STALL = 3,
+ MSS_INIT_CAL_FAIL = 4
+};
extern "C" {
@@ -105,7 +138,13 @@ extern "C" {
using namespace fapi;
ReturnCode mss_draminit_training(Target& i_target);
-ReturnCode mss_check_cal_status(Target& i_target, uint8_t i_port, uint8_t i_group);
+ReturnCode mss_check_cal_status(Target& i_target, uint8_t i_port, uint8_t i_group, mss_draminit_training_result& io_status);
+ReturnCode mss_check_error_status(Target& i_target, uint8_t i_port, uint8_t i_group, mss_draminit_training_result& io_status);
+ReturnCode mss_rtt_nom_rtt_wr_swap( Target& i_target, uint32_t i_port_number, uint8_t i_rank, uint32_t i_rank_pair_group, uint32_t& io_ccs_inst_cnt);
+ReturnCode getC4dq2reg(const Target &i_mba, const uint8_t i_port, const uint8_t i_dimm, const uint8_t i_rank, ecmdDataBufferBase &o_reg);
+ReturnCode setC4dq2reg(const Target &i_mba, const uint8_t i_port, const uint8_t i_dimm, const uint8_t i_rank, ecmdDataBufferBase &o_reg);
+ReturnCode mss_set_bbm_regs (const fapi::Target & mba_target);
+ReturnCode mss_get_bbm_regs (const fapi::Target & mba_target);
ReturnCode mss_draminit_training(Target& i_target)
{
@@ -116,10 +155,12 @@ ReturnCode mss_draminit_training(Target& i_target)
MAX_NUM_PORT = 2,
MAX_NUM_DIMM = 2,
MAX_NUM_GROUP = 4,
+ MAX_CAL_STEPS = 7, //read course and write course will occur at the sametime
INVALID = 255
};
+
const uint32_t NUM_POLL = 100;
-
+
ReturnCode rc;
uint32_t rc_num = 0;
@@ -167,6 +208,22 @@ ReturnCode mss_draminit_training(Target& i_target)
rc_num = rc_num | cal_timeout_cnt_mult_buffer_2.flushTo1();
ecmdDataBufferBase data_buffer_64(64);
+
+ //TEMP MBA CAL REGS bit 12 = 0
+ rc = fapiGetScom(i_target, MBA01_MBA_CAL0Q_0x0301040F, data_buffer_64);
+ if(rc) return rc;
+ rc_num = rc_num | data_buffer_64.clearBit(12);
+ FAPI_INF("+++ TEMP setting bit 12 to 0+++");
+ rc = fapiPutScom(i_target, MBA01_MBA_CAL0Q_0x0301040F, data_buffer_64);
+ if(rc) return rc;
+
+ rc = fapiGetScom(i_target, MBA01_MBA_CAL1Q_0x03010410, data_buffer_64);
+ if(rc) return rc;
+ rc_num = rc_num | data_buffer_64.clearBit(12);
+ FAPI_INF("+++ TEMP setting bit 12 to 0+++");
+ rc = fapiPutScom(i_target, MBA01_MBA_CAL1Q_0x03010410, data_buffer_64);
+ if(rc) return rc;
+
if(rc_num)
{
rc.setEcmdError(rc_num);
@@ -175,10 +232,17 @@ ReturnCode mss_draminit_training(Target& i_target)
uint8_t port = 0;
uint8_t group = 0;
-
uint8_t primary_ranks_array[4][2]; //primary_ranks_array[group][port]
+ uint8_t cal_steps = 0;
+ uint8_t cur_cal_step = 0;
+ ecmdDataBufferBase cal_steps_8(8);
+
+ enum mss_draminit_training_result cur_complete_status = MSS_INIT_CAL_COMPLETE;
+ enum mss_draminit_training_result cur_error_status = MSS_INIT_CAL_PASS;
+
+ enum mss_draminit_training_result complete_status = MSS_INIT_CAL_COMPLETE;
+ enum mss_draminit_training_result error_status = MSS_INIT_CAL_PASS;
-
//populate primary_ranks_arrays_array
rc = FAPI_ATTR_GET(ATTR_EFF_PRIMARY_RANK_GROUP0, &i_target, primary_ranks_array[0]);
if(rc) return rc;
@@ -189,9 +253,15 @@ ReturnCode mss_draminit_training(Target& i_target)
rc = FAPI_ATTR_GET(ATTR_EFF_PRIMARY_RANK_GROUP3, &i_target, primary_ranks_array[3]);
if(rc) return rc;
+ //Get which training steps we are to run
+ rc = FAPI_ATTR_GET(ATTR_MSS_CAL_STEP_ENABLE, &i_target, cal_steps);
+ if(rc) return rc;
+ rc_num = rc_num | cal_steps_8.insert(cal_steps, 0, 8, 0);
+
//Set up CCS Mode Reg for Init cal
rc = fapiGetScom(i_target, MEM_MBA01_CCS_MODEQ_0x030106A7, data_buffer_64);
if(rc) return rc;
+
rc_num = rc_num | data_buffer_64.insert(stop_on_err_buffer_1, 0, 1, 0);
rc_num = rc_num | data_buffer_64.insert(cal_timeout_cnt_buffer_16, 8, 16, 0);
rc_num = rc_num | data_buffer_64.insert(resetn_buffer_1, 24, 1, 0);
@@ -201,114 +271,330 @@ ReturnCode mss_draminit_training(Target& i_target)
rc.setEcmdError(rc_num);
return rc;
}
+
rc = fapiPutScom(i_target, MEM_MBA01_CCS_MODEQ_0x030106A7, data_buffer_64);
if(rc) return rc;
- for(port = 0; port < MAX_NUM_PORT; port++)
+
+ //rc = mss_set_bbm_regs (i_target);
+ //if(rc)
+ //{
+ //FAPI_ERR( "Error Moving bad bit information to the Phy regs. Exiting.");
+ //return rc;
+ //}
+
+ if ( ( cal_steps_8.isBitSet(0) ) ||
+ ( (cal_steps_8.isBitClear(0)) && (cal_steps_8.isBitClear(1)) &&
+ (cal_steps_8.isBitClear(2)) && (cal_steps_8.isBitClear(3)) &&
+ (cal_steps_8.isBitClear(4)) && (cal_steps_8.isBitClear(5)) &&
+ (cal_steps_8.isBitClear(6)) && (cal_steps_8.isBitClear(7)) ))
{
- rc = mss_execute_zq_cal(i_target, port);
- if(rc) return rc;
+ FAPI_INF( "Performing External ZQ Calibration.");
+
+ //Execute ZQ_CAL
+ for(port = 0; port < MAX_NUM_PORT; port++)
+ {
+ rc = mss_execute_zq_cal(i_target, port);
+ if(rc) return rc;
+ }
+
}
- //Set up for Init Cal - Done per port pair
- rc_num = rc_num | test_buffer_4.setBit(0, 2); //Init Cal test = 11XX
- rc_num = rc_num | wen_buffer_1.flushTo1(); //Init Cal ras/cas/we = 1/1/1
- rc_num = rc_num | casn_buffer_1.flushTo1();
- rc_num = rc_num | rasn_buffer_1.flushTo1();
- rc_num = rc_num | ddr_cal_enable_buffer_1.flushTo1(); //Init cal
- if(rc_num)
+ for(port = 0; port < MAX_NUM_PORT; port++)
{
- rc.setEcmdError(rc_num);
- return rc;
- }
- for(group = 0; group < MAX_NUM_GROUP; group++)
- {
- if((primary_ranks_array[group][0] != INVALID) || (primary_ranks_array[group][1] != INVALID))
- {
- //Check if rank group exists
- FAPI_INF( "+++++++++++++++ Sending init cal on rank group: %d +++++++++++++++", group);
- rc = mss_ccs_inst_arry_0(i_target, instruction_number, address_buffer_16, bank_buffer_8, activate_buffer_1, rasn_buffer_1, casn_buffer_1, wen_buffer_1, cke_buffer_8, csn_buffer_8, odt_buffer_8, test_buffer_4, 0);
- if(rc) return rc; //Error handling for mss_ccs_inst built into mss_funcs
- FAPI_INF( "primary_ranks_array[%d][0]: %d [%d][1]: %d", group, primary_ranks_array[group][0],
- group, primary_ranks_array[group][1]);
- if(primary_ranks_array[group][0] == INVALID)
- {
- rc_num = rc_num | rank_cal_buffer_4.insert(primary_ranks_array[group][1], 0, 4, 4); // 8 bit storage, need last 4 bits
- }
- else
- {
- rc_num = rc_num | rank_cal_buffer_4.insert(primary_ranks_array[group][0], 0, 4, 4); // 8 bit storage, need last 4 bits
- }
- rc = mss_ccs_inst_arry_1(i_target, instruction_number, num_idles_buffer_16, num_repeat_buffer_16, data_buffer_20, read_compare_buffer_1, rank_cal_buffer_4, ddr_cal_enable_buffer_1, ccs_end_buffer_1);
- if(rc) return rc; //Error handling for mss_ccs_inst built into mss_funcs
- FAPI_INF( "+++++++++++++++ Execute CCS array +++++++++++++++");
- rc = mss_execute_ccs_inst_array( i_target, NUM_POLL, 60);
- if(rc) return rc; //Error handling for mss_ccs_inst built into mss_funcs
- for(port = 0; port < 2; port++)
- {
- rc = mss_check_cal_status(i_target, port, group);
+ for(group = 0; group < MAX_NUM_GROUP; group++)
+ {
+
+ //Check if rank group exists
+ if(primary_ranks_array[group][port] != INVALID)
+ {
+
+ // Change the RTT_NOM to RTT_WR, RTT_WR to RTT_NOM
+ rc = mss_rtt_nom_rtt_wr_swap(i_target, port, primary_ranks_array[group][port], group, instruction_number);
if(rc) return rc;
- }
- }
+
+
+ //Set up for Init Cal - Done per port pair
+ rc_num = rc_num | test_buffer_4.setBit(0, 2); //Init Cal test = 11XX
+ rc_num = rc_num | wen_buffer_1.flushTo1(); //Init Cal ras/cas/we = 1/1/1
+ rc_num = rc_num | casn_buffer_1.flushTo1();
+ rc_num = rc_num | rasn_buffer_1.flushTo1();
+ rc_num = rc_num | ddr_cal_enable_buffer_1.flushTo1(); //Init cal
+
+ FAPI_INF( "+++++++++++++++ Sending init cal on rank group: %d cal_steps: 0x%02X +++++++++++++++", group, cal_steps);
+
+ for(cur_cal_step = 1; cur_cal_step < MAX_CAL_STEPS; cur_cal_step++) //Cycle through all possible cal steps
+ {
+ //Setup the Config Reg bit for the only cal step we want
+ rc = fapiGetScom(i_target, DPHY01_DDRPHY_PC_INIT_CAL_CONFIG0_P0_0x8000C0160301143F, data_buffer_64);
+ if(rc) return rc;
+
+ rc_num = rc_num | data_buffer_64.clearBit(48);
+ rc_num = rc_num | data_buffer_64.clearBit(50);
+ rc_num = rc_num | data_buffer_64.clearBit(51);
+ rc_num = rc_num | data_buffer_64.clearBit(52);
+ rc_num = rc_num | data_buffer_64.clearBit(53);
+ rc_num = rc_num | data_buffer_64.clearBit(54);
+ rc_num = rc_num | data_buffer_64.clearBit(55);
+
+ if ( (cur_cal_step == 1) && (cal_steps_8.isBitClear(0)) && (cal_steps_8.isBitClear(1)) &&
+ (cal_steps_8.isBitClear(2)) && (cal_steps_8.isBitClear(3)) &&
+ (cal_steps_8.isBitClear(4)) && (cal_steps_8.isBitClear(5)) &&
+ (cal_steps_8.isBitClear(6)) && (cal_steps_8.isBitClear(7)) )
+ {
+ FAPI_INF( "+++++ Sending ALL Cal Steps at the same time on rank group: %d +++++", group);
+ rc_num = rc_num | data_buffer_64.setBit(48);
+ rc_num = rc_num | data_buffer_64.setBit(50);
+ rc_num = rc_num | data_buffer_64.setBit(51);
+ rc_num = rc_num | data_buffer_64.setBit(52);
+ rc_num = rc_num | data_buffer_64.setBit(53);
+ rc_num = rc_num | data_buffer_64.setBit(54);
+ rc_num = rc_num | data_buffer_64.setBit(55);
+ }
+ else if ( (cur_cal_step == 1) && (cal_steps_8.isBitSet(1)) )
+ {
+ FAPI_INF( "+++++ Sending Write Leveling (WR_LVL) on rank group: %d +++++", group);
+ rc_num = rc_num | data_buffer_64.setBit(48);
+ }
+ else if ( (cur_cal_step == 2) && (cal_steps_8.isBitSet(2)) )
+ {
+ FAPI_INF( "+++++ Sending DQS Align (DQS_ALIGN) on rank group: %d +++++", group);
+ rc_num = rc_num | data_buffer_64.setBit(50);
+ }
+ else if ( (cur_cal_step == 3) && (cal_steps_8.isBitSet(3)) )
+ {
+ FAPI_INF( "+++++ Sending RD CLK Align (RDCLK_ALIGN) on rank group: %d +++++", group);
+ rc_num = rc_num | data_buffer_64.setBit(51);
+ }
+ else if ( (cur_cal_step == 4) && (cal_steps_8.isBitSet(4)) )
+ {
+ FAPI_INF( "+++++ Sending Read Centering (READ_CTR) on rank group: %d +++++", group);
+ rc_num = rc_num | data_buffer_64.setBit(52);
+ }
+ else if ( (cur_cal_step == 5) && (cal_steps_8.isBitSet(5)) )
+ {
+ FAPI_INF( "+++++ Sending Write Centering (WRITE_CTR) on rank group: %d +++++", group);
+ rc_num = rc_num | data_buffer_64.setBit(53);
+ }
+ else if ( (cur_cal_step == 6) && (cal_steps_8.isBitSet(6)) && (cal_steps_8.isBitClear(7)) )
+ {
+ FAPI_INF( "+++++ Sending Initial Course Write (COURSE_WR) on rank group: %d +++++", group);
+ rc_num = rc_num | data_buffer_64.setBit(54);
+ }
+ else if ( (cur_cal_step == 6) && (cal_steps_8.isBitClear(6)) && (cal_steps_8.isBitSet(7)) )
+ {
+ FAPI_INF( "+++++ Sending Course Read (COURSE_RD) on rank group: %d +++++", group);
+ rc_num = rc_num | data_buffer_64.setBit(55);
+ }
+ else if ( (cur_cal_step == 6) && (cal_steps_8.isBitSet(6)) && (cal_steps_8.isBitSet(7)) )
+ {
+ FAPI_INF( "+++++ Sending Initial Course Write (COURSE_WR) and Course Read (COURSE_RD) on rank group: %d +++++", group);
+ rc_num = rc_num | data_buffer_64.setBit(54);
+ rc_num = rc_num | data_buffer_64.setBit(55);
+ }
+
+ if(rc_num)
+ {
+ rc.setEcmdError(rc_num);
+ return rc;
+ }
+
+ if ( !( data_buffer_64.isBitClear(48, 8) ) ) // Only execute if we are doing a Cal Step
+ {
+
+ //Set the config register
+ if(port == 0)
+ {
+ rc = fapiPutScom(i_target, DPHY01_DDRPHY_PC_INIT_CAL_CONFIG0_P0_0x8000C0160301143F, data_buffer_64);
+ if(rc) return rc;
+ }
+ else
+ {
+ rc = fapiPutScom(i_target, DPHY01_DDRPHY_PC_INIT_CAL_CONFIG0_P1_0x8001C0160301143F, data_buffer_64);
+ if(rc) return rc;
+ }
+
+ rc = mss_ccs_inst_arry_0(i_target,
+ instruction_number,
+ address_buffer_16,
+ bank_buffer_8,
+ activate_buffer_1,
+ rasn_buffer_1,
+ casn_buffer_1,
+ wen_buffer_1,
+ cke_buffer_8,
+ csn_buffer_8,
+ odt_buffer_8,
+ test_buffer_4,
+ port);
+
+ if(rc) return rc; //Error handling for mss_ccs_inst built into mss_funcs
+
+ FAPI_INF( "primary_ranks_array[%d][0]: %d [%d][1]: %d", group, primary_ranks_array[group][0], group, primary_ranks_array[group][1]);
+
+
+ rc_num = rc_num | rank_cal_buffer_4.insert(primary_ranks_array[group][port], 0, 4, 4); // 8 bit storage, need last 4 bits
+
+ rc = mss_ccs_inst_arry_1(i_target,
+ instruction_number,
+ num_idles_buffer_16,
+ num_repeat_buffer_16,
+ data_buffer_20,
+ read_compare_buffer_1,
+ rank_cal_buffer_4,
+ ddr_cal_enable_buffer_1,
+ ccs_end_buffer_1);
+
+ if(rc) return rc; //Error handling for mss_ccs_inst built into mss_funcs
+
+ FAPI_INF( "+++++++++++++++ Execute CCS array +++++++++++++++");
+
+ rc = mss_execute_ccs_inst_array( i_target, NUM_POLL, 60);
+ if(rc) return rc; //Error handling for mss_ccs_inst built into mss_funcs
+
+ //Check to see if the training completes
+ rc = mss_check_cal_status(i_target, port, group, cur_complete_status);
+ if(rc) return rc;
+
+ if (cur_complete_status == MSS_INIT_CAL_STALL)
+ {
+ complete_status = cur_complete_status;
+ }
+
+ //Check to see if the training errored out
+ rc = mss_check_error_status(i_target, port, group, cur_error_status);
+ if(rc) return rc;
+
+ if (cur_error_status == MSS_INIT_CAL_FAIL)
+ {
+ error_status = cur_error_status;
+ }
+
+ }
+ }//end of step loop
+
+ // Change the RTT_NOM to RTT_WR, RTT_WR to RTT_NOM
+ rc = mss_rtt_nom_rtt_wr_swap(i_target, port, primary_ranks_array[group][port], group, instruction_number);
+ }
+ }//end of group loop
+ }//end of port loop
+
+ if(rc) return rc;
+ //rc = mss_get_bbm_regs(i_target);
+ //if(rc)
+ //{
+ //FAPI_ERR( "Error Moving bad bit information from the Phy regs. Exiting.");
+ //return rc;
+ //}
+
+ if (complete_status == MSS_INIT_CAL_STALL)
+ {
+ FAPI_ERR( "+++++++++++++++ Calibration on stalled! +++++++++++++++");
+ FAPI_SET_HWP_ERROR(rc, RC_MSS_DRAMINIT_TRAINING_INIT_CAL_STALLED);
}
+ else if (error_status == MSS_INIT_CAL_FAIL)
+ {
+ FAPI_ERR( "+++++++++++++++ Calibration on failed! +++++++++++++++");
+ FAPI_SET_HWP_ERROR(rc, RC_MSS_DRAMINIT_TRAINING_INIT_CAL_FAILED);
+ }
+
return rc;
}
-ReturnCode mss_check_cal_status(
- Target& i_target,
- uint8_t i_port,
- uint8_t i_group
- ) {
+
+ReturnCode mss_check_cal_status( Target& i_target,
+ uint8_t i_port,
+ uint8_t i_group,
+ mss_draminit_training_result& io_status
+ )
+{
ecmdDataBufferBase cal_status_buffer_64(64);
- ecmdDataBufferBase cal_error_buffer_64(64);
+
uint8_t cal_status_reg_offset = 0;
- uint8_t cal_error_reg_offset = 0;
cal_status_reg_offset = 48 + i_group;
- cal_error_reg_offset = 60 + i_group;
+
uint8_t poll_count = 1;
ReturnCode rc;
FAPI_INF( "+++++++++++++++ Check Cal Status on port: %d rank group: %d +++++++++++++++", i_port, i_group);
+
if(i_port == 0)
{
rc = fapiGetScom(i_target, DPHY01_DDRPHY_PC_INIT_CAL_STATUS_P0_0x8000C0190301143F, cal_status_buffer_64);
if(rc) return rc;
- rc = fapiGetScom(i_target, DPHY01_DDRPHY_PC_INIT_CAL_ERROR_P0_0x8000C0180301143F, cal_error_buffer_64);
- if(rc) return rc;
}
else
{
rc = fapiGetScom(i_target, DPHY01_DDRPHY_PC_INIT_CAL_STATUS_P1_0x8001C0190301143F, cal_status_buffer_64);
if(rc) return rc;
- rc = fapiGetScom(i_target, DPHY01_DDRPHY_PC_INIT_CAL_ERROR_P1_0x8001C0180301143F, cal_error_buffer_64);
- if(rc) return rc;
}
- while((!cal_status_buffer_64.isBitSet(cal_status_reg_offset)) && (!cal_error_buffer_64.isBitSet(cal_error_reg_offset)) && (poll_count <= 20))
+
+ while((!cal_status_buffer_64.isBitSet(cal_status_reg_offset)) &&
+ (poll_count <= 20))
{
FAPI_INF( "+++++++++++++++ Calibration on port: %d rank group: %d in progress. Poll count: %d +++++++++++++++", i_port, i_group, poll_count);
+
poll_count++;
if(i_port == 0)
{
rc = fapiGetScom(i_target, DPHY01_DDRPHY_PC_INIT_CAL_STATUS_P0_0x8000C0190301143F, cal_status_buffer_64);
if(rc) return rc;
- rc = fapiGetScom(i_target, DPHY01_DDRPHY_PC_INIT_CAL_ERROR_P0_0x8000C0180301143F, cal_error_buffer_64);
- if(rc) return rc;
}
else
{
rc = fapiGetScom(i_target, DPHY01_DDRPHY_PC_INIT_CAL_STATUS_P1_0x8001C0190301143F, cal_status_buffer_64);
if(rc) return rc;
- rc = fapiGetScom(i_target, DPHY01_DDRPHY_PC_INIT_CAL_ERROR_P1_0x8001C0180301143F, cal_error_buffer_64);
- if(rc) return rc;
}
+
+ }
+
+ if(cal_status_buffer_64.isBitSet(cal_status_reg_offset))
+ {
+ FAPI_INF( "+++++++++++++++ Calibration on port: %d rank group: %d Completed! +++++++++++++++", i_port, i_group);
+ io_status = MSS_INIT_CAL_COMPLETE;
+ }
+ else
+ {
+ FAPI_ERR( "+++++++++++++++ Calibration on port: %d rank group: %d has stalled! +++++++++++++++", i_port, i_group);
+ io_status = MSS_INIT_CAL_STALL;
}
+
+ return rc;
+}
+
+ReturnCode mss_check_error_status( Target& i_target,
+ uint8_t i_port,
+ uint8_t i_group,
+ mss_draminit_training_result& io_status
+ )
+{
+
+ ecmdDataBufferBase cal_error_buffer_64(64);
+
+ uint8_t cal_error_reg_offset = 0;
+ cal_error_reg_offset = 60 + i_group;
+
+ ReturnCode rc;
+
+ FAPI_INF( "+++++++++++++++ Check Error Status on port: %d rank group: %d +++++++++++++++", i_port, i_group);
+
+ if(i_port == 0)
+ {
+ rc = fapiGetScom(i_target, DPHY01_DDRPHY_PC_INIT_CAL_ERROR_P0_0x8000C0180301143F, cal_error_buffer_64);
+ if(rc) return rc;
+ }
+ else
+ {
+ rc = fapiGetScom(i_target, DPHY01_DDRPHY_PC_INIT_CAL_ERROR_P1_0x8001C0180301143F, cal_error_buffer_64);
+ if(rc) return rc;
+ }
+
if(cal_error_buffer_64.isBitSet(cal_error_reg_offset))
{
- //Should it be changed to FAPI_ERR once integrated to xml file. Using FAPI_INF so procedure moves to next group before erroring out.
FAPI_ERR( "+++++++++++++++ Calibration on port: %d rank group: %d failed! +++++++++++++++", i_port, i_group);
- FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR);
- //FAPI_SET_HWP_ERROR(rc, RC_MSS_INIT_CAL_FAILED);
+ io_status = MSS_INIT_CAL_FAIL;
+
if(cal_error_buffer_64.isBitSet(48))
{
FAPI_ERR( "+++++++++++++++ Write leveling error occured on port: %d rank group: %d! +++++++++++++++", i_port, i_group);
@@ -348,18 +634,1080 @@ ReturnCode mss_check_cal_status(
}
else
{
- if(cal_status_buffer_64.isBitSet(cal_status_reg_offset))
+ FAPI_INF( "+++++++++++++++ Calibration on port: %d rank group: %d was successful! +++++++++++++++", i_port, i_group);
+ io_status = MSS_INIT_CAL_PASS;
+ }
+
+ return rc;
+}
+
+ReturnCode mss_rtt_nom_rtt_wr_swap(
+ Target& i_target,
+ uint32_t i_port_number,
+ uint8_t i_rank,
+ uint32_t i_rank_pair_group,
+ uint32_t& io_ccs_inst_cnt
+ )
+{
+
+ ReturnCode rc;
+ ReturnCode rc_buff;
+ uint32_t rc_num = 0;
+
+ ecmdDataBufferBase address_16(16);
+ ecmdDataBufferBase bank_3(3);
+ ecmdDataBufferBase activate_1(1);
+ ecmdDataBufferBase rasn_1(1);
+ rc_num = rc_num | rasn_1.clearBit(0);
+ ecmdDataBufferBase casn_1(1);
+ rc_num = rc_num | casn_1.clearBit(0);
+ ecmdDataBufferBase wen_1(1);
+ rc_num = rc_num | wen_1.clearBit(0);
+ ecmdDataBufferBase cke_4(4);
+ rc_num = rc_num | cke_4.setBit(0,4);
+ ecmdDataBufferBase csn_8(8);
+ rc_num = rc_num | csn_8.setBit(0,8);
+ ecmdDataBufferBase odt_4(4);
+ rc_num = rc_num | odt_4.setBit(0,4);
+ ecmdDataBufferBase ddr_cal_type_4(4);
+
+ ecmdDataBufferBase num_idles_16(16);
+ ecmdDataBufferBase num_repeat_16(16);
+ ecmdDataBufferBase data_20(20);
+ ecmdDataBufferBase read_compare_1(1);
+ ecmdDataBufferBase rank_cal_4(4);
+ ecmdDataBufferBase ddr_cal_enable_1(1);
+ ecmdDataBufferBase ccs_end_1(1);
+
+ ecmdDataBufferBase mrs1_16(16);
+ ecmdDataBufferBase mrs2_16(16);
+
+ ecmdDataBufferBase data_buffer_64(64);
+
+ uint16_t MRS1 = 0;
+ uint16_t MRS2 = 0;
+
+ // Raise CKE high with NOPS, waiting min Reset CKE exit time (tXPR) - 400 cycles
+ rc_num = rc_num | csn_8.setBit(0,8);
+ rc_num = rc_num | address_16.clearBit(0, 16);
+ rc_num = rc_num | num_idles_16.insertFromRight((uint32_t) 400, 0, 16);
+ rc = mss_ccs_inst_arry_0( i_target,
+ io_ccs_inst_cnt,
+ address_16,
+ bank_3,
+ activate_1,
+ rasn_1,
+ casn_1,
+ wen_1,
+ cke_4,
+ csn_8,
+ odt_4,
+ ddr_cal_type_4,
+ i_port_number);
+ if(rc) return rc;
+ rc = mss_ccs_inst_arry_1( i_target,
+ io_ccs_inst_cnt,
+ num_idles_16,
+ num_repeat_16,
+ data_20,
+ read_compare_1,
+ rank_cal_4,
+ ddr_cal_enable_1,
+ ccs_end_1);
+ if(rc) return rc;
+ io_ccs_inst_cnt ++;
+
+ rc_num = rc_num | csn_8.setBit(0,8);
+ if (i_rank == 0)
+ {
+ rc_num = rc_num | csn_8.clearBit(0);
+ }
+ else if (i_rank == 1)
+ {
+ rc_num = rc_num | csn_8.clearBit(1);
+ }
+ else if (i_rank == 2)
+ {
+ rc_num = rc_num | csn_8.clearBit(2);
+ }
+ else if (i_rank == 3)
+ {
+ rc_num = rc_num | csn_8.clearBit(3);
+ }
+
+ // MRS CMD to CMD spacing = 12 cycles
+ rc_num = rc_num | num_idles_16.insertFromRight((uint32_t) 12, 0, 16);
+
+ FAPI_INF( "SWAPPING RTT_NOM AND RTT_WR FOR PORT%d RP%d", i_port_number, i_rank_pair_group);
+
+ //MRS1
+ // Get contents of MRS 1 Shadow Reg
+
+ if (i_port_number == 0){
+ if (i_rank_pair_group == 0)
+ {
+ rc = fapiGetScom(i_target, DPHY01_DDRPHY_PC_MR1_PRI_RP0_P0_0x8000C01D0301143F, data_buffer_64);
+ }
+ else if (i_rank_pair_group == 1)
+ {
+ rc = fapiGetScom(i_target, DPHY01_DDRPHY_PC_MR1_PRI_RP1_P0_0x8000C11D0301143F, data_buffer_64);
+ }
+ else if (i_rank_pair_group == 2)
+ {
+ rc = fapiGetScom(i_target, DPHY01_DDRPHY_PC_MR1_PRI_RP2_P0_0x8000C21D0301143F, data_buffer_64);
+ }
+ else if (i_rank_pair_group == 3)
+ {
+ rc = fapiGetScom(i_target, DPHY01_DDRPHY_PC_MR1_PRI_RP3_P0_0x8000C31D0301143F, data_buffer_64);
+ }
+ }
+ else if (i_port_number == 1){
+ if (i_rank_pair_group == 0)
+ {
+ rc = fapiGetScom(i_target, DPHY01_DDRPHY_PC_MR1_PRI_RP0_P1_0x8001C01D0301143F, data_buffer_64);
+ }
+ else if (i_rank_pair_group == 1)
+ {
+ rc = fapiGetScom(i_target, DPHY01_DDRPHY_PC_MR1_PRI_RP1_P1_0x8001C11D0301143F, data_buffer_64);
+ }
+ else if (i_rank_pair_group == 2)
+ {
+ rc = fapiGetScom(i_target, DPHY01_DDRPHY_PC_MR1_PRI_RP2_P1_0x8001C21D0301143F, data_buffer_64);
+ }
+ else if (i_rank_pair_group == 3)
+ {
+ rc = fapiGetScom(i_target, DPHY01_DDRPHY_PC_MR1_PRI_RP3_P1_0x8001C31D0301143F, data_buffer_64);
+ }
+ }
+
+ rc_num = rc_num | data_buffer_64.reverse();
+ rc_num = rc_num | mrs1_16.insert(data_buffer_64, 0, 16, 0);
+ rc_num = rc_num | mrs1_16.extractPreserve(&MRS1, 0, 16, 0);
+ FAPI_INF( "ORIGINAL MRS 1: 0x%04X", MRS1);
+
+ uint8_t dll_enable = 0x00; //DLL Enable
+ if (mrs1_16.isBitSet(0))
+ {
+ // DLL disabled
+ dll_enable = 0xFF;
+ }
+ else if (mrs1_16.isBitClear(0))
+ {
+ // DLL enabled
+ dll_enable = 0x00;
+ }
+
+ uint8_t out_drv_imp_cntl = 0x00;
+ if ( (mrs1_16.isBitClear(1)) && (mrs1_16.isBitClear(5)) )
+ {
+ // out_drv_imp_ctrl set to 40 (Rzq/6)
+ out_drv_imp_cntl = 0x00;
+ }
+ else if ( (mrs1_16.isBitSet(1)) && (mrs1_16.isBitClear(5)) )
+ {
+ // out_drv_imp_ctrl set to 34 (Rzq/7)
+ out_drv_imp_cntl = 0x80;
+ }
+
+ uint8_t dram_rtt_wr = 0x00;
+ if ( (mrs1_16.isBitClear(2)) && (mrs1_16.isBitClear(6)) && (mrs1_16.isBitClear(9)) )
+ {
+ // RTT_NOM set to disabled
+ //RTT WR Disabled
+ dram_rtt_wr = 0x00;
+ }
+ else if ( (mrs1_16.isBitClear(2)) && (mrs1_16.isBitClear(6)) && (mrs1_16.isBitSet(9)) )
+ {
+ // RTT_NOM set to 20
+ //RTT WR 60 OHM
+ dram_rtt_wr = 0x80;
+ }
+ else if ( (mrs1_16.isBitSet(2)) && (mrs1_16.isBitClear(6)) && (mrs1_16.isBitSet(9)) )
+ {
+ // RTT_NOM set to 30
+ //RTT WR 60 OHM
+ dram_rtt_wr = 0x80;
+ }
+ else if ( (mrs1_16.isBitSet(2)) && (mrs1_16.isBitSet(6)) && (mrs1_16.isBitClear(9)) )
+ {
+ // RTT_NOM set to 40
+ //RTT WR 60 OHM
+ dram_rtt_wr = 0x80;
+ }
+ else if ( (mrs1_16.isBitSet(2)) && (mrs1_16.isBitSet(6)) && (mrs1_16.isBitClear(9)) )
+ {
+ // RTT_NOM set to 60
+ //RTT WR 60 OHM
+ dram_rtt_wr = 0x80;
+ }
+ else if ( (mrs1_16.isBitClear(2)) && (mrs1_16.isBitSet(6)) && (mrs1_16.isBitClear(9)) )
+ {
+ // RTT_NOM set to 120
+ // RTT_WR set to 120
+ dram_rtt_wr = 0x40;
+ }
+
+ uint8_t dram_al = 0x00;
+ if ( (mrs1_16.isBitClear(3)) && (mrs1_16.isBitClear(4)) )
+ {
+ //AL DISABLED
+ dram_al = 0x00;
+ }
+ else if ( (mrs1_16.isBitSet(3)) && (mrs1_16.isBitClear(4)) )
+ {
+ // AL = CL -1
+ dram_al = 0x80;
+ }
+ else if ( (mrs1_16.isBitClear(3)) && (mrs1_16.isBitSet(4)) )
+ {
+ // AL = CL -2
+ dram_al = 0x40;
+ }
+
+ uint8_t wr_lvl = 0x00; //write leveling enable
+ if (mrs1_16.isBitClear(7))
+ {
+ // WR_LVL DISABLED
+ wr_lvl = 0x00;
+ }
+ else if (mrs1_16.isBitSet(7))
+ {
+ // WR_LVL ENABLED
+ wr_lvl = 0xFF;
+ }
+
+ uint8_t tdqs_enable = 0x00; //TDQS Enable
+ if (mrs1_16.isBitClear(11))
+ {
+ //TDQS DISABLED
+ tdqs_enable = 0x00;
+ }
+ else if (mrs1_16.isBitSet(11))
+ {
+ //TDQS ENABLED
+ tdqs_enable = 0xFF;
+ }
+
+ uint8_t q_off = 0x00; //Qoff - Output buffer Enable
+ if (mrs1_16.isBitSet(12))
+ {
+ //Output Buffer Disabled
+ q_off = 0xFF;
+ }
+ else if (mrs1_16.isBitClear(12))
+ {
+ //Output Buffer Enabled
+ q_off = 0x00;
+ }
+
+ //MRS2
+ // MRS CMD to CMD spacing = 12 cycles
+ rc_num = rc_num | num_idles_16.insertFromRight((uint32_t) 12, 0, 16);
+
+ // Get contents of MRS 1 Shadow Reg
+ if (i_port_number == 0){
+ if (i_rank_pair_group == 0)
+ {
+ rc = fapiGetScom(i_target, DPHY01_DDRPHY_PC_MR2_PRI_RP0_P0_0x8000C01E0301143F, data_buffer_64);
+ }
+ else if (i_rank_pair_group == 1)
+ {
+ rc = fapiGetScom(i_target, DPHY01_DDRPHY_PC_MR2_PRI_RP1_P0_0x8000C11E0301143F, data_buffer_64);
+ }
+ else if (i_rank_pair_group == 2)
{
- FAPI_INF( "+++++++++++++++ Calibration on port: %d rank group: %d was successful! +++++++++++++++", i_port, i_group);
+ rc = fapiGetScom(i_target, DPHY01_DDRPHY_PC_MR2_PRI_RP2_P0_0x8000C21E0301143F, data_buffer_64);
}
- else
+ else if (i_rank_pair_group == 3)
+ {
+ rc = fapiGetScom(i_target, DPHY01_DDRPHY_PC_MR2_PRI_RP3_P0_0x8000C31E0301143F, data_buffer_64);
+ }
+ }
+ else if (i_port_number == 1){
+ if (i_rank_pair_group == 0)
+ {
+ rc = fapiGetScom(i_target, DPHY01_DDRPHY_PC_MR2_PRI_RP0_P1_0x8001C01E0301143F, data_buffer_64);
+ }
+ else if (i_rank_pair_group == 1)
+ {
+ rc = fapiGetScom(i_target, DPHY01_DDRPHY_PC_MR2_PRI_RP1_P1_0x8001C11E0301143F, data_buffer_64);
+ }
+ else if (i_rank_pair_group == 2)
+ {
+ rc = fapiGetScom(i_target, DPHY01_DDRPHY_PC_MR2_PRI_RP2_P1_0x8001C21E0301143F, data_buffer_64);
+ }
+ else if (i_rank_pair_group == 3)
{
- FAPI_ERR( "+++++++++++++++ Calibration on port: %d rank group: %d has stalled! +++++++++++++++", i_port, i_group);
- //Should it be changed to FAPI_ERR once integrated to xml file. Using FAPI_INF so procedure moves to next group before erroring out.
- FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR);
+ rc = fapiGetScom(i_target, DPHY01_DDRPHY_PC_MR2_PRI_RP3_P1_0x8001C31E0301143F, data_buffer_64);
}
}
+
+ rc_num = rc_num | data_buffer_64.reverse();
+ rc_num = rc_num | mrs2_16.insert(data_buffer_64, 0, 16, 0);
+ rc_num = rc_num | mrs2_16.extractPreserve(&MRS2, 0, 16, 0);
+ FAPI_INF( "ORIGINAL MRS 2: 0x%04X", MRS2);
+
+ uint8_t pt_arr_sr = 0x00; //Partial Array Self Refresh
+ if ( (mrs2_16.isBitClear(0)) && (mrs2_16.isBitClear(1)) && (mrs2_16.isBitClear(2)) )
+ {
+ //PASR FULL
+ pt_arr_sr = 0x00;
+ }
+ else if ( (mrs2_16.isBitSet(0)) && (mrs2_16.isBitClear(1)) && (mrs2_16.isBitClear(2)) )
+ {
+ //PASR FIRST HALF
+ pt_arr_sr = 0x80;
+ }
+ else if ( (mrs2_16.isBitClear(0)) && (mrs2_16.isBitSet(1)) && (mrs2_16.isBitClear(2)) )
+ {
+ // PASR FIRST QUARTER
+ pt_arr_sr = 0x40;
+ }
+ else if ( (mrs2_16.isBitSet(0)) && (mrs2_16.isBitSet(1)) && (mrs2_16.isBitClear(2)) )
+ {
+ // PASR FIRST EIGHTH
+ pt_arr_sr = 0xC0;
+ }
+ else if ( (mrs2_16.isBitClear(0)) && (mrs2_16.isBitClear(1)) && (mrs2_16.isBitSet(2)) )
+ {
+ // PASR LAST FOURTH
+ pt_arr_sr = 0x20;
+ }
+ else if ( (mrs2_16.isBitSet(0)) && (mrs2_16.isBitClear(1)) && (mrs2_16.isBitSet(2)) )
+ {
+ // PASR LAST HALF
+ pt_arr_sr = 0xA0;
+ }
+ else if ( (mrs2_16.isBitClear(0)) && (mrs2_16.isBitSet(1)) && (mrs2_16.isBitSet(2)) )
+ {
+ // PASR LAST QUARTER
+ pt_arr_sr = 0x60;
+ }
+ else if ( (mrs2_16.isBitSet(0)) && (mrs2_16.isBitSet(1)) && (mrs2_16.isBitSet(2)) )
+ {
+ // PASR LAST EIGHTH
+ pt_arr_sr = 0xE0;
+ }
+
+ uint8_t cwl = 0x00; // CAS Write Latency
+ if ( (mrs2_16.isBitClear(3)) && (mrs2_16.isBitClear(4)) && (mrs2_16.isBitClear(5)) )
+ {
+ // CWL = 5
+ cwl = 0x00;
+ }
+ else if ( (mrs2_16.isBitSet(3)) && (mrs2_16.isBitClear(4)) && (mrs2_16.isBitClear(5)) )
+ {
+ // CWL = 6
+ cwl = 0x80;
+ }
+ else if ( (mrs2_16.isBitClear(3)) && (mrs2_16.isBitSet(4)) && (mrs2_16.isBitClear(5)) )
+ {
+ // CWL = 7
+ cwl = 0x40;
+ }
+ else if ( (mrs2_16.isBitSet(3)) && (mrs2_16.isBitSet(4)) && (mrs2_16.isBitClear(5)) )
+ {
+ // CWL = 8
+ cwl = 0xC0;
+ }
+ else if ( (mrs2_16.isBitClear(3)) && (mrs2_16.isBitClear(4)) && (mrs2_16.isBitSet(5)) )
+ {
+ // CWL = 9
+ cwl = 0x20;
+ }
+ else if ( (mrs2_16.isBitSet(3)) && (mrs2_16.isBitClear(4)) && (mrs2_16.isBitSet(5)) )
+ {
+ // CWL = 10
+ cwl = 0xA0;
+ }
+ else if ( (mrs2_16.isBitClear(3)) && (mrs2_16.isBitSet(4)) && (mrs2_16.isBitSet(5)) )
+ {
+ // CWL = 11
+ cwl = 0x60;
+ }
+ else if ( (mrs2_16.isBitSet(3)) && (mrs2_16.isBitSet(4)) && (mrs2_16.isBitSet(5)) )
+ {
+ // CWL = 12
+ cwl = 0xE0;
+ }
+
+ uint8_t auto_sr = 0x00; // Auto Self-Refresh
+ if ( (mrs2_16.isBitClear(6)) )
+ {
+ //AUTO SR = SRT
+ auto_sr = 0x00;
+ }
+ else if ( (mrs2_16.isBitSet(6)) )
+ {
+ //AUTO SR = ASR ENABLE
+ auto_sr = 0xFF;
+ }
+
+ uint8_t sr_temp = 0x00; // Self-Refresh Temp Range
+ if ( (mrs2_16.isBitClear(7)) )
+ {
+ //SRT NORMAL
+ sr_temp = 0x00;
+ }
+ else if ( (mrs2_16.isBitSet(7)) )
+ {
+ //SRT EXTEND
+ sr_temp = 0xFF;
+ }
+
+ uint8_t dram_rtt_nom = 0x00;
+ if ( (mrs2_16.isBitClear(9)) && (mrs2_16.isBitClear(10)) )
+ {
+ //RTT WR DISABLE
+ // RTT_NOM set to disabled
+ dram_rtt_nom = 0x00;
+ }
+ else if ( (mrs2_16.isBitSet(9)) && (mrs2_16.isBitClear(10)) )
+ {
+ //RTT WR 60 OHM
+ // RTT_NOM set to 60
+ dram_rtt_nom = 0x80;
+ }
+ else if ( (mrs2_16.isBitClear(9)) && (mrs2_16.isBitSet(10)) )
+ {
+ //RTT WR 120 OHM
+ // RTT_NOM set to 120
+ dram_rtt_nom = 0x40;
+ }
+
+ rc_num = rc_num | mrs1_16.insert((uint8_t) dll_enable, 0, 1, 0);
+ rc_num = rc_num | mrs1_16.insert((uint8_t) out_drv_imp_cntl, 1, 1, 0);
+ rc_num = rc_num | mrs1_16.insert((uint8_t) dram_rtt_nom, 2, 1, 0);
+ rc_num = rc_num | mrs1_16.insert((uint8_t) dram_al, 3, 2, 0);
+ rc_num = rc_num | mrs1_16.insert((uint8_t) out_drv_imp_cntl, 5, 1, 1);
+ rc_num = rc_num | mrs1_16.insert((uint8_t) dram_rtt_nom, 6, 1, 1);
+ rc_num = rc_num | mrs1_16.insert((uint8_t) wr_lvl, 7, 1, 0);
+ rc_num = rc_num | mrs1_16.insert((uint8_t) 0x00, 8, 1);
+ rc_num = rc_num | mrs1_16.insert((uint8_t) dram_rtt_nom, 9, 1, 2);
+ rc_num = rc_num | mrs1_16.insert((uint8_t) 0x00, 10, 1);
+ rc_num = rc_num | mrs1_16.insert((uint8_t) tdqs_enable, 11, 1, 0);
+ rc_num = rc_num | mrs1_16.insert((uint8_t) q_off, 12, 1, 0);
+ rc_num = rc_num | mrs1_16.insert((uint8_t) 0x00, 13, 3);
+
+ rc_num = rc_num | mrs1_16.extractPreserve(&MRS1, 0, 16, 0);
+ FAPI_INF( "NEW MRS 1: 0x%04X", MRS1);
+
+ rc_num = rc_num | address_16.insert(mrs1_16, 0, 16, 0);
+ rc_num = rc_num | bank_3.insert((uint8_t) MRS1_BA, 0, 1, 7);
+ rc_num = rc_num | bank_3.insert((uint8_t) MRS1_BA, 1, 1, 6);
+ rc_num = rc_num | bank_3.insert((uint8_t) MRS1_BA, 2, 1, 5);
+
+ if (rc_num)
+ {
+ FAPI_ERR( "mss_mrs_load: Error setting up buffers");
+ rc_buff.setEcmdError(rc_num);
+ return rc_buff;
+ }
+
+ // Send out to the CCS array
+ rc = mss_ccs_inst_arry_0( i_target,
+ io_ccs_inst_cnt,
+ address_16,
+ bank_3,
+ activate_1,
+ rasn_1,
+ casn_1,
+ wen_1,
+ cke_4,
+ csn_8,
+ odt_4,
+ ddr_cal_type_4,
+ i_port_number);
+ if(rc) return rc;
+ rc = mss_ccs_inst_arry_1( i_target,
+ io_ccs_inst_cnt,
+ num_idles_16,
+ num_repeat_16,
+ data_20,
+ read_compare_1,
+ rank_cal_4,
+ ddr_cal_enable_1,
+ ccs_end_1);
+ if(rc) return rc;
+ io_ccs_inst_cnt++;
+
+
+ rc_num = rc_num | mrs2_16.insert((uint8_t) pt_arr_sr, 0, 3);
+ rc_num = rc_num | mrs2_16.insert((uint8_t) cwl, 3, 3);
+ rc_num = rc_num | mrs2_16.insert((uint8_t) auto_sr, 6, 1);
+ rc_num = rc_num | mrs2_16.insert((uint8_t) sr_temp, 7, 1);
+ rc_num = rc_num | mrs2_16.insert((uint8_t) 0x00, 8, 1);
+ rc_num = rc_num | mrs2_16.insert((uint8_t) dram_rtt_wr, 9, 2);
+ rc_num = rc_num | mrs2_16.insert((uint8_t) 0x00, 10, 6);
+
+ rc_num = rc_num | mrs2_16.extractPreserve(&MRS2, 0, 16, 0);
+ FAPI_INF( "NEW MRS 2: 0x%04X", MRS2);
+
+ rc_num = rc_num | address_16.insert(mrs2_16, 0, 16, 0);
+ rc_num = rc_num | bank_3.insert((uint8_t) MRS2_BA, 0, 1, 7);
+ rc_num = rc_num | bank_3.insert((uint8_t) MRS2_BA, 1, 1, 6);
+ rc_num = rc_num | bank_3.insert((uint8_t) MRS2_BA, 2, 1, 5);
+
+ if (rc_num)
+ {
+ FAPI_ERR( "mss_mrs_load: Error setting up buffers");
+ rc_buff.setEcmdError(rc_num);
+ return rc_buff;
+ }
+
+ // Send out to the CCS array
+ rc = mss_ccs_inst_arry_0( i_target,
+ io_ccs_inst_cnt,
+ address_16,
+ bank_3,
+ activate_1,
+ rasn_1,
+ casn_1,
+ wen_1,
+ cke_4,
+ csn_8,
+ odt_4,
+ ddr_cal_type_4,
+ i_port_number);
+ if(rc) return rc;
+ rc = mss_ccs_inst_arry_1( i_target,
+ io_ccs_inst_cnt,
+ num_idles_16,
+ num_repeat_16,
+ data_20,
+ read_compare_1,
+ rank_cal_4,
+ ddr_cal_enable_1,
+ ccs_end_1);
+ if(rc) return rc;
+ io_ccs_inst_cnt++;
+
return rc;
+
+}
+
+fapi::ReturnCode mss_set_bbm_regs (const fapi::Target & mba_target)
+{
+ // Flash to registers.
+
+
+ const uint64_t disable_reg[MAX_PORTS][MAX_PRI_RANKS][DP18_INSTANCES] = {
+ /* port 0 */
+ { // primary rank pair 0
+ {DPHY01_DDRPHY_DP18_DATA_BIT_DISABLE0_RP0_P0_0_0x8000007c0301143F,
+ DPHY01_DDRPHY_DP18_DATA_BIT_DISABLE0_RP0_P0_1_0x8000047c0301143F,
+ DPHY01_DDRPHY_DP18_DATA_BIT_DISABLE0_RP0_P0_2_0x8000087c0301143F,
+ DPHY01_DDRPHY_DP18_DATA_BIT_DISABLE0_RP0_P0_3_0x80000c7c0301143F,
+ DPHY01_DDRPHY_DP18_DATA_BIT_DISABLE0_RP0_P0_4_0x8000107c0301143F},
+ // primary rank pair 1
+ {DPHY01_DDRPHY_DP18_DATA_BIT_DISABLE0_RP1_P0_0_0x8000017c0301143F,
+ DPHY01_DDRPHY_DP18_DATA_BIT_DISABLE0_RP1_P0_1_0x8000057c0301143F,
+ DPHY01_DDRPHY_DP18_DATA_BIT_DISABLE0_RP1_P0_2_0x8000097c0301143F,
+ DPHY01_DDRPHY_DP18_DATA_BIT_DISABLE0_RP1_P0_3_0x80000d7c0301143F,
+ DPHY01_DDRPHY_DP18_DATA_BIT_DISABLE0_RP1_P0_4_0x8000117c0301143F},
+ // primary rank pair 2
+ {DPHY01_DDRPHY_DP18_DATA_BIT_DISABLE0_RP2_P0_0_0x8000027c0301143F,
+ DPHY01_DDRPHY_DP18_DATA_BIT_DISABLE0_RP2_P0_1_0x8000067c0301143F,
+ DPHY01_DDRPHY_DP18_DATA_BIT_DISABLE0_RP2_P0_2_0x80000a7c0301143F,
+ DPHY01_DDRPHY_DP18_DATA_BIT_DISABLE0_RP2_P0_3_0x80000e7c0301143F,
+ DPHY01_DDRPHY_DP18_DATA_BIT_DISABLE0_RP2_P0_4_0x8000127c0301143F},
+ // primary rank pair 3
+ {DPHY01_DDRPHY_DP18_DATA_BIT_DISABLE0_RP3_P0_0_0x8000037c0301143F,
+ DPHY01_DDRPHY_DP18_DATA_BIT_DISABLE0_RP3_P0_1_0x8000077c0301143F,
+ DPHY01_DDRPHY_DP18_DATA_BIT_DISABLE0_RP3_P0_2_0x80000b7c0301143F,
+ DPHY01_DDRPHY_DP18_DATA_BIT_DISABLE0_RP3_P0_3_0x80000f7c0301143F,
+ DPHY01_DDRPHY_DP18_DATA_BIT_DISABLE0_RP3_P0_4_0x8000137c0301143F}
+ },
+ /* port 1 */
+ {
+ // primary rank pair 0
+ {DPHY01_DDRPHY_DP18_DATA_BIT_DISABLE0_RP0_P1_0_0x8001007c0301143F,
+ DPHY01_DDRPHY_DP18_DATA_BIT_DISABLE0_RP0_P1_1_0x8001047c0301143F,
+ DPHY01_DDRPHY_DP18_DATA_BIT_DISABLE0_RP0_P1_2_0x8001087c0301143F,
+ DPHY01_DDRPHY_DP18_DATA_BIT_DISABLE0_RP0_P1_3_0x80010c7c0301143F,
+ DPHY01_DDRPHY_DP18_DATA_BIT_DISABLE0_RP0_P1_4_0x8001107c0301143F},
+ // primary rank pair 1
+ {DPHY01_DDRPHY_DP18_DATA_BIT_DISABLE0_RP1_P1_0_0x8001017c0301143F,
+ DPHY01_DDRPHY_DP18_DATA_BIT_DISABLE0_RP1_P1_1_0x8001057c0301143F,
+ DPHY01_DDRPHY_DP18_DATA_BIT_DISABLE0_RP1_P1_2_0x8001097c0301143F,
+ DPHY01_DDRPHY_DP18_DATA_BIT_DISABLE0_RP1_P1_3_0x80010d7c0301143F,
+ DPHY01_DDRPHY_DP18_DATA_BIT_DISABLE0_RP1_P1_4_0x8001117c0301143F},
+ // primary rank pair 2
+ {DPHY01_DDRPHY_DP18_DATA_BIT_DISABLE0_RP2_P1_0_0x8001027c0301143F,
+ DPHY01_DDRPHY_DP18_DATA_BIT_DISABLE0_RP2_P1_1_0x8001067c0301143F,
+ DPHY01_DDRPHY_DP18_DATA_BIT_DISABLE0_RP2_P1_2_0x80010a7c0301143F,
+ DPHY01_DDRPHY_DP18_DATA_BIT_DISABLE0_RP2_P1_3_0x80010e7c0301143F,
+ DPHY01_DDRPHY_DP18_DATA_BIT_DISABLE0_RP2_P1_4_0x8001127c0301143F},
+ // primary rank pair 3
+ {DPHY01_DDRPHY_DP18_DATA_BIT_DISABLE0_RP3_P1_0_0x8001037c0301143F,
+ DPHY01_DDRPHY_DP18_DATA_BIT_DISABLE0_RP3_P1_1_0x8001077c0301143F,
+ DPHY01_DDRPHY_DP18_DATA_BIT_DISABLE0_RP3_P1_2_0x80010b7c0301143F,
+ DPHY01_DDRPHY_DP18_DATA_BIT_DISABLE0_RP3_P1_3_0x80010f7c0301143F,
+ DPHY01_DDRPHY_DP18_DATA_BIT_DISABLE0_RP3_P1_4_0x8001137c0301143F}
+ }};
+ const uint8_t rg_invalid[] = {
+ ENUM_ATTR_EFF_PRIMARY_RANK_GROUP0_INVALID,
+ ENUM_ATTR_EFF_PRIMARY_RANK_GROUP1_INVALID,
+ ENUM_ATTR_EFF_PRIMARY_RANK_GROUP2_INVALID,
+ ENUM_ATTR_EFF_PRIMARY_RANK_GROUP3_INVALID,
+ };
+
+ ReturnCode rc;
+ ecmdDataBufferBase data_buffer(64);
+ ecmdDataBufferBase db_reg(BITS_PER_PORT);
+ uint32_t l_ecmdRc = ECMD_DBUF_SUCCESS;
+ uint8_t prg[MAX_PRI_RANKS][MAX_PORTS]; // primary rank group values
+
+ FAPI_INF("Running set bad bits FN:mss_set_bbm_regs,"
+ " input Target: %s", mba_target.toEcmdString());
+
+ std::vector<Target> mba_dimms;
+ fapiGetAssociatedDimms(mba_target, mba_dimms); // functional dimms
+
+ FAPI_INF("***-------- Found %i functional DIMMS --------***",
+ mba_dimms.size());
+
+ // ATTR_EFF_PRIMARY_RANK_GROUP0[port], GROUP1[port], GROUP2[port], GROUP3[port]
+ rc=FAPI_ATTR_GET(ATTR_EFF_PRIMARY_RANK_GROUP0, &mba_target, prg[0]);
+ if(rc) return rc;
+ rc=FAPI_ATTR_GET(ATTR_EFF_PRIMARY_RANK_GROUP1, &mba_target, prg[1]);
+ if(rc) return rc;
+ rc=FAPI_ATTR_GET(ATTR_EFF_PRIMARY_RANK_GROUP2, &mba_target, prg[2]);
+ if(rc) return rc;
+ rc=FAPI_ATTR_GET(ATTR_EFF_PRIMARY_RANK_GROUP3, &mba_target, prg[3]);
+ if(rc) return rc;
+
+ l_ecmdRc = data_buffer.flushTo0();
+ if (l_ecmdRc != ECMD_DBUF_SUCCESS)
+ {
+ FAPI_ERR("Error from ecmdDataBuffer flushTo0() "
+ "- rc 0x%.8X", l_ecmdRc);
+
+ rc.setEcmdError(l_ecmdRc);
+ return rc;
+ }
+ for (uint8_t port = 0; port < MAX_PORTS; port++ ) // [0:1]
+ {
+ // loop through primary ranks [0:3]
+ for (uint8_t prank = 0; prank < MAX_PRI_RANKS; prank++ )
+ {
+ uint8_t dimm = prg[prank][port] >> 2;
+ uint8_t rank = prg[prank][port] & 0x03;
+ uint16_t l_data = 0;
+
+ if (prg[prank][port] == rg_invalid[prank]) // invalid rank
+ {
+ FAPI_INF("Primary rank group %i is INVALID, continuing...",
+ prank);
+ continue;
+ }
+
+ rc = getC4dq2reg(mba_target, port, dimm, rank, db_reg);
+ if (rc)
+ {
+ FAPI_ERR("Error from getting register bitmap port=%i: "
+ "dimm=%i, rank=%i rc=%i", port, dimm, rank,
+ static_cast<uint32_t>(rc));
+ return rc;
+ }
+ // quick test to move on to next rank if no bits need to be set
+ if (db_reg.getNumBitsSet(0, BITS_PER_PORT) == 0)
+ {
+ FAPI_INF("No bad bits found for p%i:d%i:r%i(rg%i):cs%i",
+ port, dimm, rank, prank, prg[prank][port]);
+ continue;
+ }
+
+ for ( uint8_t i=0; i < DP18_INSTANCES; i++ ) // dp18 [0:4]
+ {
+ // clear bits 48:63
+ l_ecmdRc = data_buffer.clearBit(48, BITS_PER_REG);
+ l_data = db_reg.getHalfWord(i);
+
+ // check or not to check(always set register)?
+ if (l_data == 0)
+ {
+ FAPI_INF("DP18_%i has no bad bits set, continuing...", i);
+ continue;
+ }
+
+ l_ecmdRc |= data_buffer.setHalfWord(3, l_data);
+ if (l_ecmdRc != ECMD_DBUF_SUCCESS)
+ {
+ FAPI_ERR("Error from ecmdDataBuffer setHalfWord() "
+ "- rc 0x%.8X", l_ecmdRc);
+
+ rc.setEcmdError(l_ecmdRc);
+ return rc;
+ }
+ FAPI_INF("+++ Setting Bad Bit Mask p%i: DIMM%i PRG%i "
+ "Rank%i \tdp18_%i addr=0x%llx, data=0x%04X", port,
+ dimm, prank, prg[prank][port], i,
+ disable_reg[port][prank][i], l_data);
+
+ rc = fapiPutScom(mba_target, disable_reg[port][prank][i],
+ data_buffer);
+ if (rc)
+ {
+ FAPI_ERR("Error from fapiPutScom writing disable reg");
+ return rc;
+ }
+ } // end DP18 instance loop
+ } // end primary rank loop
+ } // end port loop
+ return rc;
+} // end mss_set_bbm_regs
+
+
+
+fapi::ReturnCode mss_get_bbm_regs (const fapi::Target & mba_target)
+{
+// Registers to Flash.
+
+ const uint64_t disable_reg[MAX_PORTS][MAX_PRI_RANKS][DP18_INSTANCES] = {
+ /* port 0 */
+ { // primary rank pair 0
+ {DPHY01_DDRPHY_DP18_DATA_BIT_DISABLE0_RP0_P0_0_0x8000007c0301143F,
+ DPHY01_DDRPHY_DP18_DATA_BIT_DISABLE0_RP0_P0_1_0x8000047c0301143F,
+ DPHY01_DDRPHY_DP18_DATA_BIT_DISABLE0_RP0_P0_2_0x8000087c0301143F,
+ DPHY01_DDRPHY_DP18_DATA_BIT_DISABLE0_RP0_P0_3_0x80000c7c0301143F,
+ DPHY01_DDRPHY_DP18_DATA_BIT_DISABLE0_RP0_P0_4_0x8000107c0301143F},
+ // primary rank pair 1
+ {DPHY01_DDRPHY_DP18_DATA_BIT_DISABLE0_RP1_P0_0_0x8000017c0301143F,
+ DPHY01_DDRPHY_DP18_DATA_BIT_DISABLE0_RP1_P0_1_0x8000057c0301143F,
+ DPHY01_DDRPHY_DP18_DATA_BIT_DISABLE0_RP1_P0_2_0x8000097c0301143F,
+ DPHY01_DDRPHY_DP18_DATA_BIT_DISABLE0_RP1_P0_3_0x80000d7c0301143F,
+ DPHY01_DDRPHY_DP18_DATA_BIT_DISABLE0_RP1_P0_4_0x8000117c0301143F},
+ // primary rank pair 2
+ {DPHY01_DDRPHY_DP18_DATA_BIT_DISABLE0_RP2_P0_0_0x8000027c0301143F,
+ DPHY01_DDRPHY_DP18_DATA_BIT_DISABLE0_RP2_P0_1_0x8000067c0301143F,
+ DPHY01_DDRPHY_DP18_DATA_BIT_DISABLE0_RP2_P0_2_0x80000a7c0301143F,
+ DPHY01_DDRPHY_DP18_DATA_BIT_DISABLE0_RP2_P0_3_0x80000e7c0301143F,
+ DPHY01_DDRPHY_DP18_DATA_BIT_DISABLE0_RP2_P0_4_0x8000127c0301143F},
+ // primary rank pair 3
+ {DPHY01_DDRPHY_DP18_DATA_BIT_DISABLE0_RP3_P0_0_0x8000037c0301143F,
+ DPHY01_DDRPHY_DP18_DATA_BIT_DISABLE0_RP3_P0_1_0x8000077c0301143F,
+ DPHY01_DDRPHY_DP18_DATA_BIT_DISABLE0_RP3_P0_2_0x80000b7c0301143F,
+ DPHY01_DDRPHY_DP18_DATA_BIT_DISABLE0_RP3_P0_3_0x80000f7c0301143F,
+ DPHY01_DDRPHY_DP18_DATA_BIT_DISABLE0_RP3_P0_4_0x8000137c0301143F}
+ },
+ /* port 1 */
+ {
+ // primary rank pair 0
+ {DPHY01_DDRPHY_DP18_DATA_BIT_DISABLE0_RP0_P1_0_0x8001007c0301143F,
+ DPHY01_DDRPHY_DP18_DATA_BIT_DISABLE0_RP0_P1_1_0x8001047c0301143F,
+ DPHY01_DDRPHY_DP18_DATA_BIT_DISABLE0_RP0_P1_2_0x8001087c0301143F,
+ DPHY01_DDRPHY_DP18_DATA_BIT_DISABLE0_RP0_P1_3_0x80010c7c0301143F,
+ DPHY01_DDRPHY_DP18_DATA_BIT_DISABLE0_RP0_P1_4_0x8001107c0301143F},
+ // primary rank pair 1
+ {DPHY01_DDRPHY_DP18_DATA_BIT_DISABLE0_RP1_P1_0_0x8001017c0301143F,
+ DPHY01_DDRPHY_DP18_DATA_BIT_DISABLE0_RP1_P1_1_0x8001057c0301143F,
+ DPHY01_DDRPHY_DP18_DATA_BIT_DISABLE0_RP1_P1_2_0x8001097c0301143F,
+ DPHY01_DDRPHY_DP18_DATA_BIT_DISABLE0_RP1_P1_3_0x80010d7c0301143F,
+ DPHY01_DDRPHY_DP18_DATA_BIT_DISABLE0_RP1_P1_4_0x8001117c0301143F},
+ // primary rank pair 2
+ {DPHY01_DDRPHY_DP18_DATA_BIT_DISABLE0_RP2_P1_0_0x8001027c0301143F,
+ DPHY01_DDRPHY_DP18_DATA_BIT_DISABLE0_RP2_P1_1_0x8001067c0301143F,
+ DPHY01_DDRPHY_DP18_DATA_BIT_DISABLE0_RP2_P1_2_0x80010a7c0301143F,
+ DPHY01_DDRPHY_DP18_DATA_BIT_DISABLE0_RP2_P1_3_0x80010e7c0301143F,
+ DPHY01_DDRPHY_DP18_DATA_BIT_DISABLE0_RP2_P1_4_0x8001127c0301143F},
+ // primary rank pair 3
+ {DPHY01_DDRPHY_DP18_DATA_BIT_DISABLE0_RP3_P1_0_0x8001037c0301143F,
+ DPHY01_DDRPHY_DP18_DATA_BIT_DISABLE0_RP3_P1_1_0x8001077c0301143F,
+ DPHY01_DDRPHY_DP18_DATA_BIT_DISABLE0_RP3_P1_2_0x80010b7c0301143F,
+ DPHY01_DDRPHY_DP18_DATA_BIT_DISABLE0_RP3_P1_3_0x80010f7c0301143F,
+ DPHY01_DDRPHY_DP18_DATA_BIT_DISABLE0_RP3_P1_4_0x8001137c0301143F}
+
+ }};
+
+
+
+ const uint8_t rg_invalid[] = {
+ ENUM_ATTR_EFF_PRIMARY_RANK_GROUP0_INVALID,
+ ENUM_ATTR_EFF_PRIMARY_RANK_GROUP1_INVALID,
+ ENUM_ATTR_EFF_PRIMARY_RANK_GROUP2_INVALID,
+ ENUM_ATTR_EFF_PRIMARY_RANK_GROUP3_INVALID,
+ };
+
+ ReturnCode rc;
+ ecmdDataBufferBase data_buffer(64);
+ ecmdDataBufferBase db_reg(BITS_PER_PORT);
+ uint32_t l_ecmdRc = ECMD_DBUF_SUCCESS;
+ uint8_t prg[MAX_PRI_RANKS][MAX_PORTS]; // primary rank group values
+
+ FAPI_INF("Running set bad bits FN:mss_set_bbm_regs \n"
+ " input Target: %s", mba_target.toEcmdString());
+
+ std::vector<Target> mba_dimms;
+ fapiGetAssociatedDimms(mba_target, mba_dimms); // functional dimms
+
+ FAPI_INF("***-------- Found %i functional DIMMS --------***",
+ mba_dimms.size());
+
+ // 4 dimms per MBA, 2 per port
+
+ // ATTR_EFF_PRIMARY_RANK_GROUP0[port], GROUP1[port], GROUP2[port], GROUP3[port]
+ rc=FAPI_ATTR_GET(ATTR_EFF_PRIMARY_RANK_GROUP0, &mba_target, prg[0]);
+ if(rc) return rc;
+ rc=FAPI_ATTR_GET(ATTR_EFF_PRIMARY_RANK_GROUP1, &mba_target, prg[1]);
+ if(rc) return rc;
+ rc=FAPI_ATTR_GET(ATTR_EFF_PRIMARY_RANK_GROUP2, &mba_target, prg[2]);
+ if(rc) return rc;
+ rc=FAPI_ATTR_GET(ATTR_EFF_PRIMARY_RANK_GROUP3, &mba_target, prg[3]);
+ if(rc) return rc;
+
+ l_ecmdRc = data_buffer.flushTo0();
+ if (l_ecmdRc != ECMD_DBUF_SUCCESS)
+ {
+ FAPI_ERR("Error from ecmdDataBuffer flushTo0() "
+ "- rc 0x%.8X", l_ecmdRc);
+
+ rc.setEcmdError(l_ecmdRc);
+ return rc;
+ }
+ for (uint8_t port = 0; port < MAX_PORTS; port++ ) // [0:1]
+ {
+ // loop through primary ranks [0:3]
+ for (uint8_t prank = 0; prank < MAX_PRI_RANKS; prank++ )
+ {
+ uint8_t dimm = prg[prank][port] >> 2;
+ uint8_t rank = prg[prank][port] & 0x03;
+ uint16_t l_data = 0;
+
+ if (prg[prank][port] == rg_invalid[prank]) // invalid rank
+ {
+ FAPI_INF("Primary rank group %i is INVALID, continuing...",
+ prank);
+ continue;
+ }
+
+ for ( uint8_t i=0; i < DP18_INSTANCES; i++ ) // dp18 [0:4]
+ {
+
+ // clear bits 48:63
+ l_ecmdRc = data_buffer.clearBit(48, BITS_PER_REG);
+
+ rc = fapiGetScom(mba_target, disable_reg[port][prank][i],
+ data_buffer);
+ if (rc)
+ {
+ FAPI_ERR("Error from fapiPutScom writing disable reg");
+ return rc;
+ }
+
+ l_data = data_buffer.getHalfWord(3);
+ if (l_ecmdRc != ECMD_DBUF_SUCCESS)
+ {
+ FAPI_ERR("Error from ecmdDataBuffer setHalfWord() "
+ "- rc 0x%.8X", l_ecmdRc);
+
+ rc.setEcmdError(l_ecmdRc);
+ return rc;
+ }
+
+ l_ecmdRc |= db_reg.setHalfWord(i, l_data);
+
+ FAPI_INF("+++ Setting Bad Bit Mask p%i: DIMM%i PRG%i "
+ "Rank%i \tdp18_%i addr=0x%llx, data=0x%04X", port,
+ dimm, prank, prg[prank][port], i,
+ disable_reg[port][prank][i], l_data);
+
+
+ } // end DP18 instance loop
+
+
+ rc = setC4dq2reg(mba_target, port, dimm, rank, db_reg);
+ if (rc)
+ {
+ FAPI_ERR("Error from setting register bitmap p%i: "
+ "dimm=%i, rank=%i rc=%i", port, dimm, rank,
+ static_cast<uint32_t>(rc));
+ return rc;
+ }
+
+ } // end primary rank loop
+ } // end port loop
+ return rc;
+} // end mss_set_bbm_regs
+
+// output reg = in phy based order
+ReturnCode getC4dq2reg(const Target & i_mba, const uint8_t i_port, const uint8_t i_dimm, const uint8_t i_rank, ecmdDataBufferBase &o_reg)
+{
+ // [port][bits per port]
+ const uint8_t lookup[4][BITS_PER_PORT] = {
+ // port 0
+ {65,66,67,64, 70,69,68,71, 21,20,23,22, 18,16,19,17, // DP18 block 0
+ 61,63,60,62, 57,58,59,56, 73,74,75,72, 78,77,79,76, // ... block 1
+ 7, 5, 4, 6, 0, 2, 1, 3, 12,13,15,14, 10, 8,11, 9, // ... block 2
+ 47,44,46,45, 43,42,41,40, 31,29,30,28, 26,24,27,25, // ... block 3
+ 55,53,54,52, 50,48,49,51, 33,34,35,32, 36,37,38,39}, // ... block 4
+ // port 1
+ {17,16,18,19, 20,21,22,23, 2, 0, 3, 1, 7, 4, 5, 6,
+ 70,71,69,68, 66,64,67,65, 27,24,26,25, 29,30,31,28,
+ 37,36,38,39, 35,32,34,33, 77,76,79,78, 73,75,72,74,
+ 40,42,41,43, 45,44,46,47, 9,11, 8,10, 12,13,14,15,
+ 48,51,49,50, 52,53,54,55, 61,63,62,60, 56,58,59,57},
+ // port 2
+ {22,23,20,21, 19,16,17,18, 26,25,24,27, 29,28,31,30,
+ 67,64,65,66, 71,70,69,68, 7, 5, 6, 4, 2, 0, 3, 1,
+ 45,44,47,46, 42,43,41,40, 39,38,37,36, 33,34,35,32,
+ 48,50,49,51, 54,52,53,55, 15,13,12,14, 9, 8,10,11,
+ 61,60,62,63, 59,56,58,57, 74,72,73,75, 76,79,78,77},
+ // port 3
+ {25,26,27,24, 28,31,29,30, 17,19,16,18, 20,21,23,22,
+ 64,67,66,65, 71,69,68,70, 75,74,72,73, 76,77,79,78,
+ 4, 5, 7, 6, 0, 1, 2, 3, 12,13,14,15, 8, 9,11,10,
+ 47,45,46,44, 43,41,42,40, 35,32,33,34, 39,37,36,38,
+ 55,52,53,54, 51,48,49,50, 60,62,61,63, 57,59,56,58}
+ };
+
+ uint8_t l_bbm[TOTAL_BYTES] = {0}; // bad bitmap from dimmGetBadDqBitmap
+ ecmdDataBufferBase c4dqbmp(BITS_PER_PORT); // databuffer of C4 dq bitmap
+ ReturnCode rc;
+ uint8_t l_port = i_port; // port # relative to Centaur
+ uint8_t mba_pos = 0;
+ uint32_t ecmdrc = ECMD_DBUF_SUCCESS;
+
+ ecmdrc = o_reg.flushTo0(); // clear output databuffer
+ if (ecmdrc != ECMD_DBUF_SUCCESS)
+ {
+ FAPI_ERR("Error from ecmdDataBuffer flushTo0() "
+ "- rc 0x%.8X", ecmdrc);
+
+ rc.setEcmdError(ecmdrc);
+ return rc;
+ }
+ rc=FAPI_ATTR_GET(ATTR_CHIP_UNIT_POS, &i_mba, mba_pos);
+ if (rc)
+ {
+ FAPI_ERR("Error getting ATTR_CHIP_UNIT_POS for MBA");
+ return (rc);
+ }
+
+ // get Centaur dq bitmap (C4 signal) order=[0:79], array of bytes
+ rc = dimmGetBadDqBitmap(i_mba, i_port, i_dimm, i_rank, l_bbm);
+ if (rc)
+ {
+ FAPI_ERR("Error from dimmGetBadDqBitmap on MBA%ip%i: "
+ "dimm=%i, rank=%i rc=%i", mba_pos, i_port, i_dimm, i_rank,
+ static_cast<uint32_t>(rc));
+ return rc;
+ }
+
+ // create databuffer from C4 dq bitmap array
+ ecmdrc = c4dqbmp.insertFromRight(l_bbm, 0, BITS_PER_PORT);
+ if (ecmdrc != ECMD_DBUF_SUCCESS)
+ {
+ FAPI_ERR("Error from ecmdDataBuffer insertFromRight() "
+ "- rc 0x%.8X", ecmdrc);
+
+ rc.setEcmdError(ecmdrc);
+ return rc;
+ }
+
+ // quick check if there no bits on, we're done
+ if (c4dqbmp.getNumBitsSet(0, BITS_PER_PORT) == 0)
+ {
+ return rc;
+ }
+ l_port = i_port + (mba_pos * MAX_PORTS); // relative to Centaur
+
+ for (uint8_t i=0; i < BITS_PER_PORT; i++)
+ {
+ if (c4dqbmp.isBitSet(lookup[l_port][i]))
+ {
+ o_reg.setBit(i);
+ FAPI_DBG("set bad bit C4_dq=%i,\t dp18_%i_lane%i\t (bit %i)",
+ lookup[l_port][i], (i / 16), (i % 16), i);
+ }
+ }
+
+ return rc;
+}
+
+ReturnCode setC4dq2reg(const Target &i_mba, const uint8_t i_port, const uint8_t i_dimm, const uint8_t i_rank, ecmdDataBufferBase &o_reg)
+{
+
+ const uint8_t lookup[4][BITS_PER_PORT] = {
+ // port 0
+ {65,66,67,64,70,69,68,71,21,20,23,22,18,16,19,17, // DP18 block 0
+ 61,63,60,62,57,58,59,56,73,74,75,72,78,77,79,76, // ... block 1
+ 7, 5, 4, 6, 0, 2, 1, 3,12,13,15,14,10, 8,11, 9, // ... block 2
+ 47,44,46,45,43,42,41,40,31,29,30,28,26,24,27,25, // ... block 3
+ 55,53,54,52,50,48,49,51,33,34,35,32,36,37,38,39}, // ... block 4
+ // port 1
+ {17,16,18,19,20,21,22,23, 2, 0, 3, 1, 7, 4, 5, 6,
+ 70,71,69,68,66,64,67,65,27,24,26,25,29,30,31,28,
+ 37,36,38,39,35,32,34,33,77,76,79,78,73,75,72,74,
+ 40,42,41,43,45,44,46,47, 9,11, 8,10,12,13,14,15,
+ 48,51,49,50,52,53,54,55,61,63,62,60,56,58,59,57},
+ // port 2
+ {22,23,20,21,19,16,17,18,26,25,24,27,29,28,31,30,
+ 67,64,65,66,71,70,69,68, 7, 5, 6, 4, 2, 0, 3, 1,
+ 45,44,47,46,42,43,41,40,39,38,37,36,33,34,35,32,
+ 48,50,49,51,54,52,53,55,15,13,12,14, 9, 8,10,11,
+ 61,60,62,63,59,56,58,57,74,72,73,75,76,79,78,77},
+ // port 3
+ {25,26,27,24,28,31,29,30,17,19,16,18,20,21,23,22,
+ 64,67,66,65,71,69,68,70,75,74,72,73,76,77,79,78,
+ 4, 5, 7, 6, 0, 1, 2, 3,12,13,14,15, 8, 9,11,10,
+ 47,45,46,44,43,41,42,40,35,32,33,34,39,37,36,38,
+ 55,52,53,54,51,48,49,50,60,62,61,63,57,59,56,58}
+ };
+ uint8_t l_bbm [TOTAL_BYTES] = {0};
+ ecmdDataBufferBase c4dqbmp(BITS_PER_PORT);
+ ReturnCode rc;
+ uint8_t l_port = i_port;
+ uint8_t mba_pos = 0;
+ uint32_t ecmdrc = ECMD_DBUF_SUCCESS;
+
+ // clear output databuffer
+ ecmdrc = c4dqbmp.flushTo0();
+ if (ecmdrc != ECMD_DBUF_SUCCESS)
+ {
+ FAPI_ERR("Error from ecmdDataBuffer flushTo0() "
+ "- rc 0x%.8X", ecmdrc);
+
+ rc.setEcmdError(ecmdrc);
+ return rc;
+ }
+
+ // Set Port info
+ rc=FAPI_ATTR_GET(ATTR_CHIP_UNIT_POS, &i_mba, mba_pos);
+ if (rc)
+ {
+ FAPI_ERR("Error getting ATTR_CHIP_UNIT_POS for MBA");
+ return (rc);
+ }
+
+ l_port = i_port + (mba_pos * MAX_PORTS);
+
+ // translate c4 from input
+ for (uint8_t i=0; i < BITS_PER_PORT; i++)
+ {
+ if (o_reg.isBitSet(i))
+ {
+ c4dqbmp.setBit(lookup[l_port][i]);
+ }
+ }
+
+ // create array from databuffer
+ for (uint8_t b=0; b < TOTAL_BYTES; b++)
+ {
+ l_bbm[b] = c4dqbmp.getByte(b);
+ }
+
+ // set Centaur dq bitmap (C4 signal) order=[0:79], array of bytes
+ rc = dimmSetBadDqBitmap(i_mba, i_port, i_dimm, i_rank, l_bbm);
+ if (rc)
+ {
+ FAPI_ERR("Error from dimmSetBadDqBitmap on MBA%ip%i: "
+ "dimm=%i, rank=%i rc=%i", mba_pos, i_port, i_dimm, i_rank,
+ static_cast<uint32_t>(rc));
+ return rc;
+ }
+
+ return rc;
}
} //end extern C
diff --git a/src/usr/hwpf/hwp/dram_training/mss_funcs.C b/src/usr/hwpf/hwp/dram_training/mss_funcs.C
index 5395b5cd8..4aa0fa551 100644
--- a/src/usr/hwpf/hwp/dram_training/mss_funcs.C
+++ b/src/usr/hwpf/hwp/dram_training/mss_funcs.C
@@ -1,27 +1,26 @@
-/* IBM_PROLOG_BEGIN_TAG
- * This is an automatically generated prolog.
- *
- * $Source: src/usr/hwpf/hwp/dram_training/mss_funcs.C $
- *
- * IBM CONFIDENTIAL
- *
- * COPYRIGHT International Business Machines Corp. 2012
- *
- * p1
- *
- * Object Code Only (OCO) source materials
- * Licensed Internal Code Source Materials
- * IBM HostBoot Licensed Internal Code
- *
- * The source code for this program is not published or other-
- * wise divested of its trade secrets, irrespective of what has
- * been deposited with the U.S. Copyright Office.
- *
- * Origin: 30
- *
- * IBM_PROLOG_END_TAG
- */
-// $Id: mss_funcs.C,v 1.28 2012/07/17 13:24:16 bellows Exp $
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/hwpf/hwp/dram_training/mss_funcs.C $ */
+/* */
+/* IBM CONFIDENTIAL */
+/* */
+/* COPYRIGHT International Business Machines Corp. 2012 */
+/* */
+/* p1 */
+/* */
+/* Object Code Only (OCO) source materials */
+/* Licensed Internal Code Source Materials */
+/* IBM HostBoot Licensed Internal Code */
+/* */
+/* The source code for this program is not published or otherwise */
+/* divested of its trade secrets, irrespective of what has been */
+/* deposited with the U.S. Copyright Office. */
+/* */
+/* Origin: 30 */
+/* */
+/* IBM_PROLOG_END_TAG */
+// $Id: mss_funcs.C,v 1.29 2012/11/19 21:18:40 jsabrow Exp $
/* File mss_funcs.C created by SLOAT JACOB D. (JAKE),2D3970 on Fri Apr 22 2011. */
//------------------------------------------------------------------------------
@@ -44,6 +43,7 @@
//------------------------------------------------------------------------------
// Version:| Author: | Date: | Comment:
//---------|----------|---------|-----------------------------------------------
+// 1.29 | jsabrow | 11/19/12| added CCS data loader: mss_ccs_load_data_pattern
// 1.28 | bellows | 07/16/12|added in Id tag
// 1.27 | divyakum | 3/22/12 | Fixed warnings from mss_execute_zq_cal function
// 1.26 | divyakum | 3/22/12 | Fixed mss_execute_zq_cal function variable name mismatch
@@ -228,7 +228,7 @@ ReturnCode mss_ccs_inst_arry_1(
rc_num = rc_num | goto_inst.insertFromRight(io_instruction_number + 1, 0, 5);
- //Setting up a CSS Instruction Array Type 1
+ //Setting up a CCS Instruction Array Type 1
rc_num = rc_num | data_buffer.insert( i_num_idles, 0, 16, 0);
rc_num = rc_num | data_buffer.insert( i_num_repeat, 16, 16, 0);
rc_num = rc_num | data_buffer.insert( i_data, 32, 20, 0);
@@ -250,6 +250,82 @@ ReturnCode mss_ccs_inst_arry_1(
return rc;
}
+//--------------
+ReturnCode mss_ccs_load_data_pattern(
+ Target& i_target,
+ uint32_t io_instruction_number,
+ mss_ccs_data_pattern data_pattern)
+{
+ //Example Use:
+ //
+ ReturnCode rc;
+
+ if (data_pattern == MSS_CCS_DATA_PATTERN_00)
+ {
+ rc = mss_ccs_load_data_pattern(i_target, io_instruction_number, 0x00000000);
+ }
+ else if (data_pattern == MSS_CCS_DATA_PATTERN_0F)
+ {
+ rc = mss_ccs_load_data_pattern(i_target, io_instruction_number, 0x00055555);
+ }
+ else if (data_pattern == MSS_CCS_DATA_PATTERN_F0)
+ {
+ rc = mss_ccs_load_data_pattern(i_target, io_instruction_number, 0x000aaaaa);
+ }
+ else if (data_pattern == MSS_CCS_DATA_PATTERN_FF)
+ {
+ rc = mss_ccs_load_data_pattern(i_target, io_instruction_number, 0x000fffff);
+ }
+
+ return rc;
+}
+
+
+ReturnCode mss_ccs_load_data_pattern(
+ Target& i_target,
+ uint32_t io_instruction_number,
+ uint32_t data_pattern)
+{
+ //Example Use:
+ //
+ ReturnCode rc;
+ ReturnCode rc_buff;
+ uint32_t rc_num = 0;
+ uint32_t reg_address = 0;
+
+ if (io_instruction_number > 31)
+ {
+ FAPI_INF("mss_ccs_load_data_pattern: CCS Instruction Array index out of bounds");
+ }
+ else
+ {
+ reg_address = io_instruction_number + CCS_INST_ARRY1_AB_REG0_0x03010635;
+ ecmdDataBufferBase data_buffer(64);
+
+ //read current array1 reg
+ rc = fapiGetScom(i_target, reg_address, data_buffer);
+ if(rc) return rc;
+
+ //modify data bits for specified pattern
+ rc_num = rc_num | data_buffer.insertFromRight(data_pattern, 32, 20);
+ if (rc_num)
+ {
+ FAPI_ERR( "mss_ccs_load_data_pattern: Error setting up buffers");
+ rc_buff.setEcmdError(rc_num);
+ return rc_buff;
+ }
+
+ //write array1 back out
+ rc = fapiPutScom(i_target, reg_address, data_buffer);
+ if(rc) return rc;
+ }
+
+ return rc;
+}
+//--------------
+
+
+
ReturnCode mss_ccs_mode(
Target& i_target,
ecmdDataBufferBase i_stop_on_err,
diff --git a/src/usr/hwpf/hwp/dram_training/mss_funcs.H b/src/usr/hwpf/hwp/dram_training/mss_funcs.H
index d87c4d9b8..685ed1ef1 100644
--- a/src/usr/hwpf/hwp/dram_training/mss_funcs.H
+++ b/src/usr/hwpf/hwp/dram_training/mss_funcs.H
@@ -1,27 +1,26 @@
-/* IBM_PROLOG_BEGIN_TAG
- * This is an automatically generated prolog.
- *
- * $Source: src/usr/hwpf/hwp/dram_training/mss_funcs.H $
- *
- * IBM CONFIDENTIAL
- *
- * COPYRIGHT International Business Machines Corp. 2012
- *
- * p1
- *
- * Object Code Only (OCO) source materials
- * Licensed Internal Code Source Materials
- * IBM HostBoot Licensed Internal Code
- *
- * The source code for this program is not published or other-
- * wise divested of its trade secrets, irrespective of what has
- * been deposited with the U.S. Copyright Office.
- *
- * Origin: 30
- *
- * IBM_PROLOG_END_TAG
- */
-// $Id: mss_funcs.H,v 1.12 2012/07/17 13:22:58 bellows Exp $
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/hwpf/hwp/dram_training/mss_funcs.H $ */
+/* */
+/* IBM CONFIDENTIAL */
+/* */
+/* COPYRIGHT International Business Machines Corp. 2012 */
+/* */
+/* p1 */
+/* */
+/* Object Code Only (OCO) source materials */
+/* Licensed Internal Code Source Materials */
+/* IBM HostBoot Licensed Internal Code */
+/* */
+/* The source code for this program is not published or otherwise */
+/* divested of its trade secrets, irrespective of what has been */
+/* deposited with the U.S. Copyright Office. */
+/* */
+/* Origin: 30 */
+/* */
+/* IBM_PROLOG_END_TAG */
+// $Id: mss_funcs.H,v 1.13 2012/11/19 21:18:41 jsabrow Exp $
/* File mss_funcs.H created by SLOAT JACOB D. (JAKE),2D3970 on Fri Apr 22 2011. */
//------------------------------------------------------------------------------
@@ -44,6 +43,7 @@
//------------------------------------------------------------------------------
// Version:| Author: | Date: | Comment:
//---------|----------|---------|-----------------------------------------------
+// 1.13 | jsabrow | 11/19/12| added CCS data loader: mss_ccs_load_data_pattern
// 1.12 | 07/16/12 | bellows | added in Id tag
// 1.11 | 3/21/12 | divyakum| Added mss_execute_zq_cal function
// 1.10 | 2/14/12 | jdsloat | Comment section filled in, elimated unnecessary constant, added enums
@@ -90,6 +90,14 @@ enum mss_ccs_status_query_result
};
+enum mss_ccs_data_pattern
+{
+ MSS_CCS_DATA_PATTERN_00 = 1,
+ MSS_CCS_DATA_PATTERN_0F = 2,
+ MSS_CCS_DATA_PATTERN_F0 = 3,
+ MSS_CCS_DATA_PATTERN_FF = 4
+};
+
const bool MSS_CCS_START = 0;
const bool MSS_CCS_STOP = 1;
@@ -133,6 +141,27 @@ fapi::ReturnCode mss_ccs_inst_arry_1( fapi::Target& i_target,
ecmdDataBufferBase i_ddr_cal_enable,
ecmdDataBufferBase i_ccs_end);
+
+//---------------------------------------------------------------
+// mss_ccs_load_data_pattern
+// load predefined pattern (enum) into specified array1 index
+// Target = centaur.mba
+//---------------------------------------------------------------
+fapi::ReturnCode mss_ccs_load_data_pattern( fapi::Target& i_target,
+ uint32_t io_instruction_number,
+ mss_ccs_data_pattern data_pattern);
+
+
+//---------------------------------------------------------------
+// mss_ccs_load_data_pattern
+// load specified pattern (20 bits) into specified array1 index
+// Target = centaur.mba
+//---------------------------------------------------------------
+fapi::ReturnCode mss_ccs_load_data_pattern( fapi::Target& i_target,
+ uint32_t io_instruction_number,
+ uint32_t data_pattern);
+
+
//-----------------------------------------
// mss_ccs_status_query
// Querying the status of the CCS
@@ -141,6 +170,7 @@ fapi::ReturnCode mss_ccs_inst_arry_1( fapi::Target& i_target,
fapi::ReturnCode mss_ccs_status_query( fapi::Target& i_target,
mss_ccs_status_query_result& io_status);
+
//-----------------------------------------
// mss_ccs_start_stop
// Issuing a start or stop of the CCS
@@ -172,6 +202,7 @@ fapi::ReturnCode mss_ccs_mode( fapi::Target& i_target,
//-----------------------------------------
fapi::ReturnCode mss_ccs_fail_type( fapi::Target& i_target);
+
//-----------------------------------
// mss_execute_ccs_inst_array
// Execute the CCS intruction array
diff --git a/src/usr/hwpf/hwp/dram_training/mss_scominit/mss_scominit.C b/src/usr/hwpf/hwp/dram_training/mss_scominit/mss_scominit.C
index 8f9d6fd8e..b94b5fbdd 100644
--- a/src/usr/hwpf/hwp/dram_training/mss_scominit/mss_scominit.C
+++ b/src/usr/hwpf/hwp/dram_training/mss_scominit/mss_scominit.C
@@ -20,7 +20,7 @@
/* Origin: 30 */
/* */
/* IBM_PROLOG_END_TAG */
-// $Id: mss_scominit.C,v 1.11 2012/08/23 00:11:37 mwuu Exp $
+// $Id: mss_scominit.C,v 1.15 2012/11/12 03:08:50 mwuu Exp $
//------------------------------------------------------------------------------
// *! (C) Copyright International Business Machines Corp. 2011
// *! All Rights Reserved -- Property of IBM
@@ -41,6 +41,11 @@
//------------------------------------------------------------------------------
// Version:| Author: | Date: | Comment:
//---------|----------|---------|-----------------------------------------------
+// 1.15 | menlowuu |11-NOV-12| Removed include of dimmBadDqBitmapFuncs.H>
+// 1.14 | menlowuu |09-NOV-12| Removed mss_set_bbm_regs FN since now handled
+// in draminit_training.
+// 1.13 | menlowuu |26-SEP-12| Changed ORing of port to SCOM address
+// 1.12 | menlowuu |19-SEP-12| Fixed some return codes.
// 1.11 | menlowuu |22-AUG-12| Added return code for mss_set_bbm_regs FN.
// 1.10 | menlowuu |21-AUG-12| Removed running *_mcbist files since it was
// moved into the *_def files.
@@ -68,7 +73,6 @@
// Includes
//----------------------------------------------------------------------
#include <fapi.H>
-#include <dimmBadDqBitmapFuncs.H>
#include <fapiHwpExecInitFile.H>
//----------------------------------------------------------------------
@@ -82,189 +86,6 @@ extern "C" {
using namespace fapi;
//******************************************************************************
-// expects i_target = functional MBA target, MBA position (uint8_t)
-// sets bad bit mask (disable0) registers in the PHY with data from SPD
-//******************************************************************************
-fapi::ReturnCode mss_set_bbm_regs (const fapi::Target & mba_target,
- const uint8_t mba_pos)
-{
- // DPHY01_DDRPHY_DP18_DATA_BIT_DISABLE0_RP0_P0_0_0x8000007C0301143F
- const uint64_t base_addr = 0x8000007C0301143Full;
- const uint8_t rg_invalid[] = {
- ENUM_ATTR_EFF_PRIMARY_RANK_GROUP0_INVALID,
- ENUM_ATTR_EFF_PRIMARY_RANK_GROUP1_INVALID,
- ENUM_ATTR_EFF_PRIMARY_RANK_GROUP2_INVALID,
- ENUM_ATTR_EFF_PRIMARY_RANK_GROUP3_INVALID,
- };
-
- ReturnCode rc;
- uint64_t address = base_addr;
- ecmdDataBufferBase data_buffer(64);
- uint8_t prg[MAX_PRI_RANKS][MAX_PORTS]; // primary rank group values
-
- FAPI_INF("Running set bad bits FN:mss_set_bbm_regs on \nMBA%i,"
- " input Target: %s", mba_pos, mba_target.toEcmdString());
-
- std::vector<Target> mba_dimms;
- fapiGetAssociatedDimms(mba_target, mba_dimms); // functional dimms
-
- FAPI_INF("***-------- Found %i functional DIMMS in MBA%i --------***",
- mba_dimms.size(), mba_pos);
-
- // 4 dimms per MBA, 2 per port
-/*
- RAW SPD 0 1 2 3 4 5 6 7 8 9 A B C D E F
- b0: 0000 0000 0000 0000 0000 0000 0000 0000
- c0: 0000 0000 0000 0000 0000 0000 0000 0000
- d0: 0000 0000 0000 0000 0000 0000 0000 0000
- e0: 0000 0000 0000 0000 0000 0000 0000 00FE
- f0: 0000 0000 0000 0000 0000 0000 0000 00FF
-*/
-// uint8_t bad_dq_data[80] = {
-// /* spd |------------ HEADER -----------------------------------------
-// * byte# |--- magic number ----|-ver-|---- reserved ----|
-// * 0-7 */ 0xBA, 0xDD, 0x44, 0x71, 0x01, 0x00, 0x00, 0x00,
-// /* |------------------- DATA --------------------| ECC |SPARE|
-// * 0 1 2 3 4 5 6 7 8 9
-// * 8-17*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-// /* 18-27*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-// /* 28-37*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-// /* 38-47*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-// /* 48-49*/ 0x00, 0x00,
-// /* 50-59*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-// /* 60-69*/ 0x00, 0x00, 0x00, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-// /* 70-79*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF
-// };
-/*
- for (uint8_t d = 0; d < 8; d++)
- {
- rc=FAPI_ATTR_SET(ATTR_SPD_BAD_DQ_DATA, &mba_dimms[0], bad_dq_data);
- if (rc)
- {
- FAPI_ERR("Error performing FAPI_ATTR_SET on ATTR_SPD_BAD_DQ_DATA");
- }
- }
-*/
- // ATTR_EFF_PRIMARY_RANK_GROUP0[port], GROUP1[port], GROUP2[port], GROUP3[port]
- rc=FAPI_ATTR_GET(ATTR_EFF_PRIMARY_RANK_GROUP0, &mba_target, prg[0]);
- if(rc) return rc;
- rc=FAPI_ATTR_GET(ATTR_EFF_PRIMARY_RANK_GROUP1, &mba_target, prg[1]);
- if(rc) return rc;
- rc=FAPI_ATTR_GET(ATTR_EFF_PRIMARY_RANK_GROUP2, &mba_target, prg[2]);
- if(rc) return rc;
- rc=FAPI_ATTR_GET(ATTR_EFF_PRIMARY_RANK_GROUP3, &mba_target, prg[3]);
- if(rc) return rc;
-
- for (uint8_t port = 0; port < MAX_PORTS; port++ ) // [0:1]
- {
- uint8_t l_bbm[TOTAL_BYTES] = {0}; // bad bits
-
- // port 0 = 0x8000..., port 1 = 0x8001...
- address = address | ((uint64_t)port << 48);
-
- // loop through primary ranks [0:3]
- for (uint8_t prank = 0; prank < MAX_PRI_RANKS; prank++ )
- {
- // 0x800p 0r7C 0301 143F
- uint64_t r_addr = address | ((uint64_t)prank << 40);
- uint8_t dimm = prg[prank][port] >> 2;
- uint8_t rank = prg[prank][port] & 0x03;
- uint8_t bbm_e = 0, bbm_o = 0;
-
-// uint8_t spd_data[10] = {
-// // |-------------------- DATA ----------- --------| ECC |SPARE|
-// //byte 0 1 2 3 4 5 6 7 8 9
-// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-// };
-/*
- rc = dimmSetBadDqBitmap(mba_target, port, dimm, rank, spd_data);
- if (rc)
- {
- FAPI_ERR("Error from dimmSetBadDqBitmap on MBA%ip%i: dimm=%i,
- rank=%i rc=%i", mba_pos, port, dimm, rank,
- static_cast<uint32_t>(rc));
- return rc;
- break;
- }
-*/
- if (prg[prank][port] != rg_invalid[prank]) // valid rank group
- {
- rc = dimmGetBadDqBitmap(mba_target, port, dimm, rank, l_bbm);
- if (rc)
- {
- FAPI_ERR("Error from dimmGetBadDqBitmap on MBA%ip%i: "
- "dimm=%i, rank=%i rc=%i", mba_pos, port, dimm, rank,
- static_cast<uint32_t>(rc));
-
- return rc;
- break;
- }
- }
-
- for ( uint8_t i=0; i < TOTAL_BYTES/2; i++ ) // [0:4] dp18 instances
- {
- uint64_t scom_addr = r_addr | ((uint64_t) i << 42);
- uint64_t l_data = 0;
- uint32_t l_ecmdRc = ECMD_DBUF_SUCCESS;
-
- if (prg[prank][port] == rg_invalid[prank]) // invalid rank
- {
- FAPI_INF("Primary rank group %i is invalid, prepare"
- " broadcast write to all instances", prank);
-
- l_data = 0xFFFF; // invalidate data bits
- // set address to broadcast to all instances in the rank
- scom_addr = scom_addr | 0x00003C0000000000ull;
- }
- else
- { // scom signifies port dimm rank byte
- bbm_e = l_bbm[i*2]; // even byte data
- bbm_o = l_bbm[(i*2)+1]; // odd byte data
- l_data = (bbm_e << 8) | bbm_o;
- if (l_data == 0)
- {
- // no need to set register since bits are good?
- continue; // should double check!
- }
- }
-
- // ecmdDataBufferBase data_buffer(64);
- l_ecmdRc = data_buffer.setDoubleWord(0, l_data);
-
- if (l_ecmdRc != ECMD_DBUF_SUCCESS)
- {
- FAPI_ERR("Error from ecmdDataBuffer setDoubleWord() "
- "- rc 0x%.8X", l_ecmdRc);
-
- rc.setEcmdError(l_ecmdRc);
- break;
- }
-
- FAPI_INF("+++ Setting Bad Bit Mask in MBA%ip%i: PRG%i=%i,"
- " addr=0x%llx, data=0x%04llx", mba_pos, port, prank,
- prg[prank][port], scom_addr, l_data);
-
- rc = fapiPutScom(mba_target, scom_addr, data_buffer);
- if (rc)
- {
- FAPI_ERR("Error from fapiPutScom");
- break;
- }
- if (prg[prank][port] == rg_invalid[prank]) // invalid rank
- {
- FAPI_INF("Disabled primary rank group %i data bits"
- " via broadcast continuing to next rank", prank);
-
- // did broadcast to all instances in rank move to next rank
- break;
- }
- } // end byte loop
- } // end primary rank loop
- } // end port loop
- return rc;
-} // end mss_set_bbm_regs
-
-//******************************************************************************
//
//******************************************************************************
ReturnCode mss_scominit(const Target & i_target) {
@@ -384,18 +205,6 @@ ReturnCode mss_scominit(const Target & i_target) {
FAPI_INF("MBA scom initfile %s passed", mba_if[itr]);
}
} // end for loop, running MBA/PHY initfiles
-
- // set bad bits from SPD into disable bit registers
- rc=mss_set_bbm_regs(vector_targets[i], l_unitPos);
- if (rc)
- {
- FAPI_INF("Error setting disable bit mask registers");
- return (rc);
- }
- else
- {
- FAPI_INF("mss_set_bbm_regs FN passed on MBA%i", l_unitPos);
- }
} // end else, MBA fapiHwpExecInitFile
} // end for loop, valid chip unit pos
} // found functional MBAs
diff --git a/src/usr/hwpf/hwp/dram_training/mss_scominit/mss_scominit.H b/src/usr/hwpf/hwp/dram_training/mss_scominit/mss_scominit.H
index 7319bfd6f..2654a42c2 100644
--- a/src/usr/hwpf/hwp/dram_training/mss_scominit/mss_scominit.H
+++ b/src/usr/hwpf/hwp/dram_training/mss_scominit/mss_scominit.H
@@ -20,7 +20,7 @@
/* Origin: 30 */
/* */
/* IBM_PROLOG_END_TAG */
-// $Id: mss_scominit.H,v 1.6 2012/08/15 23:07:26 mwuu Exp $
+// $Id: mss_scominit.H,v 1.7 2012/11/10 02:53:17 mwuu Exp $
//------------------------------------------------------------------------------
// *! (C) Copyright International Business Machines Corp. 2011
// *! All Rights Reserved -- Property of IBM
@@ -41,6 +41,8 @@
//------------------------------------------------------------------------------
// Version:| Author: | Date: | Comment:
//---------|----------|---------|-----------------------------------------------
+// 1.7 | menlowuu |09-NOV-12| Removed mss_set_bbm_regs since now done in
+// draminit_training
// 1.6 | menlowuu |15-AUG-12| added bad bitmask function
// 1.5 |bellows |16-JUL-12| added in Id tag
// 1.4 | menlowuu |20-JUN-12| added type to the typedef
@@ -64,8 +66,6 @@
#include <fapi.H>
typedef fapi::ReturnCode (*mss_scominit_FP_t)(const fapi::Target & i_target);
-typedef fapi::ReturnCode (*mss_set_bbm_regs_FP_t)(const fapi::Target
- & mba_target, const uint8_t mba_pos);
extern "C" {
@@ -78,18 +78,6 @@ extern "C" {
fapi::ReturnCode mss_scominit(const fapi::Target & i_target);
-
-//******************************************************************************
-// mss_set_bbm_regs
-//******************************************************************************
-// mss_set_bbm_regs procedure [Sets disable bits in PHY registers for bad bit lanes]
-// param[in] i_target [Reference to target, expecting MBA target],
-// mba_pos [mba position, 0=mba01, 1=mba23]
-// return ReturnCode
-
-fapi::ReturnCode mss_set_bbm_regs(const fapi::Target & mba_target,
- const uint8_t mba_pos);
-
} // extern "C"
#endif // MSS_SCOMINIT_H_
diff --git a/src/usr/hwpf/hwp/dram_training/mss_unmask_errors.C b/src/usr/hwpf/hwp/dram_training/mss_unmask_errors.C
new file mode 100644
index 000000000..5efa72815
--- /dev/null
+++ b/src/usr/hwpf/hwp/dram_training/mss_unmask_errors.C
@@ -0,0 +1,2743 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/hwpf/hwp/dram_training/mss_unmask_errors.C $ */
+/* */
+/* IBM CONFIDENTIAL */
+/* */
+/* COPYRIGHT International Business Machines Corp. 2012 */
+/* */
+/* p1 */
+/* */
+/* Object Code Only (OCO) source materials */
+/* Licensed Internal Code Source Materials */
+/* IBM HostBoot Licensed Internal Code */
+/* */
+/* The source code for this program is not published or otherwise */
+/* divested of its trade secrets, irrespective of what has been */
+/* deposited with the U.S. Copyright Office. */
+/* */
+/* Origin: 30 */
+/* */
+/* IBM_PROLOG_END_TAG */
+// $Id: mss_unmask_errors.C,v 1.1 2012/09/05 21:04:52 gollub Exp $
+//------------------------------------------------------------------------------
+// Don't forget to create CVS comments when you check in your changes!
+//------------------------------------------------------------------------------
+// CHANGE HISTORY:
+//------------------------------------------------------------------------------
+// Version:| Date: | Author: | Comment:
+//---------|----------|---------|-----------------------------------------------
+// 1.1 | 09/05/12 | gollub | Created
+
+
+//------------------------------------------------------------------------------
+// Includes
+//------------------------------------------------------------------------------
+
+#include <mss_unmask_errors.H>
+#include <cen_scom_addresses.H>
+using namespace fapi;
+
+
+//------------------------------------------------------------------------------
+// Constants and enums
+//------------------------------------------------------------------------------
+
+
+//------------------------------------------------------------------------------
+// mss_unmask_inband_errors
+//------------------------------------------------------------------------------
+
+fapi::ReturnCode mss_unmask_inband_errors( const fapi::Target & i_target,
+ fapi::ReturnCode i_bad_rc )
+
+{
+
+ FAPI_INF("ENTER mss_unmask_inband_errors()");
+
+ fapi::ReturnCode l_rc;
+ uint32_t l_ecmd_rc = 0;
+
+ //*************************
+ //*************************
+ // MBS_FIR_REG
+ //*************************
+ //*************************
+
+ ecmdDataBufferBase l_mbs_fir_mask(64);
+ ecmdDataBufferBase l_mbs_fir_mask_or(64);
+ ecmdDataBufferBase l_mbs_fir_mask_and(64);
+ ecmdDataBufferBase l_mbs_fir_action0(64);
+ ecmdDataBufferBase l_mbs_fir_action1(64);
+
+ // Read mask
+ l_rc = fapiGetScom_w_retry(i_target, MBS_FIR_MASK_REG_0x02011403, l_mbs_fir_mask);
+ if(l_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+
+ // TODO: Here is where I could clear bits that were bogus, before I unmask
+ // them. But typically we are expecting the bit set at this point
+ // to be valid errors for PRD to log.
+
+
+ //(Action0, Action1, Mask)
+ //
+ // (0,0,0) = checkstop
+ // (0,1,0) = recoverable error
+ // (1,0,0) = report unused
+ // (1,1,0) = machine check
+ // (x,x,1) = error is masked
+
+ l_ecmd_rc |= l_mbs_fir_action0.flushTo0();
+ l_ecmd_rc |= l_mbs_fir_action1.flushTo0();
+ l_ecmd_rc |= l_mbs_fir_mask_or.flushTo0();
+ l_ecmd_rc |= l_mbs_fir_mask_and.flushTo1();
+
+ // 0 host_protocol_error channel checkstop unmask
+ l_ecmd_rc |= l_mbs_fir_action0.clearBit(0);
+ l_ecmd_rc |= l_mbs_fir_action1.clearBit(0);
+ l_ecmd_rc |= l_mbs_fir_mask_and.clearBit(0);
+
+ // 1 int_protocol_error channel checkstop unmask
+ l_ecmd_rc |= l_mbs_fir_action0.clearBit(1);
+ l_ecmd_rc |= l_mbs_fir_action1.clearBit(1);
+ l_ecmd_rc |= l_mbs_fir_mask_and.clearBit(1);
+
+ // 2 invalid_address_error channel checkstop mask (until unmask_fetch_errors)
+ l_ecmd_rc |= l_mbs_fir_action0.clearBit(2);
+ l_ecmd_rc |= l_mbs_fir_action1.clearBit(2);
+ l_ecmd_rc |= l_mbs_fir_mask_or.setBit(2);
+
+ // 3 external_timeout channel checkstop mask (until unmask_fetch_errors)
+ l_ecmd_rc |= l_mbs_fir_action0.clearBit(3);
+ l_ecmd_rc |= l_mbs_fir_action1.clearBit(3);
+ l_ecmd_rc |= l_mbs_fir_mask_or.setBit(3);
+
+ // 4 internal_timeout channel checkstop mask (until unmask_fetch_errors)
+ l_ecmd_rc |= l_mbs_fir_action0.clearBit(4);
+ l_ecmd_rc |= l_mbs_fir_action1.clearBit(4);
+ l_ecmd_rc |= l_mbs_fir_mask_or.setBit(4);
+
+ // 5 int_buffer_ce recoverable unmask
+ l_ecmd_rc |= l_mbs_fir_action0.clearBit(5);
+ l_ecmd_rc |= l_mbs_fir_action1.setBit(5);
+ l_ecmd_rc |= l_mbs_fir_mask_and.clearBit(5);
+
+ // 6 int_buffer_ue recoverable unmask
+ l_ecmd_rc |= l_mbs_fir_action0.clearBit(6);
+ l_ecmd_rc |= l_mbs_fir_action1.setBit(6);
+ l_ecmd_rc |= l_mbs_fir_mask_and.clearBit(6);
+
+ // 7 int_buffer_sue recoverable mask (forever)
+ l_ecmd_rc |= l_mbs_fir_action0.clearBit(7);
+ l_ecmd_rc |= l_mbs_fir_action1.setBit(7);
+ l_ecmd_rc |= l_mbs_fir_mask_or.setBit(7);
+
+ // 8 int_parity_error channel checkstop unmask
+ l_ecmd_rc |= l_mbs_fir_action0.clearBit(8);
+ l_ecmd_rc |= l_mbs_fir_action1.clearBit(8);
+ l_ecmd_rc |= l_mbs_fir_mask_and.clearBit(8);
+
+ // 9 cache_srw_ce recoverable mask (until unmask_fetch_errors)
+ l_ecmd_rc |= l_mbs_fir_action0.clearBit(9);
+ l_ecmd_rc |= l_mbs_fir_action1.setBit(9);
+ l_ecmd_rc |= l_mbs_fir_mask_or.setBit(9);
+
+ // 10 cache_srw_ue recoverable mask (until unmask_fetch_errors)
+ l_ecmd_rc |= l_mbs_fir_action0.clearBit(10);
+ l_ecmd_rc |= l_mbs_fir_action1.setBit(10);
+ l_ecmd_rc |= l_mbs_fir_mask_or.setBit(10);
+
+ // 11 cache_srw_sue recoverable mask (forever)
+ l_ecmd_rc |= l_mbs_fir_action0.clearBit(11);
+ l_ecmd_rc |= l_mbs_fir_action1.setBit(11);
+ l_ecmd_rc |= l_mbs_fir_mask_or.setBit(11);
+
+ // 12 cache_co_ce recoverable mask (until unmask_fetch_errors)
+ l_ecmd_rc |= l_mbs_fir_action0.clearBit(12);
+ l_ecmd_rc |= l_mbs_fir_action1.setBit(12);
+ l_ecmd_rc |= l_mbs_fir_mask_or.setBit(12);
+
+ // 13 cache_co_ue recoverable mask (until unmask_fetch_errors)
+ l_ecmd_rc |= l_mbs_fir_action0.clearBit(13);
+ l_ecmd_rc |= l_mbs_fir_action1.setBit(13);
+ l_ecmd_rc |= l_mbs_fir_mask_or.setBit(13);
+
+ // 14 cache_co_sue recoverable mask (forever)
+ l_ecmd_rc |= l_mbs_fir_action0.clearBit(14);
+ l_ecmd_rc |= l_mbs_fir_action1.setBit(14);
+ l_ecmd_rc |= l_mbs_fir_mask_or.setBit(14);
+
+ // 15 dir_ce recoverable mask (until unmask_fetch_errors)
+ l_ecmd_rc |= l_mbs_fir_action0.clearBit(15);
+ l_ecmd_rc |= l_mbs_fir_action1.setBit(15);
+ l_ecmd_rc |= l_mbs_fir_mask_or.setBit(15);
+
+ // 16 dir_ue channel checkstop mask (until unmask_fetch_errors)
+ l_ecmd_rc |= l_mbs_fir_action0.clearBit(16);
+ l_ecmd_rc |= l_mbs_fir_action1.clearBit(16);
+ l_ecmd_rc |= l_mbs_fir_mask_or.setBit(16);
+
+ // 17 dir_member_deleted recoverable mask (forever)
+ l_ecmd_rc |= l_mbs_fir_action0.clearBit(17);
+ l_ecmd_rc |= l_mbs_fir_action1.setBit(17);
+ l_ecmd_rc |= l_mbs_fir_mask_or.setBit(17);
+
+ // 18 dir_all_members_deleted channel checkstop mask (until unmask_fetch_errors)
+ l_ecmd_rc |= l_mbs_fir_action0.clearBit(18);
+ l_ecmd_rc |= l_mbs_fir_action1.clearBit(18);
+ l_ecmd_rc |= l_mbs_fir_mask_or.setBit(18);
+
+ // 19 lru_error recoverable mask (until unmask_fetch_errors)
+ l_ecmd_rc |= l_mbs_fir_action0.clearBit(19);
+ l_ecmd_rc |= l_mbs_fir_action1.setBit(19);
+ l_ecmd_rc |= l_mbs_fir_mask_or.setBit(19);
+
+ // 20 eDRAM error channel checkstop mask (until unmask_fetch_errors)
+ l_ecmd_rc |= l_mbs_fir_action0.clearBit(20);
+ l_ecmd_rc |= l_mbs_fir_action1.clearBit(20);
+ l_ecmd_rc |= l_mbs_fir_mask_or.setBit(20);
+
+ // 21 emergency_throttle_set recoverable mask (forever)
+ l_ecmd_rc |= l_mbs_fir_action0.clearBit(21);
+ l_ecmd_rc |= l_mbs_fir_action1.setBit(21);
+ l_ecmd_rc |= l_mbs_fir_mask_or.setBit(21);
+
+ // 22 Host Inband Read Error recoverable mask (forever)
+ l_ecmd_rc |= l_mbs_fir_action0.clearBit(22);
+ l_ecmd_rc |= l_mbs_fir_action1.setBit(22);
+ l_ecmd_rc |= l_mbs_fir_mask_or.setBit(22);
+
+ // 23 Host Inband Write Error recoverable mask (forever)
+ l_ecmd_rc |= l_mbs_fir_action0.clearBit(23);
+ l_ecmd_rc |= l_mbs_fir_action1.setBit(23);
+ l_ecmd_rc |= l_mbs_fir_mask_or.setBit(23);
+
+ // 24 OCC Inband Read Error recoverable mask (forever)
+ l_ecmd_rc |= l_mbs_fir_action0.clearBit(24);
+ l_ecmd_rc |= l_mbs_fir_action1.setBit(24);
+ l_ecmd_rc |= l_mbs_fir_mask_or.setBit(24);
+
+ // 25 OCC Inband Write Error recoverable mask (forever)
+ l_ecmd_rc |= l_mbs_fir_action0.clearBit(25);
+ l_ecmd_rc |= l_mbs_fir_action1.setBit(25);
+ l_ecmd_rc |= l_mbs_fir_mask_or.setBit(25);
+
+ // 26 srb_buffer_ce recoverable mask (until unmask_fetch_errors)
+ l_ecmd_rc |= l_mbs_fir_action0.clearBit(26);
+ l_ecmd_rc |= l_mbs_fir_action1.setBit(26);
+ l_ecmd_rc |= l_mbs_fir_mask_or.setBit(26);
+
+ // 27 srb_buffer_ue recoverable mask (until unmask_fetch_errors)
+ l_ecmd_rc |= l_mbs_fir_action0.clearBit(27);
+ l_ecmd_rc |= l_mbs_fir_action1.setBit(27);
+ l_ecmd_rc |= l_mbs_fir_mask_or.setBit(27);
+
+ // 28 srb_buffer_sue recoverable mask (forever)
+ l_ecmd_rc |= l_mbs_fir_action0.clearBit(28);
+ l_ecmd_rc |= l_mbs_fir_action1.setBit(28);
+ l_ecmd_rc |= l_mbs_fir_mask_or.setBit(28);
+
+ // 29 internal_scom_error recoverable mask (tbd)
+ l_ecmd_rc |= l_mbs_fir_action0.clearBit(29);
+ l_ecmd_rc |= l_mbs_fir_action1.setBit(29);
+ l_ecmd_rc |= l_mbs_fir_mask_or.setBit(29);
+
+ // 30 internal_scom_error_copy recoverable mask (tbd)
+ l_ecmd_rc |= l_mbs_fir_action0.clearBit(30);
+ l_ecmd_rc |= l_mbs_fir_action1.setBit(30);
+ l_ecmd_rc |= l_mbs_fir_mask_or.setBit(30);
+
+ // 31:63 Reserved not implemented, so won't touch these
+
+ if(l_ecmd_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+
+ l_rc.setEcmdError(l_ecmd_rc);
+ return l_rc;
+ }
+
+ // Write action0
+ l_rc = fapiPutScom_w_retry(i_target, MBS_FIR_ACTION0_REG_0x02011406, l_mbs_fir_action0);
+ if(l_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+
+ // Write action1
+ l_rc = fapiPutScom_w_retry(i_target, MBS_FIR_ACTION1_REG_0x02011407, l_mbs_fir_action1);
+ if(l_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+
+
+ // Write mask OR
+ l_rc = fapiPutScom_w_retry(i_target, MBS_FIR_MASK_REG_OR_0x02011405, l_mbs_fir_mask_or);
+ if(l_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+
+ // Write mask AND
+ l_rc = fapiPutScom_w_retry(i_target, MBS_FIR_MASK_REG_AND_0x02011404, l_mbs_fir_mask_and);
+ if(l_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+
+
+ //************************************************
+ // DEBUG: read them all back to verify
+ l_rc = fapiGetScom_w_retry(i_target, MBS_FIR_ACTION0_REG_0x02011406, l_mbs_fir_action0);
+ if(l_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+ l_rc = fapiGetScom_w_retry(i_target, MBS_FIR_ACTION1_REG_0x02011407, l_mbs_fir_action1);
+ if(l_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+ l_rc = fapiGetScom_w_retry(i_target, MBS_FIR_MASK_REG_0x02011403, l_mbs_fir_mask);
+ if(l_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+
+ //************************************************
+
+
+ FAPI_INF("EXIT mss_unmask_inband_errors()");
+
+ return i_bad_rc;
+}
+
+
+
+//------------------------------------------------------------------------------
+// mss_unmask_ddrphy_errors
+//------------------------------------------------------------------------------
+
+fapi::ReturnCode mss_unmask_ddrphy_errors( const fapi::Target & i_target,
+ fapi::ReturnCode i_bad_rc )
+
+{
+
+ FAPI_INF("ENTER mss_unmask ddrphy_errors()");
+
+ fapi::ReturnCode l_rc;
+ uint32_t l_ecmd_rc = 0;
+
+ //*************************
+ //*************************
+ // DDRPHY_FIR_REG
+ //*************************
+ //*************************
+
+ ecmdDataBufferBase l_ddrphy_fir_mask(64);
+ ecmdDataBufferBase l_ddrphy_fir_mask_or(64);
+ ecmdDataBufferBase l_ddrphy_fir_mask_and(64);
+ ecmdDataBufferBase l_ddrphy_fir_action0(64);
+ ecmdDataBufferBase l_ddrphy_fir_action1(64);
+
+
+ // TODO: Here is where I could clear bits that were bogus, before I unmask
+ // them. But typically we are expecting the bit set at this point
+ // to be valid errors for PRD to log.
+
+
+ //(Action0, Action1, Mask)
+ //
+ // (0,0,0) = checkstop
+ // (0,1,0) = recoverable error
+ // (1,0,0) = report unused
+ // (1,1,0) = machine check
+ // (x,x,1) = error is masked
+
+ l_ecmd_rc |= l_ddrphy_fir_action0.flushTo0();
+ l_ecmd_rc |= l_ddrphy_fir_action1.flushTo0();
+ l_ecmd_rc |= l_ddrphy_fir_mask_or.flushTo0();
+ l_ecmd_rc |= l_ddrphy_fir_mask_and.flushTo0();
+ l_ecmd_rc |= l_ddrphy_fir_mask_and.setBit(48,16);
+
+ // 0:47 Reserved not implemented, so won't touch these
+
+ // 48 ddr0_fsm_ckstp channel checkstop unmask
+ l_ecmd_rc |= l_ddrphy_fir_action0.clearBit(48);
+ l_ecmd_rc |= l_ddrphy_fir_action1.clearBit(48);
+ l_ecmd_rc |= l_ddrphy_fir_mask_and.clearBit(48);
+
+ // 49 ddr0_parity_ckstp channel checkstop unmask
+ l_ecmd_rc |= l_ddrphy_fir_action0.clearBit(49);
+ l_ecmd_rc |= l_ddrphy_fir_action1.clearBit(49);
+ l_ecmd_rc |= l_ddrphy_fir_mask_and.clearBit(49);
+
+ // 50 ddr0_calibration_error recoverable mask (forever)
+ l_ecmd_rc |= l_ddrphy_fir_action0.clearBit(50);
+ l_ecmd_rc |= l_ddrphy_fir_action1.setBit(50);
+ l_ecmd_rc |= l_ddrphy_fir_mask_or.setBit(50);
+
+ // 51 ddr0_fsm_err recoverable unmask
+ l_ecmd_rc |= l_ddrphy_fir_action0.clearBit(51);
+ l_ecmd_rc |= l_ddrphy_fir_action1.setBit(51);
+ l_ecmd_rc |= l_ddrphy_fir_mask_and.clearBit(51);
+
+ // 52 ddr0_parity_err recoverable unmask
+ l_ecmd_rc |= l_ddrphy_fir_action0.clearBit(52);
+ l_ecmd_rc |= l_ddrphy_fir_action1.setBit(52);
+ l_ecmd_rc |= l_ddrphy_fir_mask_and.clearBit(52);
+
+ // 53 ddr01_fir_parity_err recoverable mask (forever)
+ l_ecmd_rc |= l_ddrphy_fir_action0.clearBit(53);
+ l_ecmd_rc |= l_ddrphy_fir_action1.setBit(53);
+ l_ecmd_rc |= l_ddrphy_fir_mask_or.setBit(53);
+
+ // 54 Reserved recoverable mask (forever)
+ l_ecmd_rc |= l_ddrphy_fir_action0.clearBit(54);
+ l_ecmd_rc |= l_ddrphy_fir_action1.setBit(54);
+ l_ecmd_rc |= l_ddrphy_fir_mask_or.setBit(54);
+
+ // 55 Reserved recoverable mask (forever)
+ l_ecmd_rc |= l_ddrphy_fir_action0.clearBit(55);
+ l_ecmd_rc |= l_ddrphy_fir_action1.setBit(55);
+ l_ecmd_rc |= l_ddrphy_fir_mask_or.setBit(55);
+
+ // 56 ddr1_fsm_ckstp channel checkstop unmask
+ l_ecmd_rc |= l_ddrphy_fir_action0.clearBit(56);
+ l_ecmd_rc |= l_ddrphy_fir_action1.clearBit(56);
+ l_ecmd_rc |= l_ddrphy_fir_mask_and.clearBit(56);
+
+ // 57 ddr1_parity_ckstp channel checkstop unmask
+ l_ecmd_rc |= l_ddrphy_fir_action0.clearBit(57);
+ l_ecmd_rc |= l_ddrphy_fir_action1.clearBit(57);
+ l_ecmd_rc |= l_ddrphy_fir_mask_and.clearBit(57);
+
+ // 58 ddr1_calibration_error recoverable mask (forever)
+ l_ecmd_rc |= l_ddrphy_fir_action0.clearBit(58);
+ l_ecmd_rc |= l_ddrphy_fir_action1.setBit(58);
+ l_ecmd_rc |= l_ddrphy_fir_mask_or.setBit(58);
+
+ // 59 ddr1_fsm_err recoverable unmask
+ l_ecmd_rc |= l_ddrphy_fir_action0.clearBit(59);
+ l_ecmd_rc |= l_ddrphy_fir_action1.setBit(59);
+ l_ecmd_rc |= l_ddrphy_fir_mask_and.clearBit(59);
+
+ // 60 ddr1_parity_err recoverable unmask
+ l_ecmd_rc |= l_ddrphy_fir_action0.clearBit(60);
+ l_ecmd_rc |= l_ddrphy_fir_action1.setBit(60);
+ l_ecmd_rc |= l_ddrphy_fir_mask_and.clearBit(60);
+
+ // 61 Reserved recoverable mask (forever)
+ l_ecmd_rc |= l_ddrphy_fir_action0.clearBit(61);
+ l_ecmd_rc |= l_ddrphy_fir_action1.setBit(61);
+ l_ecmd_rc |= l_ddrphy_fir_mask_or.setBit(61);
+
+ // 62 Reserved recoverable mask (forever)
+ l_ecmd_rc |= l_ddrphy_fir_action0.clearBit(62);
+ l_ecmd_rc |= l_ddrphy_fir_action1.setBit(62);
+ l_ecmd_rc |= l_ddrphy_fir_mask_or.setBit(62);
+
+ // 63 Reserved recoverable mask (forever)
+ l_ecmd_rc |= l_ddrphy_fir_action0.clearBit(63);
+ l_ecmd_rc |= l_ddrphy_fir_action1.setBit(63);
+ l_ecmd_rc |= l_ddrphy_fir_mask_or.setBit(63);
+
+
+
+ if(l_ecmd_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+
+ l_rc.setEcmdError(l_ecmd_rc);
+ return l_rc;
+ }
+
+ // Write action0
+ l_rc = fapiPutScom_w_retry(i_target, PHY01_DDRPHY_FIR_ACTION0_REG_0x800200960301143f, l_ddrphy_fir_action0);
+ if(l_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+
+ // Write action1
+ l_rc = fapiPutScom_w_retry(i_target, PHY01_DDRPHY_FIR_ACTION1_REG_0x800200970301143f, l_ddrphy_fir_action1);
+ if(l_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+
+
+ // Write mask OR
+ l_rc = fapiPutScom_w_retry(i_target, PHY01_DDRPHY_FIR_MASK_REG_OR_0x800200950301143f, l_ddrphy_fir_mask_or);
+ if(l_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+
+ // Write mask AND
+ l_rc = fapiPutScom_w_retry(i_target, PHY01_DDRPHY_FIR_MASK_REG_AND_0x800200940301143f, l_ddrphy_fir_mask_and);
+ if(l_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+
+
+ //************************************************
+ // DEBUG: read them all back to verify
+ l_rc = fapiGetScom_w_retry(i_target, PHY01_DDRPHY_FIR_ACTION0_REG_0x800200960301143f, l_ddrphy_fir_action0);
+ if(l_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+ l_rc = fapiGetScom_w_retry(i_target, PHY01_DDRPHY_FIR_ACTION1_REG_0x800200970301143f, l_ddrphy_fir_action1);
+ if(l_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+ l_rc = fapiGetScom_w_retry(i_target, PHY01_DDRPHY_FIR_MASK_REG_0x800200930301143f, l_ddrphy_fir_mask);
+ if(l_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+
+ //************************************************
+
+
+ //*************************
+ //*************************
+ // MBAFIR
+ //*************************
+ //*************************
+
+ ecmdDataBufferBase l_mbafir_mask(64);
+ ecmdDataBufferBase l_mbafir_mask_or(64);
+ ecmdDataBufferBase l_mbafir_mask_and(64);
+ ecmdDataBufferBase l_mbafir_action0(64);
+ ecmdDataBufferBase l_mbafir_action1(64);
+
+
+ // Read mask
+ l_rc = fapiGetScom_w_retry(i_target,
+ MBA01_MBAFIRMASK_0x03010603,
+ l_mbafir_mask);
+ if(l_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+
+ // TODO: Here is where I could clear bits that were bogus, before I unmask
+ // them. But typically we are expecting the bit set at this point
+ // to be valid errors for PRD to log.
+
+
+ //(Action0, Action1, Mask)
+ //
+ // (0,0,0) = checkstop
+ // (0,1,0) = recoverable error
+ // (1,0,0) = report unused
+ // (1,1,0) = machine check
+ // (x,x,1) = error is masked
+
+ l_ecmd_rc |= l_mbafir_action0.flushTo0();
+ l_ecmd_rc |= l_mbafir_action1.flushTo0();
+ l_ecmd_rc |= l_mbafir_mask_or.flushTo0();
+ l_ecmd_rc |= l_mbafir_mask_and.flushTo1();
+
+
+ // 0 Invalid_Maint_Cmd recoverable masked (forever)
+ l_ecmd_rc |= l_mbafir_action0.clearBit(0);
+ l_ecmd_rc |= l_mbafir_action1.setBit(0);
+ l_ecmd_rc |= l_mbafir_mask_or.setBit(0);
+
+ // 1 Invalid_Maint_Address recoverable masked (forever)
+ l_ecmd_rc |= l_mbafir_action0.clearBit(1);
+ l_ecmd_rc |= l_mbafir_action1.setBit(1);
+ l_ecmd_rc |= l_mbafir_mask_or.setBit(1);
+
+ // 2 Multi_address_Maint_timeout recoverable masked (until mss_unmask_maint_errors)
+ l_ecmd_rc |= l_mbafir_action0.clearBit(2);
+ l_ecmd_rc |= l_mbafir_action1.setBit(2);
+ l_ecmd_rc |= l_mbafir_mask_or.setBit(2);
+
+ // 3 Internal_fsm_error recoverable unmask
+ l_ecmd_rc |= l_mbafir_action0.clearBit(3);
+ l_ecmd_rc |= l_mbafir_action1.setBit(3);
+ l_ecmd_rc |= l_mbafir_mask_and.clearBit(3);
+
+ // 4 MCBIST_Error recoverable mask (forever)
+ l_ecmd_rc |= l_mbafir_action0.clearBit(4);
+ l_ecmd_rc |= l_mbafir_action1.setBit(4);
+ l_ecmd_rc |= l_mbafir_mask_or.setBit(4);
+
+ // 5 scom_cmd_reg_pe recoverable unmask
+ l_ecmd_rc |= l_mbafir_action0.clearBit(5);
+ l_ecmd_rc |= l_mbafir_action1.setBit(5);
+ l_ecmd_rc |= l_mbafir_mask_and.clearBit(5);
+
+ // 6 channel_chkstp_err channel checkstop unmask
+ l_ecmd_rc |= l_mbafir_action0.clearBit(6);
+ l_ecmd_rc |= l_mbafir_action1.clearBit(6);
+ l_ecmd_rc |= l_mbafir_mask_and.clearBit(6);
+
+ // 7 wrd_caw2_data_ce_ue_err recoverable masked (until mss_unmask_maint_errors)
+ l_ecmd_rc |= l_mbafir_action0.clearBit(7);
+ l_ecmd_rc |= l_mbafir_action1.setBit(7);
+ l_ecmd_rc |= l_mbafir_mask_or.setBit(7);
+
+ // 8:14 RESERVED recoverable mask (forever)
+ l_ecmd_rc |= l_mbafir_action0.clearBit(8,7);
+ l_ecmd_rc |= l_mbafir_action1.setBit(8,7);
+ l_ecmd_rc |= l_mbafir_mask_or.setBit(8,7);
+
+ // 15 internal scom error recoverable mask (tbd)
+ l_ecmd_rc |= l_mbafir_action0.clearBit(15);
+ l_ecmd_rc |= l_mbafir_action1.setBit(15);
+ l_ecmd_rc |= l_mbafir_mask_or.setBit(15);
+
+ // 16 internal scom error clone recoverable mask (tbd)
+ l_ecmd_rc |= l_mbafir_action0.clearBit(16);
+ l_ecmd_rc |= l_mbafir_action1.setBit(16);
+ l_ecmd_rc |= l_mbafir_mask_or.setBit(16);
+
+
+ // 17:63 RESERVED not implemented, so won't touch these
+
+ if(l_ecmd_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+
+ l_rc.setEcmdError(l_ecmd_rc);
+ return l_rc;
+ }
+
+ // Write action0
+ l_rc = fapiPutScom_w_retry(i_target,
+ MBA01_MBAFIRACT0_0x03010606,
+ l_mbafir_action0);
+ if(l_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+
+ // Write action1
+ l_rc = fapiPutScom_w_retry(i_target,
+ MBA01_MBAFIRACT1_0x03010607,
+ l_mbafir_action1);
+ if(l_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+
+
+ // Write mask OR
+ l_rc = fapiPutScom_w_retry(i_target,
+ MBA01_MBAFIRMASK_OR_0x03010605,
+ l_mbafir_mask_or);
+ if(l_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+
+
+ // Write mask AND
+ l_rc = fapiPutScom_w_retry(i_target,
+ MBA01_MBAFIRMASK_AND_0x03010604,
+ l_mbafir_mask_and);
+ if(l_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+
+
+ //************************************************
+ // DEBUG: read them all back to verify
+ l_rc = fapiGetScom_w_retry(i_target,
+ MBA01_MBAFIRACT0_0x03010606,
+ l_mbafir_action0);
+ if(l_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+ l_rc = fapiGetScom_w_retry(i_target,
+ MBA01_MBAFIRACT1_0x03010607,
+ l_mbafir_action1);
+ if(l_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+ l_rc = fapiGetScom_w_retry(i_target,
+ MBA01_MBAFIRMASK_0x03010603,
+ l_mbafir_mask);
+ if(l_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+
+ //************************************************
+
+
+ FAPI_INF("EXIT mss_unmask_ddrphy_errors()");
+
+ return i_bad_rc;
+}
+
+
+//------------------------------------------------------------------------------
+// mss_unmask_draminit_errors
+//------------------------------------------------------------------------------
+
+fapi::ReturnCode mss_unmask_draminit_errors( const fapi::Target & i_target,
+ fapi::ReturnCode i_bad_rc )
+
+{
+
+ FAPI_INF("ENTER mss_unmask_draminit_errors()");
+
+ fapi::ReturnCode l_rc;
+ uint32_t l_ecmd_rc = 0;
+
+ //*************************
+ //*************************
+ // MBACALFIR
+ //*************************
+ //*************************
+
+ ecmdDataBufferBase l_mbacalfir_mask(64);
+ ecmdDataBufferBase l_mbacalfir_mask_or(64);
+ ecmdDataBufferBase l_mbacalfir_mask_and(64);
+ ecmdDataBufferBase l_mbacalfir_action0(64);
+ ecmdDataBufferBase l_mbacalfir_action1(64);
+
+
+ // Read mask
+ l_rc = fapiGetScom_w_retry(i_target, MBA01_MBACALFIR_MASK_0x03010403, l_mbacalfir_mask);
+ if(l_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+
+ // TODO: Here is where I could clear bits that were bogus, before I unmask
+ // them. But typically we are expecting the bit set at this point
+ // to be valid errors for PRD to log.
+
+
+ //(Action0, Action1, Mask)
+ //
+ // (0,0,0) = checkstop
+ // (0,1,0) = recoverable error
+ // (1,0,0) = report unused
+ // (1,1,0) = machine check
+ // (x,x,1) = error is masked
+
+ l_ecmd_rc |= l_mbacalfir_action0.flushTo0();
+ l_ecmd_rc |= l_mbacalfir_action1.flushTo0();
+ l_ecmd_rc |= l_mbacalfir_mask_or.flushTo0();
+ l_ecmd_rc |= l_mbacalfir_mask_and.flushTo1();
+
+ // 0 MBA Recoverable Error recoverable mask
+ l_ecmd_rc |= l_mbacalfir_action0.clearBit(0);
+ l_ecmd_rc |= l_mbacalfir_action1.setBit(0);
+ l_ecmd_rc |= l_mbacalfir_mask_or.setBit(0);
+
+ // 1 MBA Nonrecoverable Error channel checkstop mask
+ l_ecmd_rc |= l_mbacalfir_action0.clearBit(1);
+ l_ecmd_rc |= l_mbacalfir_action1.clearBit(1);
+ l_ecmd_rc |= l_mbacalfir_mask_or.setBit(1);
+
+ // 2 Refresh Overrun recoverable mask
+ l_ecmd_rc |= l_mbacalfir_action0.clearBit(2);
+ l_ecmd_rc |= l_mbacalfir_action1.setBit(2);
+ l_ecmd_rc |= l_mbacalfir_mask_or.setBit(2);
+
+ // 3 WAT error recoverable mask (forever)
+ l_ecmd_rc |= l_mbacalfir_action0.clearBit(3);
+ l_ecmd_rc |= l_mbacalfir_action1.setBit(3);
+ l_ecmd_rc |= l_mbacalfir_mask_or.setBit(3);
+
+ // 4 RCD Parity Error 0 recoverable unmask (only if set)
+ // TODO: Unmask, only if set, only if ISD DIMM
+ l_ecmd_rc |= l_mbacalfir_action0.clearBit(4);
+ l_ecmd_rc |= l_mbacalfir_action1.setBit(4);
+ l_ecmd_rc |= l_mbacalfir_mask_or.setBit(4);
+
+ // 5 ddr0_cal_timeout_err recoverable mask
+ l_ecmd_rc |= l_mbacalfir_action0.clearBit(5);
+ l_ecmd_rc |= l_mbacalfir_action1.setBit(5);
+ l_ecmd_rc |= l_mbacalfir_mask_or.setBit(5);
+
+ // 6 ddr1_cal_timeout_err recoverable mask
+ l_ecmd_rc |= l_mbacalfir_action0.clearBit(6);
+ l_ecmd_rc |= l_mbacalfir_action1.setBit(6);
+ l_ecmd_rc |= l_mbacalfir_mask_or.setBit(6);
+
+ // 7 RCD Parity Error 1 recoverable unmask (only if set)
+ // TODO: Unmask, only if set, only if ISD DIMM
+ l_ecmd_rc |= l_mbacalfir_action0.clearBit(7);
+ l_ecmd_rc |= l_mbacalfir_action1.setBit(7);
+ l_ecmd_rc |= l_mbacalfir_mask_or.setBit(7);
+
+
+ // 8 mbx to mba par error channel checkstop mask
+ l_ecmd_rc |= l_mbacalfir_action0.clearBit(8);
+ l_ecmd_rc |= l_mbacalfir_action1.clearBit(8);
+ l_ecmd_rc |= l_mbacalfir_mask_or.setBit(8);
+
+ // 9 mba_wrd ue recoverable mask
+ l_ecmd_rc |= l_mbacalfir_action0.clearBit(9);
+ l_ecmd_rc |= l_mbacalfir_action1.setBit(9);
+ l_ecmd_rc |= l_mbacalfir_mask_or.setBit(9);
+
+ // 10 mba_wrd ce recoverable mask
+ l_ecmd_rc |= l_mbacalfir_action0.clearBit(10);
+ l_ecmd_rc |= l_mbacalfir_action1.setBit(10);
+ l_ecmd_rc |= l_mbacalfir_mask_or.setBit(10);
+
+ // 11 mba_maint ue recoverable mask
+ l_ecmd_rc |= l_mbacalfir_action0.clearBit(11);
+ l_ecmd_rc |= l_mbacalfir_action1.setBit(11);
+ l_ecmd_rc |= l_mbacalfir_mask_or.setBit(11);
+
+ // 12 mba_maint ce recoverable mask
+ l_ecmd_rc |= l_mbacalfir_action0.clearBit(12);
+ l_ecmd_rc |= l_mbacalfir_action1.setBit(12);
+ l_ecmd_rc |= l_mbacalfir_mask_or.setBit(12);
+
+ // 13 ddr_cal_reset_timeout channel checkstop mask
+ // TODO: Leaving masked until I find proper spot to unmask this
+ l_ecmd_rc |= l_mbacalfir_action0.clearBit(13);
+ l_ecmd_rc |= l_mbacalfir_action1.clearBit(13);
+ l_ecmd_rc |= l_mbacalfir_mask_or.setBit(13);
+
+ // 14 wrq_data_ce recoverable mask
+ l_ecmd_rc |= l_mbacalfir_action0.clearBit(14);
+ l_ecmd_rc |= l_mbacalfir_action1.setBit(14);
+ l_ecmd_rc |= l_mbacalfir_mask_or.setBit(14);
+
+ // 15 wrq_data_ue recoverable mask
+ l_ecmd_rc |= l_mbacalfir_action0.clearBit(15);
+ l_ecmd_rc |= l_mbacalfir_action1.setBit(15);
+ l_ecmd_rc |= l_mbacalfir_mask_or.setBit(15);
+
+ // 16 wrq_data_sue recoverable mask
+ l_ecmd_rc |= l_mbacalfir_action0.clearBit(16);
+ l_ecmd_rc |= l_mbacalfir_action1.setBit(16);
+ l_ecmd_rc |= l_mbacalfir_mask_or.setBit(16);
+
+ // 17 wrq_rrq_hang_err recoverable mask
+ l_ecmd_rc |= l_mbacalfir_action0.clearBit(17);
+ l_ecmd_rc |= l_mbacalfir_action1.setBit(17);
+ l_ecmd_rc |= l_mbacalfir_mask_or.setBit(17);
+
+ // 18 sm_1hot_err recoverable unmask
+ l_ecmd_rc |= l_mbacalfir_action0.clearBit(18);
+ l_ecmd_rc |= l_mbacalfir_action1.setBit(18);
+ l_ecmd_rc |= l_mbacalfir_mask_and.clearBit(18);
+
+ // 19 wrd_scom_error recoverable mask (tbd)
+ l_ecmd_rc |= l_mbacalfir_action0.clearBit(19);
+ l_ecmd_rc |= l_mbacalfir_action1.setBit(19);
+ l_ecmd_rc |= l_mbacalfir_mask_or.setBit(19);
+
+ // 20 internal_scom_error recoverable mask (tbd)
+ l_ecmd_rc |= l_mbacalfir_action0.clearBit(20);
+ l_ecmd_rc |= l_mbacalfir_action1.setBit(20);
+ l_ecmd_rc |= l_mbacalfir_mask_or.setBit(20);
+
+ // 21 internal_scom_error_copy recoverable mask (tbd)
+ l_ecmd_rc |= l_mbacalfir_action0.clearBit(21);
+ l_ecmd_rc |= l_mbacalfir_action1.setBit(21);
+ l_ecmd_rc |= l_mbacalfir_mask_or.setBit(21);
+
+ // 22-63 Reserved not implemented, so won't touch these
+
+
+ if(l_ecmd_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+
+ l_rc.setEcmdError(l_ecmd_rc);
+ return l_rc;
+ }
+
+ // Write action0
+ l_rc = fapiPutScom_w_retry(i_target, MBA01_MBACALFIR_ACTION0_0x03010406, l_mbacalfir_action0);
+ if(l_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+
+ // Write action1
+ l_rc = fapiPutScom_w_retry(i_target, MBA01_MBACALFIR_ACTION1_0x03010407, l_mbacalfir_action1);
+ if(l_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+
+
+ // Write mask OR
+ l_rc = fapiPutScom_w_retry(i_target, MBA01_MBACALFIR_MASK_OR_0x03010405, l_mbacalfir_mask_or);
+ if(l_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+
+ // Write mask AND
+ l_rc = fapiPutScom_w_retry(i_target, MBA01_MBACALFIR_MASK_AND_0x03010404, l_mbacalfir_mask_and);
+ if(l_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+
+
+ //************************************************
+ // DEBUG: read them all back to verify
+ l_rc = fapiGetScom_w_retry(i_target, MBA01_MBACALFIR_ACTION0_0x03010406, l_mbacalfir_action0);
+ if(l_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+ l_rc = fapiGetScom_w_retry(i_target, MBA01_MBACALFIR_ACTION1_0x03010407, l_mbacalfir_action1);
+ if(l_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+ l_rc = fapiGetScom_w_retry(i_target, MBA01_MBACALFIR_MASK_0x03010403, l_mbacalfir_mask);
+ if(l_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+
+ //************************************************
+
+
+ FAPI_INF("EXIT mss_unmask_draminit_errors()");
+
+ return i_bad_rc;
+}
+
+
+//------------------------------------------------------------------------------
+// mss_unmask_draminit_training_errors
+//------------------------------------------------------------------------------
+
+fapi::ReturnCode mss_unmask_draminit_training_errors(
+ const fapi::Target & i_target,
+ fapi::ReturnCode i_bad_rc )
+
+{
+
+ FAPI_INF("ENTER mss_unmask_draminit_training_errors()");
+
+ fapi::ReturnCode l_rc;
+ uint32_t l_ecmd_rc = 0;
+
+ //*************************
+ //*************************
+ // MBACALFIR
+ //*************************
+ //*************************
+
+ ecmdDataBufferBase l_mbacalfir_mask(64);
+ ecmdDataBufferBase l_mbacalfir_mask_and(64);
+
+ // NOTE: In the IPL sequence, mss_unmask_draminit_errors has already been
+ // called, which has already set the MBACALFIR action regs to their runtime
+ // values, so no need to touch the action regs here.
+
+ // NOTE: In the IPL sequence, mss_unmask_draminit_errors has already been
+ // called, which has already unmasked the approproiate MBACALFIR errors
+ // following mss_draminit. So all we will do here is unmask a few more
+ // errors that would be considered valid after the mss_draminit_training
+ // procedure.
+
+
+ // Read mask
+ l_rc = fapiGetScom_w_retry(i_target, MBA01_MBACALFIR_MASK_0x03010403, l_mbacalfir_mask);
+ if(l_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+
+ // TODO: Here is where I could clear bits that were bogus, before I unmask
+ // them. But typically we are expecting the bit set at this point
+ // to be valid errors for PRD to log.
+
+
+ //(Action0, Action1, Mask)
+ //
+ // (0,0,0) = checkstop
+ // (0,1,0) = recoverable error
+ // (1,0,0) = report unused
+ // (1,1,0) = machine check
+ // (x,x,1) = error is masked
+
+ l_ecmd_rc |= l_mbacalfir_mask_and.flushTo1();
+
+ // 0 MBA Recoverable Error recoverable umask
+ l_ecmd_rc |= l_mbacalfir_mask_and.clearBit(0);
+
+ // 4 RCD Parity Error 0 recoverable unmask (only if set)
+ // TODO: Unmask, only if set, only if ISD DIMM
+
+ // 7 RCD Parity Error 1 recoverable unmask (only if set)
+ // TODO: Unmask, only if set, only if ISD DIMM
+
+ if(l_ecmd_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+
+ l_rc.setEcmdError(l_ecmd_rc);
+ return l_rc;
+ }
+
+
+ // Write mask AND
+ l_rc = fapiPutScom_w_retry(i_target, MBA01_MBACALFIR_MASK_AND_0x03010404, l_mbacalfir_mask_and);
+ if(l_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+
+ //************************************************
+ // DEBUG: read them all back to verify
+ l_rc = fapiGetScom_w_retry(i_target, MBA01_MBACALFIR_MASK_0x03010403, l_mbacalfir_mask);
+ if(l_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+
+ //************************************************
+
+
+ FAPI_INF("EXIT mss_unmask_draminit_training_errors()");
+
+ return i_bad_rc;
+}
+
+
+//------------------------------------------------------------------------------
+// mss_unmask_draminit_training_advanced_errors
+//------------------------------------------------------------------------------
+
+fapi::ReturnCode mss_unmask_draminit_training_advanced_errors(
+ const fapi::Target & i_target,
+ fapi::ReturnCode i_bad_rc )
+
+{
+
+ FAPI_INF("ENTER mss_unmask_draminit_training_advanced_errors()");
+
+ fapi::ReturnCode l_rc;
+ uint32_t l_ecmd_rc = 0;
+
+ //*************************
+ //*************************
+ // MBACALFIR
+ //*************************
+ //*************************
+
+ ecmdDataBufferBase l_mbacalfir_mask(64);
+ ecmdDataBufferBase l_mbacalfir_mask_and(64);
+
+ // NOTE: In the IPL sequence, mss_unmask_draminit_errors has already been
+ // called, which has already set the MBACALFIR action regs to their runtime
+ // values, so no need to touch the action regs here.
+
+ // NOTE: In the IPL sequence, mss_unmask_draminit_errors and
+ // mss_unmask_draminit_training has already been
+ // called, which has already unmasked the approproiate MBACALFIR errors
+ // following mss_draminit and mss_draminit_training. So all we will do here
+ // is unmask a few more errors that would be considered valid after the
+ // mss_draminit_training_advanced procedure.
+
+
+ // Read mask
+ l_rc = fapiGetScom_w_retry(i_target, MBA01_MBACALFIR_MASK_0x03010403, l_mbacalfir_mask);
+ if(l_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+
+ // TODO: Here is where I could clear bits that were bogus, before I unmask
+ // them. But typically we are expecting the bit set at this point
+ // to be valid errors for PRD to log.
+
+
+ //(Action0, Action1, Mask)
+ //
+ // (0,0,0) = checkstop
+ // (0,1,0) = recoverable error
+ // (1,0,0) = report unused
+ // (1,1,0) = machine check
+ // (x,x,1) = error is masked
+
+ l_ecmd_rc |= l_mbacalfir_mask_and.flushTo1();
+
+ // 4 RCD Parity Error 0 recoverable unmask
+ // TODO: Unmask, only if ISD DIMM
+
+ // 7 RCD Parity Error 1 recoverable unmask
+ // TODO: Unmask, only if ISD DIMM
+
+ // 8 mbx to mba par error channel checkstop unmask
+ l_ecmd_rc |= l_mbacalfir_mask_and.clearBit(8);
+
+ // 11 mba_maint ue recoverable unmask
+ l_ecmd_rc |= l_mbacalfir_mask_and.clearBit(11);
+
+ // 12 mba_maint ce recoverable unmask
+ l_ecmd_rc |= l_mbacalfir_mask_and.clearBit(12);
+
+ // 17 wrq_rrq_hang_err recoverable unmask
+ l_ecmd_rc |= l_mbacalfir_mask_and.clearBit(17);
+
+
+ if(l_ecmd_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+
+ l_rc.setEcmdError(l_ecmd_rc);
+ return l_rc;
+ }
+
+
+ // Write mask AND
+ l_rc = fapiPutScom_w_retry(i_target, MBA01_MBACALFIR_MASK_AND_0x03010404, l_mbacalfir_mask_and);
+ if(l_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+
+ //************************************************
+ // DEBUG: read them all back to verify
+ l_rc = fapiGetScom_w_retry(i_target, MBA01_MBACALFIR_MASK_0x03010403, l_mbacalfir_mask);
+ if(l_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+
+ //************************************************
+
+
+ //*************************
+ //*************************
+ // MBSFIR
+ //*************************
+ //*************************
+
+ fapi::Target l_targetCentaur;
+ uint8_t l_mbaPosition; // 0 = mba01, 1 = mba23
+
+ uint32_t l_mbsfir_mask_address[2]={
+ // port0/1 port2/3
+ MBS01_MBSFIRMASK_0x02011603, MBS23_MBSFIRMASK_0x02011703};
+
+ uint32_t l_mbsfir_mask_or_address[2]={
+ // port0/1 port2/3
+ MBS01_MBSFIRMASK_OR_0x02011605, MBS23_MBSFIRMASK_OR_0x02011705};
+
+ uint32_t l_mbsfir_mask_and_address[2]={
+ // port0/1 port2/3
+ MBS01_MBSFIRMASK_AND_0x02011604, MBS23_MBSFIRMASK_AND_0x02011704};
+
+ uint32_t l_mbsfir_action0_address[2]={
+ // port0/1 port2/3
+ MBS01_MBSFIRACT0_0x02011606, MBS23_MBSFIRACT0_0x02011706};
+
+ uint32_t l_mbsfir_action1_address[2]={
+ // port0/1 port2/3
+ MBS01_MBSFIRACT1_0x02011607, MBS23_MBSFIRACT1_0x02011707};
+
+ ecmdDataBufferBase l_mbsfir_mask(64);
+ ecmdDataBufferBase l_mbsfir_mask_or(64);
+ ecmdDataBufferBase l_mbsfir_mask_and(64);
+ ecmdDataBufferBase l_mbsfir_action0(64);
+ ecmdDataBufferBase l_mbsfir_action1(64);
+
+ // Get Centaur target for the given MBA
+ l_rc = fapiGetParentChip(i_target, l_targetCentaur);
+ if(l_rc)
+ {
+ FAPI_ERR("Error getting Centaur parent target for the given MBA");
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+
+ // Get MBA position: 0 = mba01, 1 = mba23
+ l_rc = FAPI_ATTR_GET(ATTR_CHIP_UNIT_POS, &i_target, l_mbaPosition);
+ if(l_rc)
+ {
+ FAPI_ERR("Error getting MBA position");
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+
+ // Read mask
+ l_rc = fapiGetScom_w_retry(l_targetCentaur,
+ l_mbsfir_mask_address[l_mbaPosition],
+ l_mbsfir_mask);
+ if(l_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+
+ // TODO: Here is where I could clear bits that were bogus, before I unmask
+ // them. But typically we are expecting the bit set at this point
+ // to be valid errors for PRD to log.
+
+
+ //(Action0, Action1, Mask)
+ //
+ // (0,0,0) = checkstop
+ // (0,1,0) = recoverable error
+ // (1,0,0) = report unused
+ // (1,1,0) = machine check
+ // (x,x,1) = error is masked
+
+ l_ecmd_rc |= l_mbsfir_action0.flushTo0();
+ l_ecmd_rc |= l_mbsfir_action1.flushTo0();
+ l_ecmd_rc |= l_mbsfir_mask_or.flushTo0();
+ l_ecmd_rc |= l_mbsfir_mask_and.flushTo1();
+
+ // 0 scom_par_errors recoverable unmask
+ l_ecmd_rc |= l_mbsfir_action0.clearBit(0);
+ l_ecmd_rc |= l_mbsfir_action1.setBit(0);
+ l_ecmd_rc |= l_mbsfir_mask_and.clearBit(0);
+
+ // 1 mbx_par_errors channel checkstop unmask
+ l_ecmd_rc |= l_mbsfir_action0.clearBit(1);
+ l_ecmd_rc |= l_mbsfir_action1.clearBit(1);
+ l_ecmd_rc |= l_mbsfir_mask_and.clearBit(1);
+
+ // 2:14 RESERVED recoverable mask (forever)
+ l_ecmd_rc |= l_mbsfir_action0.clearBit(2,13);
+ l_ecmd_rc |= l_mbsfir_action1.setBit(2,13);
+ l_ecmd_rc |= l_mbsfir_mask_or.setBit(2,13);
+
+ // 15 internal scom error recoverable mask (tbd)
+ l_ecmd_rc |= l_mbsfir_action0.clearBit(15);
+ l_ecmd_rc |= l_mbsfir_action1.setBit(15);
+ l_ecmd_rc |= l_mbsfir_mask_or.setBit(15);
+
+ // 16 internal scom error clone recoverable mask (tbd)
+ l_ecmd_rc |= l_mbsfir_action0.clearBit(16);
+ l_ecmd_rc |= l_mbsfir_action1.setBit(16);
+ l_ecmd_rc |= l_mbsfir_mask_or.setBit(16);
+
+ // 17:63 RESERVED not implemented, so won't touch these
+
+
+ if(l_ecmd_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+
+ l_rc.setEcmdError(l_ecmd_rc);
+ return l_rc;
+ }
+
+ // Write action0
+ l_rc = fapiPutScom_w_retry(l_targetCentaur,
+ l_mbsfir_action0_address[l_mbaPosition],
+ l_mbsfir_action0);
+ if(l_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+
+ // Write action1
+ l_rc = fapiPutScom_w_retry(l_targetCentaur,
+ l_mbsfir_action1_address[l_mbaPosition],
+ l_mbsfir_action1);
+ if(l_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+
+
+ // Write mask OR
+ l_rc = fapiPutScom_w_retry(l_targetCentaur,
+ l_mbsfir_mask_or_address[l_mbaPosition],
+ l_mbsfir_mask_or);
+ if(l_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+
+
+ // Write mask AND
+ l_rc = fapiPutScom_w_retry(l_targetCentaur,
+ l_mbsfir_mask_and_address[l_mbaPosition],
+ l_mbsfir_mask_and);
+ if(l_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+
+
+ //************************************************
+ // DEBUG: read them all back to verify
+ l_rc = fapiGetScom_w_retry(l_targetCentaur,
+ l_mbsfir_action0_address[l_mbaPosition],
+ l_mbsfir_action0);
+ if(l_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+
+ l_rc = fapiGetScom_w_retry(l_targetCentaur,
+ l_mbsfir_action1_address[l_mbaPosition],
+ l_mbsfir_action1);
+ if(l_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+
+ l_rc = fapiGetScom_w_retry(l_targetCentaur,
+ l_mbsfir_mask_address[l_mbaPosition],
+ l_mbsfir_mask);
+ if(l_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+
+ //************************************************
+
+
+ FAPI_INF("EXIT mss_unmask_draminit_training_advanced_errors()");
+
+ return i_bad_rc;
+}
+
+
+
+//------------------------------------------------------------------------------
+// mss_unmask_maint_errors
+//------------------------------------------------------------------------------
+
+fapi::ReturnCode mss_unmask_maint_errors(const fapi::Target & i_target,
+ fapi::ReturnCode i_bad_rc )
+
+{
+
+ // Target: Centaur
+
+ FAPI_INF("ENTER mss_unmask_maint_errors()");
+
+ fapi::ReturnCode l_rc;
+ uint32_t l_ecmd_rc = 0;
+ std::vector<fapi::Target> l_mbaChiplets;
+ uint8_t l_mbaPosition; // 0 = mba01, 1 = mba23
+
+ ecmdDataBufferBase l_mbacalfir_mask(64);
+ ecmdDataBufferBase l_mbacalfir_mask_and(64);
+
+ ecmdDataBufferBase l_mbafir_mask(64);
+ ecmdDataBufferBase l_mbafir_mask_and(64);
+
+ ecmdDataBufferBase l_mbaspa_mask(64);
+
+ uint32_t l_mbeccfir_mask_address[2]={
+ // port0/1 port2/3
+ MBS_ECC0_MBECCFIR_MASK_0x02011443, MBS_ECC1_MBECCFIR_MASK_0x02011483};
+
+ uint32_t l_mbeccfir_mask_or_address[2]={
+ // port0/1 port2/3
+ MBS_ECC0_MBECCFIR_MASK_OR_0x02011445, MBS_ECC1_MBECCFIR_MASK_OR_0x02011485};
+
+ uint32_t l_mbeccfir_mask_and_address[2]={
+ // port0/1 port2/3
+ MBS_ECC0_MBECCFIR_MASK_AND_0x02011444,MBS_ECC1_MBECCFIR_MASK_AND_0x02011484};
+
+ uint32_t l_mbeccfir_action0_address[2]={
+ // port0/1 port2/3
+ MBS_ECC0_MBECCFIR_ACTION0_0x02011446, MBS_ECC1_MBECCFIR_ACTION0_0x02011486};
+
+ uint32_t l_mbeccfir_action1_address[2]={
+ // port0/1 port2/3
+ MBS_ECC0_MBECCFIR_ACTION1_0x02011447, MBS_ECC1_MBECCFIR_ACTION1_0x02011487};
+
+ ecmdDataBufferBase l_mbeccfir_mask(64);
+ ecmdDataBufferBase l_mbeccfir_mask_or(64);
+ ecmdDataBufferBase l_mbeccfir_mask_and(64);
+ ecmdDataBufferBase l_mbeccfir_action0(64);
+ ecmdDataBufferBase l_mbeccfir_action1(64);
+
+
+
+ // Get associated functional MBAs on this centaur
+ l_rc = fapiGetChildChiplets(i_target,
+ fapi::TARGET_TYPE_MBA_CHIPLET,
+ l_mbaChiplets);
+ if(l_rc)
+ {
+ FAPI_ERR("Error getting functional MBAs on this Centaur");
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+
+ // Loop through functional MBAs on this Centaur
+ for (uint32_t i=0; i < l_mbaChiplets.size(); i++)
+ {
+
+ // Get MBA position: 0 = mba01, 1 = mba23
+ l_rc = FAPI_ATTR_GET(ATTR_CHIP_UNIT_POS, &l_mbaChiplets[i], l_mbaPosition);
+ if(l_rc)
+ {
+ FAPI_ERR("Error getting MBA position");
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+
+
+
+
+ //*************************
+ //*************************
+ // MBACALFIR
+ //*************************
+ //*************************
+
+
+ // NOTE: In the IPL sequence, mss_unmask_draminit_errors has already been
+ // called, which has already set the MBACALFIR action regs to their runtime
+ // values, so no need to touch the action regs here.
+
+ // NOTE: In the IPL sequence, mss_unmask_draminit_errors,
+ // mss_unmask_draminit_training and mss_unmask_draminit_training_advanced
+ // have already been called, which have already unmasked the approproiate
+ // MBACALFIR errors following mss_draminit, mss_draminit_training, and
+ // mss_unmask_draminit_training_advanced. So all we will do here
+ // is unmask a few more errors that would be considered valid after the
+ // mss_draminit_mc procedure.
+
+ // Read mask
+ l_rc = fapiGetScom_w_retry(l_mbaChiplets[i],
+ MBA01_MBACALFIR_MASK_0x03010403,
+ l_mbacalfir_mask);
+ if(l_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+
+ // TODO: Here is where I could clear bits that were bogus, before I unmask
+ // them. But typically we are expecting the bit set at this point
+ // to be valid errors for PRD to log.
+
+
+ //(Action0, Action1, Mask)
+ //
+ // (0,0,0) = checkstop
+ // (0,1,0) = recoverable error
+ // (1,0,0) = report unused
+ // (1,1,0) = machine check
+ // (x,x,1) = error is masked
+
+ l_ecmd_rc |= l_mbacalfir_mask_and.flushTo1();
+
+ // 1 MBA Nonrecoverable Error channel checkstop unmask
+ l_ecmd_rc |= l_mbacalfir_mask_and.clearBit(1);
+
+ // 2 Refresh Overrun recoverable unmask
+ l_ecmd_rc |= l_mbacalfir_mask_and.clearBit(2);
+
+ // 5 ddr0_cal_timeout_err recoverable unmask
+ l_ecmd_rc |= l_mbacalfir_mask_and.clearBit(5);
+
+ // 6 ddr1_cal_timeout_err recoverable unmask
+ l_ecmd_rc |= l_mbacalfir_mask_and.clearBit(6);
+
+ if(l_ecmd_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+
+ l_rc.setEcmdError(l_ecmd_rc);
+ return l_rc;
+ }
+
+ // Write mask AND
+ l_rc = fapiPutScom_w_retry(l_mbaChiplets[i],
+ MBA01_MBACALFIR_MASK_AND_0x03010404,
+ l_mbacalfir_mask_and);
+ if(l_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+
+ //************************************************
+ // DEBUG: read them all back to verify
+ l_rc = fapiGetScom_w_retry(l_mbaChiplets[i],
+ MBA01_MBACALFIR_MASK_0x03010403,
+ l_mbacalfir_mask);
+ if(l_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+
+ //************************************************
+
+
+ //*************************
+ //*************************
+ // MBAFIR
+ //*************************
+ //*************************
+
+ // NOTE: In the IPL sequence, mss_unmask_ddr_phy_errors has already been
+ // called, which has already set the MBAFIR action regs to their runtime
+ // values, so no need to touch the action regs here.
+
+ // NOTE: In the IPL sequence, mss_unmask_ddr_phy_errors,
+ // has already been called, which has already unmasked the approproiate
+ // MBAFIR errors following mss_ddr_phy_reset. So all we will do here
+ // is unmask a few more errors that would be considered valid after the
+ // mss_draminit_mc procedure.
+
+ // Read mask
+ l_rc = fapiGetScom_w_retry(l_mbaChiplets[i],
+ MBA01_MBAFIRMASK_0x03010603,
+ l_mbafir_mask);
+ if(l_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+
+ // TODO: Here is where I could clear bits that were bogus, before I unmask
+ // them. But typically we are expecting the bit set at this point
+ // to be valid errors for PRD to log.
+
+
+ //(Action0, Action1, Mask)
+ //
+ // (0,0,0) = checkstop
+ // (0,1,0) = recoverable error
+ // (1,0,0) = report unused
+ // (1,1,0) = machine check
+ // (x,x,1) = error is masked
+
+ l_ecmd_rc |= l_mbafir_mask_and.flushTo1();
+
+ // 2 Multi_address_Maint_timeout recoverable unmask
+ l_ecmd_rc |= l_mbafir_mask_and.clearBit(2);
+
+
+ // 7 wrd_caw2_data_ce_ue_err recoverable unmask
+ l_ecmd_rc |= l_mbafir_mask_and.clearBit(7);
+
+ if(l_ecmd_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+
+ l_rc.setEcmdError(l_ecmd_rc);
+ return l_rc;
+ }
+
+ // Write mask AND
+ l_rc = fapiPutScom_w_retry(l_mbaChiplets[i],
+ MBA01_MBAFIRMASK_AND_0x03010604,
+ l_mbafir_mask_and);
+ if(l_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+
+
+ //************************************************
+ // DEBUG: read them all back to verify
+ l_rc = fapiGetScom_w_retry(l_mbaChiplets[i],
+ MBA01_MBAFIRMASK_0x03010603,
+ l_mbafir_mask);
+ if(l_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+
+ //************************************************
+
+
+ //*************************
+ //*************************
+ // MBASPA
+ //*************************
+ //*************************
+
+
+ // Read mask
+ l_rc = fapiGetScom_w_retry(l_mbaChiplets[i],
+ MBA01_MBSPAMSKQ_0x03010614,
+ l_mbaspa_mask);
+ if(l_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+
+ // TODO: Here is where I could clear bits that were bogus, before I unmask
+ // them. But typically we are expecting the bit set at this point
+ // to be valid errors for PRD to log.
+
+
+ // 0 Command_Complete masked (DD1 broken)
+ l_ecmd_rc |= l_mbaspa_mask.setBit(0);
+
+ // 1 Hard_CE_ETE_Attn unmask
+ // NOTE: FW memdiags may want to mask this if they want to wait till
+ // cmd gets to end of rank before getting any attention.
+ // NOTE: Hards counted during super fast read, but can't be called
+ // true hard CEs since super fast read doesn't write back and read again.
+ l_ecmd_rc |= l_mbaspa_mask.clearBit(1);
+
+ // 2 Soft_CE_ETE_Attn unmask
+ // NOTE: FW memdiags may want to mask this if they want to wait till
+ // cmd gets to end of rank before getting any attention.
+ // NOTE: Softs not counted during super fast read.
+ l_ecmd_rc |= l_mbaspa_mask.clearBit(2);
+
+ // 3 Intermittent_ETE_Attn unmask
+ // NOTE: FW memdiags may want to mask this if they want to wait till
+ // cmd gets to end of rank before getting any attention.
+ // NOTE: Intermittents not counted during super fast read.
+ l_ecmd_rc |= l_mbaspa_mask.clearBit(3);
+
+ // 4 RCE_ETE_Attn unmask
+ // NOTE: FW memdiags may want to mask this if they want to wait till
+ // cmd gets to end of rank before getting any attention.
+ l_ecmd_rc |= l_mbaspa_mask.clearBit(4);
+
+ // 5 Emergency_Throttle_Attn masked
+ l_ecmd_rc |= l_mbaspa_mask.setBit(5);
+
+ // 6 Firmware_Attn0 masked
+ l_ecmd_rc |= l_mbaspa_mask.setBit(6);
+
+ // 7 Firmware_Attn1 masked
+ l_ecmd_rc |= l_mbaspa_mask.setBit(7);
+
+ // 8 wat_debug_attn unmask (DD1 workaround)
+ l_ecmd_rc |= l_mbaspa_mask.clearBit(8);
+
+ // 9 Spare_Attn1 masked
+ l_ecmd_rc |= l_mbaspa_mask.setBit(9);
+
+ // 10 MCBIST_Done masked
+ l_ecmd_rc |= l_mbaspa_mask.setBit(10);
+
+ // 11:63 RESERVED not implemented, so won't touch these
+
+
+ if(l_ecmd_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+
+ l_rc.setEcmdError(l_ecmd_rc);
+ return l_rc;
+ }
+
+ // Write mask
+ l_rc = fapiPutScom_w_retry(l_mbaChiplets[i],
+ MBA01_MBSPAMSKQ_0x03010614,
+ l_mbaspa_mask);
+ if(l_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+
+ //************************************************
+ // DEBUG: read them all back to verify
+ l_rc = fapiGetScom_w_retry(l_mbaChiplets[i],
+ MBA01_MBSPAMSKQ_0x03010614,
+ l_mbaspa_mask);
+ if(l_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+ //************************************************
+
+
+
+ //*************************
+ //*************************
+ // MBECCFIR
+ //*************************
+ //*************************
+
+ // Get MBA position: 0 = mba01, 1 = mba23
+ l_rc = FAPI_ATTR_GET(ATTR_CHIP_UNIT_POS, &l_mbaChiplets[i], l_mbaPosition);
+ if(l_rc)
+ {
+ FAPI_ERR("Error getting MBA position");
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+
+ // Read mask
+ l_rc = fapiGetScom_w_retry(i_target,
+ l_mbeccfir_mask_address[l_mbaPosition],
+ l_mbeccfir_mask);
+ if(l_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+
+ // TODO: Here is where I could clear bits that were bogus, before I unmask
+ // them. But typically we are expecting the bit set at this point
+ // to be valid errors for PRD to log.
+
+
+ //(Action0, Action1, Mask)
+ //
+ // (0,0,0) = checkstop
+ // (0,1,0) = recoverable error
+ // (1,0,0) = report unused
+ // (1,1,0) = machine check
+ // (x,x,1) = error is masked
+
+ l_ecmd_rc |= l_mbeccfir_action0.flushTo0();
+ l_ecmd_rc |= l_mbeccfir_action1.flushTo0();
+ l_ecmd_rc |= l_mbeccfir_mask_or.flushTo0();
+ l_ecmd_rc |= l_mbeccfir_mask_and.flushTo1();
+
+ // 0:7 Memory MPE Rank 0:7 recoverable mask
+ l_ecmd_rc |= l_mbeccfir_action0.clearBit(0,8);
+ l_ecmd_rc |= l_mbeccfir_action1.setBit(0,8);
+ l_ecmd_rc |= l_mbeccfir_mask_or.setBit(0,8);
+
+ // 8:15 Reserved recoverable mask (forever)
+ l_ecmd_rc |= l_mbeccfir_action0.clearBit(8,8);
+ l_ecmd_rc |= l_mbeccfir_action1.setBit(8,8);
+ l_ecmd_rc |= l_mbeccfir_mask_or.setBit(8,8);
+
+ // 16 Memory NCE recoverable mask
+ l_ecmd_rc |= l_mbeccfir_action0.clearBit(16);
+ l_ecmd_rc |= l_mbeccfir_action1.setBit(16);
+ l_ecmd_rc |= l_mbeccfir_mask_or.setBit(16);
+
+ // 17 Memory RCE recoverable mask
+ l_ecmd_rc |= l_mbeccfir_action0.clearBit(17);
+ l_ecmd_rc |= l_mbeccfir_action1.setBit(17);
+ l_ecmd_rc |= l_mbeccfir_mask_or.setBit(17);
+
+ // 18 Memory SUE recoverable mask (forever)
+ l_ecmd_rc |= l_mbeccfir_action0.clearBit(18);
+ l_ecmd_rc |= l_mbeccfir_action1.setBit(18);
+ l_ecmd_rc |= l_mbeccfir_mask_or.setBit(18);
+
+ // 19 Memory UE recoverable mask
+ l_ecmd_rc |= l_mbeccfir_action0.clearBit(19);
+ l_ecmd_rc |= l_mbeccfir_action1.setBit(19);
+ l_ecmd_rc |= l_mbeccfir_mask_or.setBit(19);
+
+ // 20:27 Maint MPE Rank 0:7 recoverable unmask
+ // NOTE: FW memdiags may want to mask this if they want to wait till
+ // cmd gets to end of rank before getting any attention.
+ l_ecmd_rc |= l_mbeccfir_action0.clearBit(20,8);
+ l_ecmd_rc |= l_mbeccfir_action1.setBit(20,8);
+ l_ecmd_rc |= l_mbeccfir_mask_and.clearBit(20,8);
+
+ // 28:35 Reserved recoverable mask (forever)
+ l_ecmd_rc |= l_mbeccfir_action0.clearBit(28,8);
+ l_ecmd_rc |= l_mbeccfir_action1.setBit(28,8);
+ l_ecmd_rc |= l_mbeccfir_mask_or.setBit(28,8);
+
+ // 36 Maintenance NCE recoverable mask (tbd)
+ l_ecmd_rc |= l_mbeccfir_action0.clearBit(36);
+ l_ecmd_rc |= l_mbeccfir_action1.setBit(36);
+ l_ecmd_rc |= l_mbeccfir_mask_or.setBit(36);
+
+ // 37 Maintenance SCE recoverable mask (tbd)
+ l_ecmd_rc |= l_mbeccfir_action0.clearBit(37);
+ l_ecmd_rc |= l_mbeccfir_action1.setBit(37);
+ l_ecmd_rc |= l_mbeccfir_mask_or.setBit(37);
+
+ // 38 Maintenance MCE recoverable mask (tbd)
+ l_ecmd_rc |= l_mbeccfir_action0.clearBit(38);
+ l_ecmd_rc |= l_mbeccfir_action1.setBit(38);
+ l_ecmd_rc |= l_mbeccfir_mask_or.setBit(38);
+
+ // 39 Maintenance RCE recoverable mask (tbd)
+ l_ecmd_rc |= l_mbeccfir_action0.clearBit(39);
+ l_ecmd_rc |= l_mbeccfir_action1.setBit(39);
+ l_ecmd_rc |= l_mbeccfir_mask_or.setBit(39);
+
+ // 40 Maintenance SUE recoverable mask (forever)
+ l_ecmd_rc |= l_mbeccfir_action0.clearBit(40);
+ l_ecmd_rc |= l_mbeccfir_action1.setBit(40);
+ l_ecmd_rc |= l_mbeccfir_mask_or.setBit(40);
+
+ // 41 Maintenance UE recoverable unmask (tbd)
+ // NOTE: FW memdiags may want to mask this if they want to wait till
+ // cmd gets to end of rank before getting any attention.
+ l_ecmd_rc |= l_mbeccfir_action0.clearBit(41);
+ l_ecmd_rc |= l_mbeccfir_action1.setBit(41);
+ l_ecmd_rc |= l_mbeccfir_mask_and.clearBit(41);
+
+ // 42 MPE during maintenance mark mode recoverable mask (forever)
+ l_ecmd_rc |= l_mbeccfir_action0.clearBit(42);
+ l_ecmd_rc |= l_mbeccfir_action1.setBit(42);
+ l_ecmd_rc |= l_mbeccfir_mask_or.setBit(42);
+
+ // 43 Prefetch Memory UE recoverable mask
+ l_ecmd_rc |= l_mbeccfir_action0.clearBit(43);
+ l_ecmd_rc |= l_mbeccfir_action1.setBit(43);
+ l_ecmd_rc |= l_mbeccfir_mask_or.setBit(43);
+
+ // 44 Memory RCD parity error recoverable mask (forever)
+ l_ecmd_rc |= l_mbeccfir_action0.clearBit(44);
+ l_ecmd_rc |= l_mbeccfir_action1.setBit(44);
+ l_ecmd_rc |= l_mbeccfir_mask_or.setBit(44);
+
+ // 45 Maint RCD parity error. recoverable mask (forever)
+ l_ecmd_rc |= l_mbeccfir_action0.clearBit(45);
+ l_ecmd_rc |= l_mbeccfir_action1.setBit(45);
+ l_ecmd_rc |= l_mbeccfir_mask_or.setBit(45);
+
+ // 46 Recoverable reg parity recoverable unmask
+ l_ecmd_rc |= l_mbeccfir_action0.clearBit(46);
+ l_ecmd_rc |= l_mbeccfir_action1.setBit(46);
+ l_ecmd_rc |= l_mbeccfir_mask_and.clearBit(46);
+
+
+ // 47 Unrecoverable reg parity channel checkstop unmask
+ l_ecmd_rc |= l_mbeccfir_action0.clearBit(47);
+ l_ecmd_rc |= l_mbeccfir_action1.clearBit(47);
+ l_ecmd_rc |= l_mbeccfir_mask_and.clearBit(47);
+
+ // 48 Maskable reg parity error recoverable mask (forever)
+ l_ecmd_rc |= l_mbeccfir_action0.clearBit(48);
+ l_ecmd_rc |= l_mbeccfir_action1.setBit(48);
+ l_ecmd_rc |= l_mbeccfir_mask_or.setBit(48);
+
+ // 49 ecc datapath parity error channel checkstop unmask
+ l_ecmd_rc |= l_mbeccfir_action0.clearBit(49);
+ l_ecmd_rc |= l_mbeccfir_action1.clearBit(49);
+ l_ecmd_rc |= l_mbeccfir_mask_and.clearBit(49);
+
+ // 50 internal scom error recovereble mask (tbd)
+ l_ecmd_rc |= l_mbeccfir_action0.clearBit(50);
+ l_ecmd_rc |= l_mbeccfir_action1.setBit(50);
+ l_ecmd_rc |= l_mbeccfir_mask_or.setBit(50);
+
+ // 51 internal scom error clone recovereble mask (tbd)
+ l_ecmd_rc |= l_mbeccfir_action0.clearBit(51);
+ l_ecmd_rc |= l_mbeccfir_action1.setBit(51);
+ l_ecmd_rc |= l_mbeccfir_mask_or.setBit(51);
+
+ // 52:63 Reserved not implemented, so won't touch these
+
+
+
+
+ if(l_ecmd_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+
+ l_rc.setEcmdError(l_ecmd_rc);
+ return l_rc;
+ }
+
+ // Write action0
+ l_rc = fapiPutScom_w_retry(i_target,
+ l_mbeccfir_action0_address[l_mbaPosition],
+ l_mbeccfir_action0);
+ if(l_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+
+ // Write action1
+ l_rc = fapiPutScom_w_retry(i_target,
+ l_mbeccfir_action1_address[l_mbaPosition],
+ l_mbeccfir_action1);
+ if(l_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+
+
+ // Write mask OR
+ l_rc = fapiPutScom_w_retry(i_target,
+ l_mbeccfir_mask_or_address[l_mbaPosition],
+ l_mbeccfir_mask_or);
+ if(l_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+
+ // Write mask AND
+ l_rc = fapiPutScom_w_retry(i_target,
+ l_mbeccfir_mask_and_address[l_mbaPosition],
+ l_mbeccfir_mask_and);
+ if(l_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+
+
+ //************************************************
+ // DEBUG: read them all back to verify
+ l_rc = fapiGetScom_w_retry(i_target,
+ l_mbeccfir_action0_address[l_mbaPosition],
+ l_mbeccfir_action0);
+ if(l_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+
+ l_rc = fapiGetScom_w_retry(i_target,
+ l_mbeccfir_action1_address[l_mbaPosition],
+ l_mbeccfir_action1);
+ if(l_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+
+ l_rc = fapiGetScom_w_retry(i_target,
+ l_mbeccfir_mask_address[l_mbaPosition],
+ l_mbeccfir_mask);
+ if(l_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+
+ //************************************************
+
+ } // End for loop through functional MBAs on this Centaur
+
+ FAPI_INF("EXIT mss_unmask_maint_errors()");
+
+ return i_bad_rc;
+}
+
+
+
+
+//------------------------------------------------------------------------------
+// mss_unmask_fetch_errors
+//------------------------------------------------------------------------------
+
+fapi::ReturnCode mss_unmask_fetch_errors(const fapi::Target & i_target,
+ fapi::ReturnCode i_bad_rc )
+
+{
+
+ // Target: Centaur
+
+ FAPI_INF("ENTER mss_unmask_fetch_errors()");
+
+ fapi::ReturnCode l_rc;
+ uint32_t l_ecmd_rc = 0;
+
+
+ //*************************
+ //*************************
+ // SCAC_LFIR
+ //*************************
+ //*************************
+
+ ecmdDataBufferBase l_scac_lfir_mask(64);
+ ecmdDataBufferBase l_scac_lfir_mask_or(64);
+ ecmdDataBufferBase l_scac_lfir_mask_and(64);
+ ecmdDataBufferBase l_scac_lfir_action0(64);
+ ecmdDataBufferBase l_scac_lfir_action1(64);
+
+ // Read mask
+ l_rc = fapiGetScom_w_retry(i_target, SCAC_FIRMASK_0x020115C3, l_scac_lfir_mask);
+ if(l_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+
+ // TODO: Here is where I could clear bits that were bogus, before I unmask
+ // them. But typically we are expecting the bit set at this point
+ // to be valid errors for PRD to log.
+
+
+ //(Action0, Action1, Mask)
+ //
+ // (0,0,0) = checkstop
+ // (0,1,0) = recoverable error
+ // (1,0,0) = report unused
+ // (1,1,0) = machine check
+ // (x,x,1) = error is masked
+
+ l_ecmd_rc |= l_scac_lfir_action0.flushTo0();
+ l_ecmd_rc |= l_scac_lfir_action1.flushTo0();
+ l_ecmd_rc |= l_scac_lfir_mask_or.flushTo0();
+ l_ecmd_rc |= l_scac_lfir_mask_and.flushTo1();
+
+ // 0 I2CMInvAddr recoverable masked (forever)
+ l_ecmd_rc |= l_scac_lfir_action0.clearBit(0);
+ l_ecmd_rc |= l_scac_lfir_action1.setBit(0);
+ l_ecmd_rc |= l_scac_lfir_mask_or.setBit(0);
+
+ // 1 I2CMInvWrite recoverable masked (forever)
+ l_ecmd_rc |= l_scac_lfir_action0.clearBit(1);
+ l_ecmd_rc |= l_scac_lfir_action1.setBit(1);
+ l_ecmd_rc |= l_scac_lfir_mask_or.setBit(1);
+
+ // 2 I2CMInvRead recoverable masked (forever)
+ l_ecmd_rc |= l_scac_lfir_action0.clearBit(2);
+ l_ecmd_rc |= l_scac_lfir_action1.setBit(2);
+ l_ecmd_rc |= l_scac_lfir_mask_or.setBit(2);
+
+ // 3 I2CMApar recoverable masked (forever)
+ l_ecmd_rc |= l_scac_lfir_action0.clearBit(3);
+ l_ecmd_rc |= l_scac_lfir_action1.setBit(3);
+ l_ecmd_rc |= l_scac_lfir_mask_or.setBit(3);
+
+ // 4 I2CMPar recoverable masked (forever)
+ l_ecmd_rc |= l_scac_lfir_action0.clearBit(4);
+ l_ecmd_rc |= l_scac_lfir_action1.setBit(4);
+ l_ecmd_rc |= l_scac_lfir_mask_or.setBit(4);
+
+ // 5 I2CMLBPar recoverable masked (forever)
+ l_ecmd_rc |= l_scac_lfir_action0.clearBit(5);
+ l_ecmd_rc |= l_scac_lfir_action1.setBit(5);
+ l_ecmd_rc |= l_scac_lfir_mask_or.setBit(5);
+
+ // 6:9 Expansion recoverable masked (forever)
+ l_ecmd_rc |= l_scac_lfir_action0.clearBit(6,4);
+ l_ecmd_rc |= l_scac_lfir_action1.setBit(6,4);
+ l_ecmd_rc |= l_scac_lfir_mask_or.setBit(6,4);
+
+ // 10 I2CMInvCmd recoverable masked (forever)
+ l_ecmd_rc |= l_scac_lfir_action0.clearBit(10);
+ l_ecmd_rc |= l_scac_lfir_action1.setBit(10);
+ l_ecmd_rc |= l_scac_lfir_mask_or.setBit(10);
+
+ // 11 I2CMPErr recoverable masked (forever)
+ l_ecmd_rc |= l_scac_lfir_action0.clearBit(11);
+ l_ecmd_rc |= l_scac_lfir_action1.setBit(11);
+ l_ecmd_rc |= l_scac_lfir_mask_or.setBit(11);
+
+ // 12 I2CMOverrun recoverable masked (forever)
+ l_ecmd_rc |= l_scac_lfir_action0.clearBit(12);
+ l_ecmd_rc |= l_scac_lfir_action1.setBit(12);
+ l_ecmd_rc |= l_scac_lfir_mask_or.setBit(12);
+
+ // 13 I2CMAccess recoverable masked (forever)
+ l_ecmd_rc |= l_scac_lfir_action0.clearBit(13);
+ l_ecmd_rc |= l_scac_lfir_action1.setBit(13);
+ l_ecmd_rc |= l_scac_lfir_mask_or.setBit(13);
+
+ // 14 I2CMArb recoverable masked (forever)
+ l_ecmd_rc |= l_scac_lfir_action0.clearBit(14);
+ l_ecmd_rc |= l_scac_lfir_action1.setBit(14);
+ l_ecmd_rc |= l_scac_lfir_mask_or.setBit(14);
+
+ // 15 I2CMNack recoverable masked (forever)
+ l_ecmd_rc |= l_scac_lfir_action0.clearBit(15);
+ l_ecmd_rc |= l_scac_lfir_action1.setBit(15);
+ l_ecmd_rc |= l_scac_lfir_mask_or.setBit(15);
+
+ // 16 I2CMStop recoverable masked (forever)
+ l_ecmd_rc |= l_scac_lfir_action0.clearBit(16);
+ l_ecmd_rc |= l_scac_lfir_action1.setBit(16);
+ l_ecmd_rc |= l_scac_lfir_mask_or.setBit(16);
+
+ // 17 LocalPib1 recoverable masked (forever)
+ l_ecmd_rc |= l_scac_lfir_action0.clearBit(17);
+ l_ecmd_rc |= l_scac_lfir_action1.setBit(17);
+ l_ecmd_rc |= l_scac_lfir_mask_or.setBit(17);
+
+ // 18 LocalPib2 recoverable masked (forever)
+ l_ecmd_rc |= l_scac_lfir_action0.clearBit(18);
+ l_ecmd_rc |= l_scac_lfir_action1.setBit(18);
+ l_ecmd_rc |= l_scac_lfir_mask_or.setBit(18);
+
+ // 19 LocalPib3 recoverable masked (forever)
+ l_ecmd_rc |= l_scac_lfir_action0.clearBit(19);
+ l_ecmd_rc |= l_scac_lfir_action1.setBit(19);
+ l_ecmd_rc |= l_scac_lfir_mask_or.setBit(19);
+
+ // 20 LocalPib4 recoverable masked (forever)
+ l_ecmd_rc |= l_scac_lfir_action0.clearBit(20);
+ l_ecmd_rc |= l_scac_lfir_action1.setBit(20);
+ l_ecmd_rc |= l_scac_lfir_mask_or.setBit(20);
+
+ // 21 LocalPib5 recoverable masked (forever)
+ l_ecmd_rc |= l_scac_lfir_action0.clearBit(21);
+ l_ecmd_rc |= l_scac_lfir_action1.setBit(21);
+ l_ecmd_rc |= l_scac_lfir_mask_or.setBit(21);
+
+ // 22 LocalPib6 recoverable masked (forever)
+ l_ecmd_rc |= l_scac_lfir_action0.clearBit(22);
+ l_ecmd_rc |= l_scac_lfir_action1.setBit(22);
+ l_ecmd_rc |= l_scac_lfir_mask_or.setBit(22);
+
+ // 23 LocalPib7 recoverable masked (forever)
+ l_ecmd_rc |= l_scac_lfir_action0.clearBit(23);
+ l_ecmd_rc |= l_scac_lfir_action1.setBit(23);
+ l_ecmd_rc |= l_scac_lfir_mask_or.setBit(23);
+
+ // 24 StallError recoverable masked (forever)
+ l_ecmd_rc |= l_scac_lfir_action0.clearBit(24);
+ l_ecmd_rc |= l_scac_lfir_action1.setBit(24);
+ l_ecmd_rc |= l_scac_lfir_mask_or.setBit(24);
+
+ // 25 RegParErr channel checkstop unmask
+ l_ecmd_rc |= l_scac_lfir_action0.clearBit(25);
+ l_ecmd_rc |= l_scac_lfir_action1.clearBit(25);
+ l_ecmd_rc |= l_scac_lfir_mask_and.clearBit(25);
+
+ // 26 RegParErrX channel checkstop unmask
+ l_ecmd_rc |= l_scac_lfir_action0.clearBit(26);
+ l_ecmd_rc |= l_scac_lfir_action1.clearBit(26);
+ l_ecmd_rc |= l_scac_lfir_mask_and.clearBit(26);
+
+ // 27:31 Reserved recoverable masked (forever)
+ l_ecmd_rc |= l_scac_lfir_action0.clearBit(27,5);
+ l_ecmd_rc |= l_scac_lfir_action1.setBit(27,5);
+ l_ecmd_rc |= l_scac_lfir_mask_or.setBit(27,5);
+
+ // 32 SMErr recoverable unmask
+ l_ecmd_rc |= l_scac_lfir_action0.clearBit(32);
+ l_ecmd_rc |= l_scac_lfir_action1.setBit(32);
+ l_ecmd_rc |= l_scac_lfir_mask_and.clearBit(32);
+
+ // 33 RegAccErr recoverable unmask
+ l_ecmd_rc |= l_scac_lfir_action0.clearBit(33);
+ l_ecmd_rc |= l_scac_lfir_action1.setBit(33);
+ l_ecmd_rc |= l_scac_lfir_mask_and.clearBit(33);
+
+ // 34 ResetErr recoverable masked (forever)
+ l_ecmd_rc |= l_scac_lfir_action0.clearBit(34);
+ l_ecmd_rc |= l_scac_lfir_action1.setBit(34);
+ l_ecmd_rc |= l_scac_lfir_mask_or.setBit(34);
+
+ // 35 internal_scom_error recoverable masked (tbd)
+ l_ecmd_rc |= l_scac_lfir_action0.clearBit(35);
+ l_ecmd_rc |= l_scac_lfir_action1.setBit(35);
+ l_ecmd_rc |= l_scac_lfir_mask_or.setBit(35);
+
+ // 36 internal_scom_error_clone recoverable masked (tbd)
+ l_ecmd_rc |= l_scac_lfir_action0.clearBit(36);
+ l_ecmd_rc |= l_scac_lfir_action1.setBit(36);
+ l_ecmd_rc |= l_scac_lfir_mask_or.setBit(36);
+
+ // 37:63 Reserved
+ // Can we write to these bits?
+
+
+ if(l_ecmd_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+
+ l_rc.setEcmdError(l_ecmd_rc);
+ return l_rc;
+ }
+
+ // Write action0
+ l_rc = fapiPutScom_w_retry(i_target, SCAC_FIRACTION0_0x020115C6, l_scac_lfir_action0);
+ if(l_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+
+ // Write action1
+ l_rc = fapiPutScom_w_retry(i_target, SCAC_FIRACTION1_0x020115C7, l_scac_lfir_action1);
+ if(l_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+
+
+ // Write mask OR
+ l_rc = fapiPutScom_w_retry(i_target, SCAC_FIRMASK_OR_0x020115C5, l_scac_lfir_mask_or);
+ if(l_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+
+ // Write mask AND
+ l_rc = fapiPutScom_w_retry(i_target, SCAC_FIRMASK_AND_0x020115C4, l_scac_lfir_mask_and);
+ if(l_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+
+
+
+ //************************************************
+ // DEBUG: read them all back to verify
+ l_rc = fapiGetScom_w_retry(i_target, SCAC_FIRACTION0_0x020115C6, l_scac_lfir_action0);
+ if(l_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+ l_rc = fapiGetScom_w_retry(i_target, SCAC_FIRACTION1_0x020115C7, l_scac_lfir_action1);
+ if(l_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+ l_rc = fapiGetScom_w_retry(i_target, SCAC_FIRMASK_0x020115C3, l_scac_lfir_mask);
+ if(l_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+
+ //************************************************
+
+
+ //*************************
+ //*************************
+ // MBS_FIR_REG
+ //*************************
+ //*************************
+
+
+ // NOTE: In the IPL sequence, mss_unmask_inband_errors has already been
+ // called, which has already set the MBS_FIR_REG action regs to their
+ // runtime values, so no need to touch the action regs here.
+
+ // NOTE: In the IPL sequence, mss_unmask_inband_errors,
+ // has already been called, which has already unmasked the approproiate
+ // MBS_FIR_REG errors following mss_unmask_inband_errors. So all we will do
+ // here is unmask errors requiring mainline traffic which would be
+ // considered valid after the mss_thermal_init procedure.
+
+
+ ecmdDataBufferBase l_mbs_fir_mask(64);
+ ecmdDataBufferBase l_mbs_fir_mask_and(64);
+
+ // Read mask
+ l_rc = fapiGetScom_w_retry(i_target, MBS_FIR_MASK_REG_0x02011403, l_mbs_fir_mask);
+ if(l_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+
+ // TODO: Here is where I could clear bits that were bogus, before I unmask
+ // them. But typically we are expecting the bit set at this point
+ // to be valid errors for PRD to log.
+
+ l_ecmd_rc |= l_mbs_fir_mask_and.flushTo1();
+
+ // 2 invalid_address_error channel checkstop unmask
+ l_ecmd_rc |= l_mbs_fir_mask_and.clearBit(2);
+
+ // 3 external_timeout channel checkstop unmask
+ l_ecmd_rc |= l_mbs_fir_mask_and.clearBit(3);
+
+ // 4 internal_timeout channel checkstop unmask
+ l_ecmd_rc |= l_mbs_fir_mask_and.clearBit(4);
+
+ // 9 cache_srw_ce recoverable unmask
+ l_ecmd_rc |= l_mbs_fir_mask_and.clearBit(9);
+
+ // 10 cache_srw_ue recoverable unmask
+ l_ecmd_rc |= l_mbs_fir_mask_and.clearBit(10);
+
+ // 12 cache_co_ce recoverable unmask
+ l_ecmd_rc |= l_mbs_fir_mask_and.clearBit(12);
+
+ // 13 cache_co_ue recoverable unmask
+ l_ecmd_rc |= l_mbs_fir_mask_and.clearBit(13);
+
+ // 15 dir_ce recoverable unmask
+ l_ecmd_rc |= l_mbs_fir_mask_and.clearBit(15);
+
+ // 16 dir_ue channel checkstop unmask
+ l_ecmd_rc |= l_mbs_fir_mask_and.clearBit(16);
+
+ // 18 dir_all_members_deleted channel checkstop unmask
+ l_ecmd_rc |= l_mbs_fir_mask_and.clearBit(18);
+
+ // 19 lru_error recoverable unmask
+ l_ecmd_rc |= l_mbs_fir_mask_and.clearBit(19);
+
+ // 20 eDRAM error channel checkstop unmask
+ l_ecmd_rc |= l_mbs_fir_mask_and.clearBit(20);
+
+ // 26 srb_buffer_ce recoverable unmask
+ l_ecmd_rc |= l_mbs_fir_mask_and.clearBit(26);
+
+ // 27 srb_buffer_ue recoverable unmask
+ l_ecmd_rc |= l_mbs_fir_mask_and.clearBit(27);
+
+ if(l_ecmd_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+
+ l_rc.setEcmdError(l_ecmd_rc);
+ return l_rc;
+ }
+
+ // Write mask AND
+ l_rc = fapiPutScom_w_retry(i_target, MBS_FIR_MASK_REG_AND_0x02011404, l_mbs_fir_mask_and);
+ if(l_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+
+
+ //************************************************
+ // DEBUG: read them all back to verify
+ l_rc = fapiGetScom_w_retry(i_target, MBS_FIR_MASK_REG_0x02011403, l_mbs_fir_mask);
+ if(l_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+
+ //************************************************
+
+
+ //*************************
+ //*************************
+ // MBECCFIR
+ //*************************
+ //*************************
+
+ std::vector<fapi::Target> l_mbaChiplets;
+ uint8_t l_mbaPosition; // 0 = mba01, 1 = mba23
+
+
+ uint32_t l_mbeccfir_mask_address[2]={
+ // port0/1 port2/3
+ MBS_ECC0_MBECCFIR_MASK_0x02011443,MBS_ECC1_MBECCFIR_MASK_0x02011483};
+
+ uint32_t l_mbeccfir_mask_and_address[2]={
+ // port0/1 port2/3
+ MBS_ECC0_MBECCFIR_MASK_AND_0x02011444,MBS_ECC1_MBECCFIR_MASK_AND_0x02011484};
+
+ ecmdDataBufferBase l_mbeccfir_mask(64);
+ ecmdDataBufferBase l_mbeccfir_mask_and(64);
+
+
+ // Get associated functional MBAs on this centaur
+ l_rc = fapiGetChildChiplets(i_target,
+ fapi::TARGET_TYPE_MBA_CHIPLET,
+ l_mbaChiplets);
+ if(l_rc)
+ {
+ FAPI_ERR("Error getting functional MBAs on this Centaur");
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+
+ // Loop through functional MBAs on this Centaur
+ for (uint32_t i=0; i < l_mbaChiplets.size(); i++)
+ {
+
+ // Get MBA position: 0 = mba01, 1 = mba23
+ l_rc = FAPI_ATTR_GET(ATTR_CHIP_UNIT_POS, &l_mbaChiplets[i], l_mbaPosition);
+ if(l_rc)
+ {
+ FAPI_ERR("Error getting MBA position");
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+
+ // Read mask
+ l_rc = fapiGetScom_w_retry(i_target,
+ l_mbeccfir_mask_address[l_mbaPosition],
+ l_mbeccfir_mask);
+ if(l_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+
+ // TODO: Here is where I could clear bits that were bogus, before I unmask
+ // them. But typically we are expecting the bit set at this point
+ // to be valid errors for PRD to log.
+
+ // NOTE: In the IPL sequence, mss_unmask_maint_errors has already been
+ // called, which has already set the MBECCFIR action regs to their runtime
+ // values, so no need to touch the action regs here.
+
+ // NOTE: In the IPL sequence, mss_unmask_maint_errors,
+ // has already been called, which has already unmasked the approproiate
+ // MBECCFIR errors following mss_unmask_maint_errors. So all we will do
+ // here is unmask errors requiring mainline traffic which would be
+ // considered valid after the mss_thermal_init procedure.
+
+ l_ecmd_rc |= l_mbeccfir_mask_and.flushTo1();
+
+ // 0:7 Memory MPE Rank 0:7 recoverable unmask
+ l_ecmd_rc |= l_mbeccfir_mask_and.clearBit(0,8);
+
+ // 16 Memory NCE recoverable unmask
+ l_ecmd_rc |= l_mbeccfir_mask_and.clearBit(16);
+
+ // 17 Memory RCE recoverable unmask
+ l_ecmd_rc |= l_mbeccfir_mask_and.clearBit(17);
+
+ // 19 Memory UE recoverable unmask
+ l_ecmd_rc |= l_mbeccfir_mask_and.clearBit(19);
+
+ // 43 Prefetch Memory UE recoverable unmask
+ l_ecmd_rc |= l_mbeccfir_mask_and.clearBit(43);
+
+
+ if(l_ecmd_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+
+ l_rc.setEcmdError(l_ecmd_rc);
+ return l_rc;
+ }
+
+ // Write mask AND
+ l_rc = fapiPutScom_w_retry(i_target,
+ l_mbeccfir_mask_and_address[l_mbaPosition],
+ l_mbeccfir_mask_and);
+ if(l_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+
+ //************************************************
+ // DEBUG: read them all back to verify
+ l_rc = fapiGetScom_w_retry(i_target,
+ l_mbeccfir_mask_address[l_mbaPosition],
+ l_mbeccfir_mask);
+ if(l_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+
+ //************************************************
+ }
+
+
+ //*************************
+ //*************************
+ // MBACALFIR
+ //*************************
+ //*************************
+
+ ecmdDataBufferBase l_mbacalfir_mask(64);
+ ecmdDataBufferBase l_mbacalfir_mask_and(64);
+
+ // NOTE: In the IPL sequence, mss_unmask_draminit_errors has already been
+ // called, which has already set the MBACALFIR action regs to their runtime
+ // values, so no need to touch the action regs here.
+
+ // NOTE: In the IPL sequence, various bits have already been unmasked
+ // after the approproiate procedures. So all we will do here is unmask
+ // errors requiring mainline traffic which would be considered valid after
+ // the mss_thermal_init procedure.
+
+ // Loop through functional MBAs on this Centaur
+ for (uint32_t i=0; i < l_mbaChiplets.size(); i++)
+ {
+
+ // Read mask
+ l_rc = fapiGetScom_w_retry(l_mbaChiplets[i],
+ MBA01_MBACALFIR_MASK_0x03010403,
+ l_mbacalfir_mask);
+ if(l_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+
+ // TODO: Here is where I could clear bits that were bogus, before I unmask
+ // them. But typically we are expecting the bit set at this point
+ // to be valid errors for PRD to log.
+
+ l_ecmd_rc |= l_mbacalfir_mask_and.flushTo1();
+
+ // 9 mba_wrd ue recoverable unmask
+ l_ecmd_rc |= l_mbacalfir_mask_and.clearBit(9);
+
+ // 10 mba_wrd ce recoverable unmask
+ l_ecmd_rc |= l_mbacalfir_mask_and.clearBit(10);
+
+ // 14 wrq_data_ce recoverable unmask
+ l_ecmd_rc |= l_mbacalfir_mask_and.clearBit(14);
+
+ // 15 wrq_data_ue recoverable unmask
+ l_ecmd_rc |= l_mbacalfir_mask_and.clearBit(15);
+
+ if(l_ecmd_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+
+ l_rc.setEcmdError(l_ecmd_rc);
+ return l_rc;
+ }
+
+ // Write mask AND
+ l_rc = fapiPutScom_w_retry(l_mbaChiplets[i],
+ MBA01_MBACALFIR_MASK_AND_0x03010404,
+ l_mbacalfir_mask_and);
+ if(l_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+
+
+ //************************************************
+ // DEBUG: read them all back to verify
+ l_rc = fapiGetScom_w_retry(l_mbaChiplets[i],
+ MBA01_MBACALFIR_MASK_0x03010403,
+ l_mbacalfir_mask);
+ if(l_rc)
+ {
+ // Log passed in error before returning with new error
+ if (i_bad_rc) fapiLogError(i_bad_rc);
+ return l_rc;
+ }
+
+ //************************************************
+ }
+
+
+
+
+ FAPI_INF("EXIT mss_unmask_fetch_errors()");
+
+ return i_bad_rc;
+}
+
+//------------------------------------------------------------------------------
+// fapiGetScom_w_retry
+//------------------------------------------------------------------------------
+fapi::ReturnCode fapiGetScom_w_retry(const fapi::Target& i_target,
+ const uint64_t i_address,
+ ecmdDataBufferBase & o_data)
+{
+ fapi::ReturnCode l_rc;
+
+ l_rc = fapiGetScom(i_target, i_address, o_data);
+ if(l_rc)
+ {
+ FAPI_ERR("1st Centaur fapiGetScom failed, so attempting retry.");
+
+ // Log centaur scom error
+ fapiLogError(l_rc);
+
+ // Retry centaur scom with assumption that retry is done via FSI,
+ // which may still work.
+ // NOTE: If scom fail was due to channel fail a retry via FSI may
+ // work. But if scom fail was due to PIB error, retry via FSI may
+ // also fail.
+ l_rc = fapiGetScom(i_target, i_address, o_data);
+ if(l_rc)
+ {
+ FAPI_ERR("fapiGetScom retry via FSI failed.");
+ // Retry didn't work either so give up and pass
+ // back centaur scom error
+ }
+ }
+
+ return l_rc;
+}
+
+
+//------------------------------------------------------------------------------
+// fapiPutScom_w_retry
+//------------------------------------------------------------------------------
+fapi::ReturnCode fapiPutScom_w_retry(const fapi::Target& i_target,
+ const uint64_t i_address,
+ ecmdDataBufferBase & i_data)
+{
+ fapi::ReturnCode l_rc;
+
+ // NOTE: Inband scom device driver takes care of read to special reg after
+ // an inband scom write in order to detect SUE
+ l_rc = fapiPutScom(i_target, i_address, i_data);
+ if(l_rc)
+ {
+ FAPI_ERR("1st Centaur fapiPutScom failed, so attempting retry.");
+
+ // Log centaur scom error
+ fapiLogError(l_rc);
+
+ // Retry centaur scom with assumption that retry is done via FSI,
+ // which may still work.
+ // NOTE: If scom fail was due to channel fail a retry via FSI may
+ // work. But if scom fail was due to PIB error, retry via FSI may
+ // also fail.
+ l_rc = fapiPutScom(i_target, i_address, i_data);
+ if(l_rc)
+ {
+ FAPI_ERR("fapiPutScom retry via FSI failed.");
+ // Retry didn't work either so give up and pass
+ // back centaur scom error
+ }
+ }
+
+ return l_rc;
+}
diff --git a/src/usr/hwpf/hwp/dram_training/mss_unmask_errors.H b/src/usr/hwpf/hwp/dram_training/mss_unmask_errors.H
new file mode 100644
index 000000000..e779b9725
--- /dev/null
+++ b/src/usr/hwpf/hwp/dram_training/mss_unmask_errors.H
@@ -0,0 +1,275 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/hwpf/hwp/dram_training/mss_unmask_errors.H $ */
+/* */
+/* IBM CONFIDENTIAL */
+/* */
+/* COPYRIGHT International Business Machines Corp. 2012 */
+/* */
+/* p1 */
+/* */
+/* Object Code Only (OCO) source materials */
+/* Licensed Internal Code Source Materials */
+/* IBM HostBoot Licensed Internal Code */
+/* */
+/* The source code for this program is not published or otherwise */
+/* divested of its trade secrets, irrespective of what has been */
+/* deposited with the U.S. Copyright Office. */
+/* */
+/* Origin: 30 */
+/* */
+/* IBM_PROLOG_END_TAG */
+// $Id: mss_unmask_errors.H,v 1.1 2012/09/05 21:04:20 gollub Exp $
+//------------------------------------------------------------------------------
+// Don't forget to create CVS comments when you check in your changes!
+//------------------------------------------------------------------------------
+// CHANGE HISTORY:
+//------------------------------------------------------------------------------
+// Version:| Date: | Author: | Comment:
+//---------|----------|---------|-----------------------------------------------
+// 1.1 | 09/05/12 | gollub | Created
+
+#ifndef _MSS_UNMASK_ERRORS_H
+#define _MSS_UNMASK_ERRORS_H
+
+/** @file mss_unmask_errors.H
+ * @brief Utility functions to set action regs and unmask FIR bits
+ * at the end of various mss IPL procedures.
+ */
+
+
+//------------------------------------------------------------------------------
+// Includes
+//------------------------------------------------------------------------------
+
+#include <fapi.H>
+#include <ecmdDataBufferBase.H>
+
+
+
+//------------------------------------------------------------------------------
+// Constants and enums
+//------------------------------------------------------------------------------
+
+
+
+
+
+
+//------------------------------------------------------------------------------
+// mss_unmask_inband_errors
+//------------------------------------------------------------------------------
+
+
+/**
+ * @brief To be called at the end of proc_cen_set_inband_addr.C
+ * Sets action regs and mask settings for inband errors to their
+ * runtime settings.
+ *
+ * @param i_target Centaur target
+ * @param i_bad_rc If proc_cen_set_inband_addr.C already has a bad rc
+ * before it calls this function, we pass it in as
+ * i_bad_rc. If this function gets it's own bad local
+ * l_rc, i_bad_rc will be commited, and l_rc will be
+ * passed back as return value. Else if no l_rc,
+ * i_bad_rc will be be passed back as return value.
+ * @return Non-SUCCESS if i_bad_rc Non_SUCCESS, or if internal function fails,
+ * SUCCESS otherwise.
+ */
+fapi::ReturnCode mss_unmask_inband_errors( const fapi::Target & i_target,
+ fapi::ReturnCode i_bad_rc );
+
+
+//------------------------------------------------------------------------------
+// mss_unmask_ddrphy_errors
+//------------------------------------------------------------------------------
+
+
+/**
+ * @brief To be called at the end of mss_ddr_phy_reset.C.
+ * Sets action regs and mask settings for ddr phy errors to their
+ * runtime settings.
+ *
+ * @param i_target MBA target
+ * @param i_bad_rc If mss_ddr_phy_reset.C already has a bad rc
+ * before it calls this function, we pass it in as
+ * i_bad_rc. If this function gets it's own bad local
+ * l_rc, i_bad_rc will be commited, and l_rc will be
+ * passed back as return value. Else if no l_rc,
+ * i_bad_rc will be be passed back as return value.
+ * @return Non-SUCCESS if i_bad_rc Non_SUCCESS, or if internal function fails,
+ * SUCCESS otherwise.
+ */
+fapi::ReturnCode mss_unmask_ddrphy_errors( const fapi::Target & i_target,
+ fapi::ReturnCode i_bad_rc );
+
+
+//------------------------------------------------------------------------------
+// mss_unmask_draminit_errors
+//------------------------------------------------------------------------------
+
+
+/**
+ * @brief To be called at the end of mss_draminit.C.
+ * Sets MBACALFIR action regs to their runtime settings, and unmasks
+ * errors that are valid for PRD to handle after mss_draminit procedure.
+ *
+ * @param i_target MBA target
+ * @param i_bad_rc If mss_draminit.C already has a bad rc
+ * before it calls this function, we pass it in as
+ * i_bad_rc. If this function gets it's own bad local
+ * l_rc, i_bad_rc will be commited, and l_rc will be
+ * passed back as return value. Else if no l_rc,
+ * i_bad_rc will be be passed back as return value.
+ * @return Non-SUCCESS if i_bad_rc Non_SUCCESS, or if internal function fails,
+ * SUCCESS otherwise.
+ */
+fapi::ReturnCode mss_unmask_draminit_errors( const fapi::Target & i_target,
+ fapi::ReturnCode i_bad_rc );
+
+
+//------------------------------------------------------------------------------
+// mss_unmask_draminit_training_errors
+//------------------------------------------------------------------------------
+
+
+/**
+ * @brief To be called at the end of mss_draminit_training.C.
+ * Unmasks MBACALFIR errors that are valid for PRD to handle after
+ * mss_draminit_training procedure.
+ *
+ * @param i_target MBA target
+ * @param i_bad_rc If mss_draminit_training.C already has a bad rc
+ * before it calls this function, we pass it in as
+ * i_bad_rc. If this function gets it's own bad local
+ * l_rc, i_bad_rc will be commited, and l_rc will be
+ * passed back as return value. Else if no l_rc,
+ * i_bad_rc will be be passed back as return value.
+ * @return Non-SUCCESS if i_bad_rc Non_SUCCESS, or if internal function fails,
+ * SUCCESS otherwise.
+ */
+fapi::ReturnCode mss_unmask_draminit_training_errors(
+ const fapi::Target & i_target,
+ fapi::ReturnCode i_bad_rc );
+
+
+//------------------------------------------------------------------------------
+// mss_unmask_draminit_training_advanced_errors
+//------------------------------------------------------------------------------
+
+
+/**
+ * @brief To be called at the end of mss_draminit_training_advanced.C.
+ * Unmasks MBACALFIR errors that are valid for PRD to handle after
+ * mss_draminit_training_advanced procedure.
+ *
+ * @param i_target MBA target
+ * @param i_bad_rc If mss_draminit_training_advanced.C already has a
+ * bad rc before it calls this function, we pass it in
+ * as i_bad_rc. If this function gets it's own bad
+ * local l_rc, i_bad_rc will be commited, and l_rc will
+ * be passed back as return value. Else if no l_rc,
+ * i_bad_rc will be be passed back as return value.
+ * @return Non-SUCCESS if i_bad_rc Non_SUCCESS, or if internal function fails,
+ * SUCCESS otherwise.
+ */
+fapi::ReturnCode mss_unmask_draminit_training_advanced_errors(
+ const fapi::Target & i_target,
+ fapi::ReturnCode i_bad_rc );
+
+
+//------------------------------------------------------------------------------
+// mss_unmask_maint_errors
+//------------------------------------------------------------------------------
+
+
+/**
+ * @brief To be called at the end of mss_draminit_mc.C.
+ * Sets action regs and unmasks maint errors prior to the maint logic
+ * being used in memdiags so that PRD will be able to handle them
+ * if they happen during memdiags.
+ *
+ * @param i_target MBA target
+ * @param i_bad_rc If mss_draminit_mc already has a
+ * bad rc before it calls this function, we pass it in
+ * as i_bad_rc. If this function gets it's own bad
+ * local l_rc, i_bad_rc will be commited, and l_rc will
+ * be passed back as return value. Else if no l_rc,
+ * i_bad_rc will be be passed back as return value.
+ * @return Non-SUCCESS if i_bad_rc Non_SUCCESS, or if internal function fails,
+ * SUCCESS otherwise.
+ */
+fapi::ReturnCode mss_unmask_maint_errors(const fapi::Target & i_target,
+ fapi::ReturnCode i_bad_rc );
+
+
+//------------------------------------------------------------------------------
+// mss_unmask_fetch_errors
+//------------------------------------------------------------------------------
+
+
+/**
+ * @brief To be called at the end of mss_thermal_init.C.
+ * Sets action regs and unmasks fetch errors prior to the start of
+ * mainline traffic.
+ *
+ * @param i_target Centaur target
+ * @param i_bad_rc If mss_thermal_init already has a
+ * bad rc before it calls this function, we pass it in
+ * as i_bad_rc. If this function gets it's own bad
+ * local l_rc, i_bad_rc will be commited, and l_rc will
+ * be passed back as return value. Else if no l_rc,
+ * i_bad_rc will be be passed back as return value.
+ * @return Non-SUCCESS if i_bad_rc Non_SUCCESS, or if internal function fails,
+ * SUCCESS otherwise.
+ */
+fapi::ReturnCode mss_unmask_fetch_errors(const fapi::Target & i_target,
+ fapi::ReturnCode i_bad_rc );
+
+
+
+//------------------------------------------------------------------------------
+// fapiGetScom_w_retry
+//------------------------------------------------------------------------------
+
+/**
+ * @brief Reads a SCOM register from a Chip and retries once if SCOM fails.
+ * Retry is done with assumption that hostboot will switch from
+ * inband SCOM to FSI, so if inband failed due to channel fail,
+ * FSI may still work.
+ * @param[in] i_target Target to operate on
+ * @param[in] i_address Scom address to read from
+ * @param[out] o_data ecmdDataBufferBase object that holds data read from
+ * address
+ * @return ReturnCode. Zero on success, else platform specified error
+ */
+fapi::ReturnCode fapiGetScom_w_retry(const fapi::Target& i_target,
+ const uint64_t i_address,
+ ecmdDataBufferBase & o_data);
+
+//------------------------------------------------------------------------------
+// fapiPutScom_w_retry
+//------------------------------------------------------------------------------
+
+/**
+ * @brief Writes a SCOM register on a Chip and retries once if SCOM fails.
+ * Retry is done with assumption that hostboot will switch from
+ * inband SCOM to FSI, so if inband failed due to channel fail,
+ * FSI may still work.
+ * @param[in] i_target Target to operate on
+ * @param[in] i_address Scom address to write to
+ * @param[in] i_data ecmdDataBufferBase object that holds data to write into
+ * address
+ * @return ReturnCode. Zero on success, else platform specified error
+ */
+fapi::ReturnCode fapiPutScom_w_retry(const fapi::Target& i_target,
+ const uint64_t i_address,
+ ecmdDataBufferBase & i_data);
+
+
+
+
+
+
+#endif /* _MSS_UNMASK_ERRORS_H */
OpenPOWER on IntegriCloud