diff options
Diffstat (limited to 'src/usr/hwpf/hwp/dram_training')
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 */ |