diff options
author | Thi Tran <thi@us.ibm.com> | 2013-09-16 16:09:48 -0500 |
---|---|---|
committer | A. Patrick Williams III <iawillia@us.ibm.com> | 2013-09-18 10:46:25 -0500 |
commit | 44933fc2a399c991c7ef31b1a29219f808c4395e (patch) | |
tree | f6fa7ad0b47c91bf7d5c37bd88f24fa72654270b /src/usr | |
parent | af0bcac5124a4c54ec38e6d00d14f2cec19d5c77 (diff) | |
download | talos-hostboot-44933fc2a399c991c7ef31b1a29219f808c4395e.tar.gz talos-hostboot-44933fc2a399c991c7ef31b1a29219f808c4395e.zip |
Hostboot - Updated HWPs from defect SW223817 lrdimm supports
Change-Id: I80e5f13a59fb3d1e882435d8a457f3a806885063
CQ: SW223817
Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/6187
Tested-by: Jenkins Server
Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src/usr')
13 files changed, 2930 insertions, 131 deletions
diff --git a/src/usr/hwpf/hwp/centaur_ec_attributes.xml b/src/usr/hwpf/hwp/centaur_ec_attributes.xml index fbf29eb8c..55277dbca 100644 --- a/src/usr/hwpf/hwp/centaur_ec_attributes.xml +++ b/src/usr/hwpf/hwp/centaur_ec_attributes.xml @@ -22,7 +22,7 @@ <!-- IBM_PROLOG_END_TAG --> <attributes> <!-- ********************************************************************* --> - <!-- $Id: centaur_ec_attributes.xml,v 1.7 2013/08/08 14:30:33 yctschan Exp $ --> + <!-- $Id: centaur_ec_attributes.xml,v 1.10 2013/09/11 12:29:40 bwieman Exp $ --> <attribute> <id>ATTR_CENTAUR_EC_ENABLE_TRACE_LCL_CLK_GATE_CTRL</id> <targetType>TARGET_TYPE_MEMBUF_CHIP</targetType> @@ -127,4 +127,76 @@ Controls the ddr_phy_reset procedure. When set to TRUE, the procedure will cont </chip> </chipEcFeature> </attribute> + + <attribute> + <id>ATTR_CENTAUR_EC_ECID_CONTAINS_PORT_LOGIC_BAD_INDICATION</id> + <targetType>TARGET_TYPE_MEMBUF_CHIP</targetType> + <description> + If true then mss_get_cen_ecid reads the ECID bits to determine if + logic on either of the ports are good. For DD2, these bits are not + used for this purpose and so the check is not made. + This is true for Centaur 1.* + </description> + <chipEcFeature> + <chip> + <name>ENUM_ATTR_NAME_CENTAUR</name> + <ec> + <value>0x20</value> + <test>LESS_THAN</test> + </ec> + </chip> + </chipEcFeature> + </attribute> + + <attribute> + <id>ATTR_CENTAUR_EC_MCBIST_RANDOM_DATA_GEN</id> + <targetType>TARGET_TYPE_MEMBUF_CHIP</targetType> + <description> + Set by the platform depending on DD2.x or newer (TRUE), otherwise FALSE. If false, this will enable the power bus ECC and FIFO mode workarounds of DD1.x for Random Data . + </description> + <chipEcFeature> + <chip> + <name>ENUM_ATTR_NAME_CENTAUR</name> + <ec> + <value>0x20</value> + <test>GREATER_THAN_OR_EQUAL</test> + </ec> + </chip> + </chipEcFeature> + </attribute> + + <attribute> + <id>ATTR_CENTAUR_EC_MCBIST_TRAP_RESET</id> + <targetType>TARGET_TYPE_MEMBUF_CHIP</targetType> + <description> + Set by the platform depending on DD2.x or newer (TRUE), otherwise FALSE. If false, work around for error trap reset logic which clears trap registers will be enabled. + </description> + <chipEcFeature> + <chip> + <name>ENUM_ATTR_NAME_CENTAUR</name> + <ec> + <value>0x20</value> + <test>GREATER_THAN_OR_EQUAL</test> + </ec> + </chip> + </chipEcFeature> + </attribute> + + <attribute> + <id>ATTR_CENTAUR_EC_MCBIST_RANDOM_ADDRESS</id> + <targetType>TARGET_TYPE_MEMBUF_CHIP</targetType> + <description> + Set by the platform depending on DD2.x or newer (TRUE), otherwise FALSE. If false, this will enable workaround for start and end counters for Random Addressing. + </description> + <chipEcFeature> + <chip> + <name>ENUM_ATTR_NAME_CENTAUR</name> + <ec> + <value>0x20</value> + <test>GREATER_THAN_OR_EQUAL</test> + </ec> + </chip> + </chipEcFeature> + </attribute> + </attributes> diff --git a/src/usr/hwpf/hwp/dram_training/makefile b/src/usr/hwpf/hwp/dram_training/makefile index 527265eec..93cd54fd5 100644 --- a/src/usr/hwpf/hwp/dram_training/makefile +++ b/src/usr/hwpf/hwp/dram_training/makefile @@ -50,6 +50,7 @@ EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/dram_training/mem_pll_setup EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/dram_training/mss_draminit_trainadv EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/build_winkle_images/p8_slw_build EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/dram_training/mss_dimm_power_test +EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/dram_training/mss_lrdimm_funcs ## NOTE: add new object files when you add a new HWP OBJS = dram_training.o \ @@ -70,7 +71,8 @@ OBJS = dram_training.o \ mss_mcbist_common.o\ hbVddrMsg.o \ mss_mcbist_address.o \ - mss_dimm_power_test.o + mss_dimm_power_test.o \ + mss_lrdimm_funcs.o ## NOTE: add a new directory onto the vpaths when you add a new HWP ##@ VPATH += ${ROOTPATH}/src/usr/hwpf/hwp/??? @@ -83,5 +85,6 @@ VPATH += ${ROOTPATH}/src/usr/hwpf/hwp/dram_training/mem_startclocks VPATH += ${ROOTPATH}/src/usr/hwpf/hwp/dram_training/mss_scominit VPATH += ${ROOTPATH}/src/usr/hwpf/hwp/dram_training/mem_pll_setup VPATH += ${ROOTPATH}/src/usr/hwpf/hwp/dram_training/mss_draminit_trainadv +VPATH += ${ROOTPATH}/src/usr/hwpf/hwp/dram_training/mss_lrdimm_funcs include ${ROOTPATH}/config.mk 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 843c6fc59..741c63394 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 @@ -20,7 +20,7 @@ /* Origin: 30 */ /* */ /* IBM_PROLOG_END_TAG */ -// $Id: mss_draminit.C,v 1.52 2013/08/07 14:31:53 jdsloat Exp $ +// $Id: mss_draminit.C,v 1.56 2013/09/16 13:56:28 bellows Exp $ //------------------------------------------------------------------------------ // Don't forget to create CVS comments when you check in your changes! //------------------------------------------------------------------------------ @@ -28,6 +28,11 @@ //------------------------------------------------------------------------------ // Version:| Author: | Date: | Comment: //---------|----------|---------|----------------------------------------------- +// 1.56 | bellows | 09/16/13| Hostboot compile fix +// 1.55 | kcook | 09/13/13| Updated define FAPI_LRDIMM token. +// 1.54 | kcook | 08/27/13| Removed LRDIMM support to mss_lrdimm_funcs.C. +// | | | Added check for valid rank when flagging address mirroring. +// 1.53 | kcook | 08/16/13| Added LRDIMM support. Use with mss_funcs.C v1.32. // 1.52 | jdsloat | 08/07/13| Added a single rc_num check and edited a debug/error message to make firmware happy. // 1.51 | jdsloat | 08/01/13| Fixed dimm/rank conversion in address mirroring phy setting for a 4 rank dimm scenario // 1.50 | mwuu | 07/17/13| Fixed CS when accessing RCD words on 1 rank RDIMMs @@ -103,6 +108,31 @@ #include <mss_funcs.H> #include "cen_scom_addresses.H" #include <mss_unmask_errors.H> +#include <mss_lrdimm_funcs.H> + + + +#ifndef FAPI_LRDIMM +using namespace fapi; +fapi::ReturnCode mss_lrdimm_rcd_load(Target& i_target, uint32_t port_number, uint32_t& ccs_inst_cnt) +{ + ReturnCode rc; + + FAPI_ERR("Invalid exec of LRDIMM function on %s!", i_target.toEcmdString()); + FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR); + return rc; + +} +ReturnCode mss_lrdimm_mrs_load(Target& i_target, uint32_t i_port_number, uint32_t dimm_number, uint32_t& io_ccs_inst_cnt) +{ + ReturnCode rc; + + FAPI_ERR("Invalid exec of LRDIMM function on %s!", i_target.toEcmdString()); + FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR); + return rc; + +} +#endif //---------------------------------------------------------------------- // Constants @@ -110,6 +140,7 @@ const uint8_t MAX_NUM_DIMMS = 2; const uint8_t MAX_NUM_PORTS = 2; const uint8_t MAX_NUM_RANK_PAIR = 4; +const uint8_t MAX_NUM_LR_RANKS = 8; const uint8_t MRS0_BA = 0; const uint8_t MRS1_BA = 1; const uint8_t MRS2_BA = 2; @@ -310,11 +341,10 @@ ReturnCode mss_draminit_cloned(Target& i_target) ter_dimm_rank = tertiary_ranks_array[rank_pair_group][port_number] - 4*ter_dimm; qua_dimm = (quaternary_ranks_array[rank_pair_group][port_number]) / 4; qua_dimm_rank = quaternary_ranks_array[rank_pair_group][port_number] - 4*qua_dimm; - // Set the rank pairs that will be affected. if ( port_number == 0 ) { - if ( address_mirror_map[port_number][pri_dimm] & (0x08 >> pri_dimm_rank) ) + if ( ( ( address_mirror_map[port_number][pri_dimm] & (0x08 >> pri_dimm_rank) ) ) && (primary_ranks_array[rank_pair_group][port_number] != 0xff ) ) { FAPI_INF( "Address Mirroring on %s PORT%d RANKPAIR%d RANK%d", i_target.toEcmdString(), port_number, rank_pair_group, primary_ranks_array[rank_pair_group][port_number]); bit_position = 2 * rank_pair_group + 48; @@ -325,8 +355,8 @@ ReturnCode mss_draminit_cloned(Target& i_target) rc = fapiPutScom(i_target, DPHY01_DDRPHY_PC_RANK_GROUP_P0_0x8000C0110301143F, data_buffer_64); if(rc) return rc; } - if ( address_mirror_map[port_number][sec_dimm] & (0x08 >> sec_dimm_rank) ) - { + if ( ( ( address_mirror_map[port_number][sec_dimm] & (0x08 >> sec_dimm_rank) ) ) && (secondary_ranks_array[rank_pair_group][port_number] != 0xff ) ) + { FAPI_INF( "Address Mirroring on %s PORT%d RANKPAIR%d RANK%d", i_target.toEcmdString(), port_number, rank_pair_group, primary_ranks_array[rank_pair_group][port_number]); bit_position = 2 * rank_pair_group + 49; FAPI_INF( "Setting bit %d", bit_position); @@ -336,7 +366,7 @@ ReturnCode mss_draminit_cloned(Target& i_target) rc = fapiPutScom(i_target, DPHY01_DDRPHY_PC_RANK_GROUP_P0_0x8000C0110301143F, data_buffer_64); if(rc) return rc; } - if ( address_mirror_map[port_number][ter_dimm] & (0x08 >> ter_dimm_rank) ) + if ( ( ( address_mirror_map[port_number][ter_dimm] & (0x08 >> ter_dimm_rank) ) ) && (tertiary_ranks_array[rank_pair_group][port_number] != 0xff ) ) { FAPI_INF( "Address Mirroring on %s PORT%d RANKPAIR%d RANK%d", i_target.toEcmdString(), port_number, rank_pair_group, primary_ranks_array[rank_pair_group][port_number]); bit_position = 2 * rank_pair_group + 48; @@ -347,8 +377,8 @@ ReturnCode mss_draminit_cloned(Target& i_target) rc = fapiPutScom(i_target, DPHY01_DDRPHY_PC_RANK_GROUP_EXT_P0_0x8000C0350301143F, data_buffer_64); if(rc) return rc; } - if ( address_mirror_map[port_number][qua_dimm] & (0x08 >> qua_dimm_rank) ) - { + if ( ( ( address_mirror_map[port_number][qua_dimm] & (0x08 >> qua_dimm_rank) ) ) && (quaternary_ranks_array[rank_pair_group][port_number] != 0xff ) ) + { FAPI_INF( "Address Mirroring on %s PORT%d RANKPAIR%d RANK%d", i_target.toEcmdString(), port_number, rank_pair_group, primary_ranks_array[rank_pair_group][port_number]); bit_position = 2 * rank_pair_group + 49; FAPI_INF( "Setting bit %d", bit_position); @@ -361,7 +391,7 @@ ReturnCode mss_draminit_cloned(Target& i_target) } if ( port_number == 1 ) { - if ( address_mirror_map[port_number][pri_dimm] & (0x08 >> pri_dimm_rank) ) + if ( ( ( address_mirror_map[port_number][pri_dimm] & (0x08 >> pri_dimm_rank) ) ) && (primary_ranks_array[rank_pair_group][port_number] != 0xff ) ) { FAPI_INF( "Address Mirroring on %s PORT%d RANKPAIR%d RANK%d", i_target.toEcmdString(), port_number, rank_pair_group, primary_ranks_array[rank_pair_group][port_number]); bit_position = 2 * rank_pair_group + 48; @@ -372,8 +402,8 @@ ReturnCode mss_draminit_cloned(Target& i_target) rc = fapiPutScom(i_target, DPHY01_DDRPHY_PC_RANK_GROUP_P1_0x8001C0110301143F, data_buffer_64); if(rc) return rc; } - if ( address_mirror_map[port_number][sec_dimm] & (0x08 >> sec_dimm_rank) ) - { + if ( ( ( address_mirror_map[port_number][sec_dimm] & (0x08 >> sec_dimm_rank) ) ) && (secondary_ranks_array[rank_pair_group][port_number] != 0xff ) ) + { FAPI_INF( "Address Mirroring on %s PORT%d RANKPAIR%d RANK%d", i_target.toEcmdString(), port_number, rank_pair_group, primary_ranks_array[rank_pair_group][port_number]); bit_position = 2 * rank_pair_group + 49; FAPI_INF( "Setting bit %d", bit_position); @@ -383,7 +413,7 @@ ReturnCode mss_draminit_cloned(Target& i_target) rc = fapiPutScom(i_target, DPHY01_DDRPHY_PC_RANK_GROUP_P1_0x8001C0110301143F, data_buffer_64); if(rc) return rc; } - if ( address_mirror_map[port_number][ter_dimm] & (0x08 >> ter_dimm_rank) ) + if ( ( ( address_mirror_map[port_number][ter_dimm] & (0x08 >> ter_dimm_rank) ) ) && (tertiary_ranks_array[rank_pair_group][port_number] != 0xff ) ) { FAPI_INF( "Address Mirroring on %s PORT%d RANKPAIR%d RANK%d", i_target.toEcmdString(), port_number, rank_pair_group, primary_ranks_array[rank_pair_group][port_number]); bit_position = 2 * rank_pair_group + 48; @@ -394,8 +424,8 @@ ReturnCode mss_draminit_cloned(Target& i_target) rc = fapiPutScom(i_target, DPHY01_DDRPHY_PC_RANK_GROUP_EXT_P1_0x8001C0350301143F, data_buffer_64); if(rc) return rc; } - if ( address_mirror_map[port_number][qua_dimm] & (0x08 >> qua_dimm_rank) ) - { + if ( ( ( address_mirror_map[port_number][qua_dimm] & (0x08 >> qua_dimm_rank) ) ) && (quaternary_ranks_array[rank_pair_group][port_number] != 0xff ) ) + { FAPI_INF( "Address Mirroring on PORT%d RANKPAIR%d RANK%d", port_number, rank_pair_group, primary_ranks_array[rank_pair_group][port_number]); bit_position = 2 * rank_pair_group + 49; FAPI_INF( "Setting bit %d", bit_position); @@ -411,7 +441,8 @@ ReturnCode mss_draminit_cloned(Target& i_target) } } - if ((!(dimm_type == ENUM_ATTR_EFF_DIMM_TYPE_LRDIMM)) && (dram_gen == ENUM_ATTR_EFF_DRAM_GEN_DDR3)) + //if ((!(dimm_type == ENUM_ATTR_EFF_DIMM_TYPE_LRDIMM)) && (dram_gen == ENUM_ATTR_EFF_DRAM_GEN_DDR3)) + if (dram_gen == ENUM_ATTR_EFF_DRAM_GEN_DDR3) { //Commented because Master Attention Reg Check not written yet. //Master Attntion Reg Check... Need to add appropriate call below. @@ -455,6 +486,18 @@ ReturnCode mss_draminit_cloned(Target& i_target) FAPI_ERR(" rcd_load Failed rc = 0x%08X (creator = %d)", uint32_t(rc), rc.getCreator()); return rc; } + + if ( dimm_type == ENUM_ATTR_EFF_DIMM_TYPE_LRDIMM ) + { + // Set Function 1-13 rcd words + rc = mss_lrdimm_rcd_load(i_target, port_number, ccs_inst_cnt); + if(rc) + { + FAPI_ERR(" LRDIMM rcd_load Failed rc = 0x%08X (creator = %d)", uint32_t(rc), rc.getCreator()); + return rc; + } + } + } } @@ -887,7 +930,10 @@ ReturnCode mss_rcd_load( uint8_t num_ranks_array[2][2]; //[port][dimm] uint64_t rcd_array[2][2]; //[port][dimm] - + uint8_t dimm_type; + + rc = FAPI_ATTR_GET(ATTR_EFF_DIMM_TYPE, &i_target, dimm_type); + if(rc) return rc; rc = FAPI_ATTR_GET(ATTR_EFF_NUM_RANKS_PER_DIMM, &i_target, num_ranks_array); if(rc) return rc; rc = FAPI_ATTR_GET(ATTR_EFF_DIMM_RCD_CNTL_WORD_0_15, &i_target, rcd_array); @@ -946,7 +992,12 @@ ReturnCode mss_rcd_load( // ALL active CS lines at a time. rc_num = rc_num | csn_8.setBit(0,8); - if ((num_ranks == 1) || (num_ranks == 2)) + if (dimm_type == ENUM_ATTR_EFF_DIMM_TYPE_LRDIMM) + { + // for dimm0 use CS0,1 (active low); for dimm1 use CS4,5 (active low) + rc_num = rc_num | csn_8.clearBit((4*dimm_number), 2 ); + } + else if ((num_ranks == 1) || (num_ranks == 2)) { rc_num = rc_num | csn_8.clearBit(0+4*dimm_number); rc_num = rc_num | csn_8.clearBit(1+4*dimm_number); @@ -981,7 +1032,15 @@ ReturnCode mss_rcd_load( 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); + if ( dimm_type == ENUM_ATTR_EFF_DIMM_TYPE_LRDIMM && (rcd_number == 2 || rcd_number == 10) ) + { + rc_num = rc_num | num_idles_16.insertFromRight((uint32_t) 4000, 0 , 16 ); // wait tStab for clock timing rcd words + } + else + { + rc_num = rc_num | num_idles_16.insertFromRight((uint32_t) 12, 0, 16); + } + if (rc_num) { @@ -1084,6 +1143,8 @@ ReturnCode mss_mrs_load( uint16_t MRS3 = 0; uint16_t num_ranks = 0; + uint8_t lrdimm_rank_mult_mode = 0; + FAPI_INF( "+++++++++++++++++++++ LOADING MRS SETTINGS FOR %s PORT %d +++++++++++++++++++++", i_target.toEcmdString(), i_port_number); @@ -1427,6 +1488,18 @@ ReturnCode mss_mrs_load( } else { + + if (dimm_type == ENUM_ATTR_EFF_DIMM_TYPE_LRDIMM) + { + rc = FAPI_ATTR_GET(ATTR_LRDIMM_RANK_MULT_MODE, &i_target, lrdimm_rank_mult_mode); + if(rc) return rc; + + if ( (lrdimm_rank_mult_mode == 4) && (num_ranks == 8) ) + { + num_ranks = 2; + } + } + // Rank 0-3 for ( rank_number = 0; rank_number < num_ranks; rank_number++) { @@ -1447,7 +1520,11 @@ ReturnCode mss_mrs_load( rc_num = rc_num | mrs0.extractPreserve(&MRS0, 0, 16, 0); - if (dram_rtt_nom[i_port_number][dimm_number][rank_number] == ENUM_ATTR_EFF_DRAM_RTT_NOM_DISABLE) + if ( lrdimm_rank_mult_mode != 0 ) + { + dram_rtt_nom[i_port_number][dimm_number][rank_number] = 0x00; + } + else if (dram_rtt_nom[i_port_number][dimm_number][rank_number] == ENUM_ATTR_EFF_DRAM_RTT_NOM_DISABLE) { dram_rtt_nom[i_port_number][dimm_number][rank_number] = 0x00; } @@ -1504,7 +1581,11 @@ ReturnCode mss_mrs_load( rc_num = rc_num | mrs1.extractPreserve(&MRS1, 0, 16, 0); - if (dram_rtt_wr[i_port_number][dimm_number][rank_number] == ENUM_ATTR_EFF_DRAM_RTT_WR_DISABLE) + if ( (lrdimm_rank_mult_mode != 0) && (rank_number > 1) ) + { + dram_rtt_wr[i_port_number][dimm_number][rank_number] = dram_rtt_wr[i_port_number][dimm_number][0]; + } + else if (dram_rtt_wr[i_port_number][dimm_number][rank_number] == ENUM_ATTR_EFF_DRAM_RTT_WR_DISABLE) { dram_rtt_wr[i_port_number][dimm_number][rank_number] = 0x00; } @@ -1662,10 +1743,17 @@ ReturnCode mss_mrs_load( ccs_end_1); if(rc) return rc; io_ccs_inst_cnt ++; - } - } - } - } + } // end mrs loop + } // end rank loop + + // For LRDIMM Set Rtt_nom, rtt_wr, driver impedance for R0 and R1 + if ( (dimm_type == fapi::ENUM_ATTR_EFF_DIMM_TYPE_LRDIMM) && lrdimm_rank_mult_mode != 0 ) + { + mss_lrdimm_mrs_load(i_target, i_port_number, dimm_number, io_ccs_inst_cnt); + } // end LRDIMM 8R dir MRS 1 + + } // end if has ranks + } // end dimm loop return rc; } 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 06f984ab9..39b5501e8 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 @@ -20,7 +20,7 @@ /* Origin: 30 */ /* */ /* IBM_PROLOG_END_TAG */ -// $Id: mss_draminit_training.C,v 1.64 2013/08/01 18:32:48 jdsloat Exp $ +// $Id: mss_draminit_training.C,v 1.68 2013/09/16 13:56:31 bellows Exp $ //------------------------------------------------------------------------------ // Don't forget to create CVS comments when you check in your changes! //------------------------------------------------------------------------------ @@ -28,6 +28,12 @@ //------------------------------------------------------------------------------ // Version:| Author: | Date: | Comment: //---------|----------|---------|------------------------------------------------ +// 1.68 | bellows |16-SEP-13| Hostboot compile update +// 1.67 | kcook |13-SEP-13| Updated define FAPI_LRDIMM token. +// 1.66 | kcook |27-AUG-13| Moved main LRDIMM sections into separate file. +// | | | Removed reference to ATTR_LAB_USE_JTAG_MODE. +// | mwuu | | Added ATTR_MSS_DISABLE1_REG_FIXED for bbm FN for DD2. +// 1.65 | kcook |16-AUG-13| Added LRDIMM support. Use with mss_funcs.C v1.32. // 1.64 | jdsloat |01-AUG-13| Fixed dimm/rank conversion in address mirroring mode for a 4 rank dimm scenario // 1.63 | jdsloat |29-JUN-13| Added JTAG mode and CONTROL SWITCH attribute checks to bad bit mask function calls. // 1.62 | mwuu |17-JUN-13| Fixed set_bbm function to disable0,disable1,wr_clk registers @@ -137,6 +143,24 @@ #include <mss_funcs.H> #include <dimmBadDqBitmapFuncs.H> #include <mss_unmask_errors.H> +#include <mss_lrdimm_funcs.H> + + + + +#ifndef FAPI_LRDIMM +using namespace fapi; +fapi::ReturnCode mss_execute_lrdimm_mb_dram_training(Target& i_target) +{ + ReturnCode rc; + + FAPI_ERR("Invalid exec of LRDIMM function on %s!", i_target.toEcmdString()); + FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR); + return rc; + +} +#endif + //------------End My Includes------------------------------------------- @@ -302,12 +326,12 @@ ReturnCode mss_draminit_training_cloned(Target& i_target) rc = fapiGetParentChip(i_target, l_target_centaur); if(rc) return rc; - uint8_t control_switch = 0; - rc = FAPI_ATTR_GET(ATTR_MSS_CONTROL_SWITCH, NULL, control_switch); + uint8_t dimm_type; + rc = FAPI_ATTR_GET(ATTR_EFF_DIMM_TYPE, &i_target, dimm_type); if(rc) return rc; - uint8_t jtag_mode = 0; - rc = FAPI_ATTR_GET(ATTR_LAB_USE_JTAG_MODE, NULL, jtag_mode); + uint8_t control_switch = 0; + rc = FAPI_ATTR_GET(ATTR_MSS_CONTROL_SWITCH, NULL, control_switch); if(rc) return rc; uint8_t dram_gen = 0; @@ -378,7 +402,7 @@ ReturnCode mss_draminit_training_cloned(Target& i_target) rc = fapiPutScom(i_target, MEM_MBA01_CCS_MODEQ_0x030106A7, data_buffer_64); if(rc) return rc; - if ( ( control_switch && 0x01 ) && (jtag_mode == 0) ) + if ( ( control_switch && 0x01 ) ) { rc = mss_set_bbm_regs (i_target); if(rc) @@ -403,6 +427,15 @@ ReturnCode mss_draminit_training_cloned(Target& i_target) if(rc) return rc; } + if ( dimm_type == fapi::ENUM_ATTR_EFF_DIMM_TYPE_LRDIMM ) + { + FAPI_INF("Performing LRDIMM MB-DRAM training"); + + // Execute MB-DRAM training + rc = mss_execute_lrdimm_mb_dram_training(i_target); + if (rc) return rc; + } + } for(port = 0; port < MAX_NUM_PORT; port++) @@ -607,15 +640,19 @@ ReturnCode mss_draminit_training_cloned(Target& i_target) // Before WR_LVL --- Change the RTT_NOM to RTT_WR pre-WR_LVL if ( (cur_cal_step == 1) && (dram_gen == ENUM_ATTR_EFF_DRAM_GEN_DDR3)) { - dram_rtt_nom_original = 0xFF; - rc = mss_rtt_nom_rtt_wr_swap(i_target, - mbaPosition, - port, - primary_ranks_array[group][port], - group, - instruction_number, - dram_rtt_nom_original); - if(rc) return rc; + if ( dimm_type != fapi::ENUM_ATTR_EFF_DIMM_TYPE_LRDIMM ) + { + + dram_rtt_nom_original = 0xFF; + rc = mss_rtt_nom_rtt_wr_swap(i_target, + mbaPosition, + port, + primary_ranks_array[group][port], + group, + instruction_number, + dram_rtt_nom_original); + if(rc) return rc; + } } @@ -694,15 +731,18 @@ ReturnCode mss_draminit_training_cloned(Target& i_target) // Following WR_LVL -- Restore RTT_NOM to orignal value post-wr_lvl if ((cur_cal_step == 1) && (dram_gen == ENUM_ATTR_EFF_DRAM_GEN_DDR3)) { - rc = mss_rtt_nom_rtt_wr_swap(i_target, - mbaPosition, - port, - primary_ranks_array[group][port], - group, - instruction_number, - dram_rtt_nom_original); - if(rc) return rc; - + if ( dimm_type != fapi::ENUM_ATTR_EFF_DIMM_TYPE_LRDIMM ) + { + + rc = mss_rtt_nom_rtt_wr_swap(i_target, + mbaPosition, + port, + primary_ranks_array[group][port], + group, + instruction_number, + dram_rtt_nom_original); + if(rc) return rc; + } } // Following Read Centering -- Enter into READ CENTERING WORKAROUND @@ -725,14 +765,14 @@ ReturnCode mss_draminit_training_cloned(Target& i_target) if(rc) return rc; } - if ( ( control_switch && 0x01 ) && (jtag_mode == 0) ) + if ( ( control_switch && 0x01 ) ) { 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) @@ -3150,7 +3190,7 @@ fapi::ReturnCode mss_set_bbm_regs (const fapi::Target & mba_target) 0x8800, 0x4400, 0x2280, 0x1140 }; - uint8_t l_dram_width, l_mbaPos; + uint8_t l_dram_width, l_mbaPos, l_disable1_fixed; uint64_t l_addr; // 0x8000007d0301143f const uint64_t l_disable1_addr_offset = 0x0000000100000000ull; // from disable0 register @@ -3188,6 +3228,13 @@ fapi::ReturnCode mss_set_bbm_regs (const fapi::Target & mba_target) rc = FAPI_ATTR_GET(ATTR_EFF_DRAM_WIDTH, &mba_target, l_dram_width); if(rc) return rc; + fapi::Target l_target_centaur; + rc = fapiGetParentChip(mba_target, l_target_centaur); + if(rc) return rc; + + rc = FAPI_ATTR_GET(ATTR_MSS_DISABLE1_REG_FIXED, &l_target_centaur, l_disable1_fixed); + if(rc) return rc; + switch (l_dram_width) { case ENUM_ATTR_EFF_DRAM_WIDTH_X4: @@ -3316,7 +3363,9 @@ fapi::ReturnCode mss_set_bbm_regs (const fapi::Target & mba_target) mask = bn_mask >> (4*q); if ((l_data & mask) == mask) { disable1_data |= disable1_mask_lookup[aport][i][q]; - wrclk_mask |= wrclk_disable_mask[q]; + if ( !l_disable1_fixed ) { + wrclk_mask |= wrclk_disable_mask[q]; + } FAPI_DBG("x4 disable1_data=0x%04X, wrclk_mask=0x%04X",disable1_data,wrclk_mask); } } @@ -3328,7 +3377,9 @@ fapi::ReturnCode mss_set_bbm_regs (const fapi::Target & mba_target) if ((l_data & mask) == mask) { disable1_data |= disable1_mask_lookup[aport][i][q] | disable1_mask_lookup[aport][i][q+1]; - wrclk_mask |= wrclk_disable_mask[q] | wrclk_disable_mask[q+1]; + if ( !l_disable1_fixed ) { + wrclk_mask |= wrclk_disable_mask[q] | wrclk_disable_mask[q+1]; + } FAPI_DBG("x8 disable1_data=0x%04X, wrclk_mask=0x%04X",disable1_data,wrclk_mask); } } @@ -3369,36 +3420,39 @@ fapi::ReturnCode mss_set_bbm_regs (const fapi::Target & mba_target) } // for DD1.X chips since disable1 register not fully working... can take out wrclk stuff for DD2+ - l_addr &= l_wrclk_en_addr_mask; // set address for wrclk_en register - - l_ecmdRc = data_buffer.flushTo0(); // clear buffer - if (l_ecmdRc != ECMD_DBUF_SUCCESS) + if ( !l_disable1_fixed ) { - FAPI_ERR("Error from ecmdDataBuffer flushTo0() " - "- rc 0x%.8X", l_ecmdRc); + l_addr &= l_wrclk_en_addr_mask; // set address for wrclk_en register - rc.setEcmdError(l_ecmdRc); - return rc; - } + l_ecmdRc = data_buffer.flushTo0(); // clear buffer + if (l_ecmdRc != ECMD_DBUF_SUCCESS) + { + FAPI_ERR("Error from ecmdDataBuffer flushTo0() " + "- rc 0x%.8X", l_ecmdRc); - ecmdDataBufferBase put_mask(64); - l_ecmdRc = put_mask.setHalfWord(3, wrclk_mask); - if (l_ecmdRc != ECMD_DBUF_SUCCESS) - { - FAPI_ERR("Error from ecmdDataBuffer setHalfWord() for wrclk_mask" - "- rc 0x%.8X", l_ecmdRc); + rc.setEcmdError(l_ecmdRc); + return rc; + } - rc.setEcmdError(l_ecmdRc); - return rc; - } - // clear(0) out the unused quads - rc = fapiPutScomUnderMask(mba_target, l_addr, data_buffer, put_mask); - if (rc) - { - FAPI_ERR("Error from fapiPutScomUnderMask writing wrclk_en reg"); - return rc; - } - } + ecmdDataBufferBase put_mask(64); + l_ecmdRc = put_mask.setHalfWord(3, wrclk_mask); + if (l_ecmdRc != ECMD_DBUF_SUCCESS) + { + FAPI_ERR("Error from ecmdDataBuffer setHalfWord() for wrclk_mask" + "- rc 0x%.8X", l_ecmdRc); + + rc.setEcmdError(l_ecmdRc); + return rc; + } + // clear(0) out the unused quads + rc = fapiPutScomUnderMask(mba_target, l_addr, data_buffer, put_mask); + if (rc) + { + FAPI_ERR("Error from fapiPutScomUnderMask writing wrclk_en reg"); + return rc; + } + } // if not disable1_fixed + } // if disable1 data != 0 } // end DP18 instance loop } // end primary rank loop } // end port loop @@ -3805,5 +3859,6 @@ ReturnCode setC4dq2reg(const Target &i_mba, const uint8_t i_port, const uint8_t 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 1fe38f852..13301ce55 100644 --- a/src/usr/hwpf/hwp/dram_training/mss_funcs.C +++ b/src/usr/hwpf/hwp/dram_training/mss_funcs.C @@ -20,7 +20,7 @@ /* Origin: 30 */ /* */ /* IBM_PROLOG_END_TAG */ -// $Id: mss_funcs.C,v 1.31 2013/05/20 21:29:50 jdsloat Exp $ +// $Id: mss_funcs.C,v 1.33 2013/08/27 22:22:46 kcook Exp $ /* File mss_funcs.C created by SLOAT JACOB D. (JAKE),2D3970 on Fri Apr 22 2011. */ //------------------------------------------------------------------------------ @@ -43,6 +43,8 @@ //------------------------------------------------------------------------------ // Version:| Author: | Date: | Comment: //---------|----------|---------|----------------------------------------------- +// 1.33 | kcook | 08/27/13| Removed LRDIMM functions to mss_lrdimm_funcs.C. Use with mss_funcs.H v1.16. +// 1.32 | kcook | 08/16/13| Added LRDIMM support. Use with mss_funcs.H v1.15. // 1.31 | jdsloat | 05/20/13| Added ddr_gen determination in address mirror mode function // 1.30 | jdsloat | 04/09/13| Moved Address mirror mode sub function in from mss_draminit // 1.29 | jsabrow | 11/19/12| added CCS data loader: mss_ccs_load_data_pattern @@ -116,6 +118,7 @@ ReturnCode mss_ccs_set_end_bit( return rc; } + ReturnCode mss_address_mirror_swizzle( Target& i_target, uint32_t i_port, @@ -762,9 +765,13 @@ ReturnCode mss_execute_zq_cal( uint8_t current_rank = 0; uint8_t start_rank = 0; uint8_t num_ranks_array[2][2]; //num_ranks_array[port][dimm] + uint8_t dimm_type; + uint8_t lrdimm_rank_mult_mode; rc = FAPI_ATTR_GET(ATTR_EFF_NUM_RANKS_PER_DIMM, &i_target, num_ranks_array); if(rc) return rc; + rc = FAPI_ATTR_GET(ATTR_EFF_DIMM_TYPE, &i_target, dimm_type); + if(rc) return rc; //Set up CCS Mode Reg for ZQ cal long and Init cal rc = fapiGetScom(i_target, MEM_MBA01_CCS_MODEQ_0x030106A7, data_buffer_64); @@ -781,6 +788,18 @@ ReturnCode mss_execute_zq_cal( for(uint8_t dimm = 0; dimm < MAX_NUM_DIMM; dimm++) { start_rank=(4 * dimm); + + if (dimm_type == ENUM_ATTR_EFF_DIMM_TYPE_LRDIMM) + { + rc = FAPI_ATTR_GET(ATTR_LRDIMM_RANK_MULT_MODE, &i_target, lrdimm_rank_mult_mode); + if(rc) return rc; + + if ( num_ranks_array[i_port][dimm] == 8 && lrdimm_rank_mult_mode == 4) + { // For LRDIMM 8 Rank, RM=4, CS0 and CS1 to execute ZQ cal + num_ranks_array[i_port][dimm] = 2; + } + } + for(current_rank = start_rank; current_rank < start_rank + num_ranks_array[i_port][dimm]; current_rank++) { FAPI_INF( "+++++++++++++++ Sending zqcal to port: %d rank: %d +++++++++++++++", i_port, current_rank); rc_num = rc_num | csn_buffer_8.flushTo1(); diff --git a/src/usr/hwpf/hwp/dram_training/mss_funcs.H b/src/usr/hwpf/hwp/dram_training/mss_funcs.H index b5af96fcd..395af3c35 100644 --- a/src/usr/hwpf/hwp/dram_training/mss_funcs.H +++ b/src/usr/hwpf/hwp/dram_training/mss_funcs.H @@ -20,7 +20,7 @@ /* Origin: 30 */ /* */ /* IBM_PROLOG_END_TAG */ -// $Id: mss_funcs.H,v 1.14 2013/04/09 23:34:27 jdsloat Exp $ +// $Id: mss_funcs.H,v 1.16 2013/08/27 22:23:53 kcook Exp $ /* File mss_funcs.H created by SLOAT JACOB D. (JAKE),2D3970 on Fri Apr 22 2011. */ //------------------------------------------------------------------------------ @@ -43,6 +43,8 @@ //------------------------------------------------------------------------------ // Version:| Author: | Date: | Comment: //---------|----------|---------|----------------------------------------------- +// 1.16 | kcook | 08/27/13| Removed LRDIMM functions to mss_lrdimm_funcs.H. Use with mss_funcs.C v1.33. +// 1.15 | kcook | 08/16/13| Added LRDIMM support. Use with mss_funcs.C v1.32. // 1.14 | jdsloat | 04/09/13| Moved Address mirror mode sub function in from mss_draminit // 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 @@ -245,6 +247,7 @@ uint8_t mss_reverse_8bits(uint8_t i_number); fapi::ReturnCode mss_execute_zq_cal(fapi::Target& i_target, uint8_t i_port); + //----------------------------------------- // mss_address_mirror_swizzle // swizzle the address bus and bank address bus for address mirror mode diff --git a/src/usr/hwpf/hwp/dram_training/mss_lrdimm_funcs/mss_lrdimm_funcs.C b/src/usr/hwpf/hwp/dram_training/mss_lrdimm_funcs/mss_lrdimm_funcs.C new file mode 100644 index 000000000..57bdab249 --- /dev/null +++ b/src/usr/hwpf/hwp/dram_training/mss_lrdimm_funcs/mss_lrdimm_funcs.C @@ -0,0 +1,1965 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/hwpf/hwp/dram_training/mss_lrdimm_funcs/mss_lrdimm_funcs.C $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2013 */ +/* */ +/* 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_lrdimm_funcs.C,v 1.4 2013/09/16 13:56:38 bellows Exp $ +//------------------------------------------------------------------------------ +// *! (C) Copyright International Business Machines Corp. 2013 +// *! All Rights Reserved -- Property of IBM +// *! *** IBM Confidential *** +//------------------------------------------------------------------------------ +// *! TITLE : mss_lrdimm_funcs.C +// *! DESCRIPTION : Tools for LRDIMM centaur procedures +// *! OWNER NAME : kcook@us.ibm.com +// *! BACKUP NAME : mwuu@us.ibm.com +// #! ADDITIONAL COMMENTS : +// + +//------------------------------------------------------------------------------ +// Don't forget to create CVS comments when you check in your changes! +//------------------------------------------------------------------------------ +// CHANGE HISTORY: +//------------------------------------------------------------------------------ +// Version:| Author: | Date: | Comment: +//---------|----------|---------|----------------------------------------------- +// 1.4 | 09/16/13 | bellows | Hostboot compile update +// 1.3 | 09/16/13 | bellows | Added ID tag. +// 1.2 | 09/13/13 | kcook | Updated define FAPI_LRDIMM token. +// 1.1 | 08/27/13 | kcook | First drop of Centaur + +//---------------------------------------------------------------------- +// Includes +//---------------------------------------------------------------------- + +#include <fapi.H> +#include <mss_lrdimm_funcs.H> +#include <mss_funcs.H> + +#ifdef FAPI_LRDIMM +const uint8_t MAX_NUM_DIMMS = 2; +const uint8_t MAX_NUM_LR_RANKS = 8; +const uint8_t MRS1_BA = 1; +const uint8_t PORT_SIZE = 2; +const uint8_t DIMM_SIZE = 2; +const uint8_t RANK_SIZE = 4; +const uint32_t MSS_EFF_VALID = 255; + + +using namespace fapi; + +fapi::ReturnCode mss_lrdimm_rcd_load( Target& i_target, uint32_t port_number, uint32_t& ccs_inst_cnt) +{ + ReturnCode rc; + uint8_t num_drops_per_port; + // LRDIMM + uint8_t func1_rcd_number_array_u8[12] = {7,0,1,2,8,9,10,11,12,13,14,15}; + uint8_t func2_rcd_number_array_u8[8] = {7,0,1,2,3,4,5,6}; + uint8_t func3_rcd_number_array_u8[7] = {7,0,1,2,6,8,9}; + uint8_t funcODT_rcd_number_array_u8[3] = {7,10,11}; + uint8_t *p_func_num_arr; + ecmdDataBufferBase data_buff_rcd_word(64); + uint64_t func_rcd_control_word[2]; + uint8_t num_ranks_array[2][2]; //[port][dimm] + uint8_t dimm_number; + uint8_t rank_number; + uint64_t spd_func_words; + uint64_t att_spd_func_words[2][2]; + uint8_t num_rows; + uint8_t num_cols; + uint8_t dram_width; + uint64_t l_func1_mask = 0x00000000F00FFFFFLL; + uint8_t l_rcd_cntl_word_0; + uint8_t l_rcd_cntl_word_1; + uint8_t l_rcd_cntl_word_2; + uint8_t l_rcd_cntl_word_3; + uint8_t l_rcd_cntl_word_4; + uint8_t l_rcd_cntl_word_5; + uint8_t l_rcd_cntl_word_6; + uint8_t l_rcd_cntl_word_7; + uint8_t l_rcd_cntl_word_8; + uint8_t l_rcd_cntl_word_9; + uint8_t l_rcd_cntl_word_10; + uint8_t l_rcd_cntl_word_11; + uint8_t dimm_func_vec; + + rc = FAPI_ATTR_GET(ATTR_EFF_NUM_RANKS_PER_DIMM, &i_target, num_ranks_array); + if(rc) return rc; + rc = FAPI_ATTR_GET(ATTR_LRDIMM_ADDITIONAL_CNTL_WORDS, &i_target, att_spd_func_words); + if(rc) return rc; + rc = FAPI_ATTR_GET(ATTR_EFF_DRAM_ROWS, &i_target, num_rows); + if(rc) return rc; + rc = FAPI_ATTR_GET(ATTR_EFF_DRAM_COLS, &i_target, num_cols); + if(rc) return rc; + rc = FAPI_ATTR_GET(ATTR_EFF_DRAM_WIDTH, &i_target, dram_width); + if (rc) return rc; + rc=FAPI_ATTR_GET(ATTR_MSS_EFF_DIMM_FUNCTIONAL_VECTOR, &i_target, dimm_func_vec); + if(rc) return rc; + rc = FAPI_ATTR_GET(ATTR_EFF_NUM_DROPS_PER_PORT, &i_target, num_drops_per_port); + if(rc) return rc; + + + // Fucntion 1 + for (dimm_number = 0;dimm_number < MAX_NUM_DIMMS; dimm_number++) + { + + if ( num_ranks_array[port_number][dimm_number] != 0 ) + { + //F[1]RC0 IBT settings for DCS pins + l_rcd_cntl_word_0 = 0; // IBT DCS[1:0] 100 Ohm, DCS[3:2] IBT as defined DCS[1:0] + l_rcd_cntl_word_1 = 0; //IBT DCKE 100 Ohm + l_rcd_cntl_word_2 = 0; //IBT DODT[1:0] 100 Ohm + + l_rcd_cntl_word_7 = 1; //Function select + l_rcd_cntl_word_9 = 0; //Refresh stagger = 0clocks + l_rcd_cntl_word_10 = 0; //Refresh stagger limit = unimited + + data_buff_rcd_word.clearBit(0,64); + data_buff_rcd_word.insertFromRight(&l_rcd_cntl_word_0, 0,4); + data_buff_rcd_word.insertFromRight(&l_rcd_cntl_word_1, 4,4); + data_buff_rcd_word.insertFromRight(&l_rcd_cntl_word_2, 8,4); + data_buff_rcd_word.insertFromRight(&l_rcd_cntl_word_7, 28,4); + data_buff_rcd_word.insertFromRight(&l_rcd_cntl_word_9, 36,4); + data_buff_rcd_word.insertFromRight(&l_rcd_cntl_word_10, 40,4); + + func_rcd_control_word[dimm_number] = data_buff_rcd_word.getDoubleWord(0); + if(rc) return rc; + spd_func_words = att_spd_func_words[port_number][dimm_number] & l_func1_mask; // SPD for F[1]RC8,11-15 + func_rcd_control_word[dimm_number] = func_rcd_control_word[dimm_number] | spd_func_words; + } + } + + FAPI_INF("SELECTING FUNCTION %d", l_rcd_cntl_word_7); + p_func_num_arr = func1_rcd_number_array_u8; + rc = mss_spec_rcd_load(i_target, port_number, p_func_num_arr, + sizeof(func1_rcd_number_array_u8)/sizeof(func1_rcd_number_array_u8[0]), + func_rcd_control_word , ccs_inst_cnt,1); + if(rc) + { + FAPI_ERR(" spec_rcd_load Failed rc = 0x%08X (creator = %d)", uint32_t(rc), rc.getCreator()); + return rc; + } + + // Function 2 + for (dimm_number = 0;dimm_number < MAX_NUM_DIMMS; dimm_number++) + { + if ( num_ranks_array[port_number][dimm_number] != 0 ) + { + l_rcd_cntl_word_0 = 0; // Transparent mode + l_rcd_cntl_word_1 = 0; // Reset control + l_rcd_cntl_word_2 = 0; // SMBus access control + l_rcd_cntl_word_3 = 8; // Training control & Errorout enable driven Low when Training + l_rcd_cntl_word_4 = 0; // MEMBIST Rank control + + //RC5 DRAM row & column addressing + if ( num_rows == 13 ) + { + if ( num_cols == 10 ) + { + l_rcd_cntl_word_5 = 0; + } + else if ( num_cols == 11 ) + { + l_rcd_cntl_word_5 = 1; + } + else if ( num_cols == 12 ) + { + l_rcd_cntl_word_5 = 2; + } + else if ( num_cols == 3 ) + { + l_rcd_cntl_word_5 = 3; + } + } + else if ( num_rows == 14 ) + { + if ( num_cols == 10 ) + { + l_rcd_cntl_word_5 = 4; + } + else if ( num_cols == 11 ) + { + l_rcd_cntl_word_5 = 5; + } + else if ( num_cols == 12 ) + { + l_rcd_cntl_word_5 = 6; + } + else if ( num_cols == 3 ) + { + l_rcd_cntl_word_5 = 7; + } + } + else if ( num_rows == 15 ) + { + if ( num_cols == 10 ) + { + l_rcd_cntl_word_5 = 8; + } + else if ( num_cols == 11 ) + { + l_rcd_cntl_word_5 = 9; + } + else if ( num_cols == 12 ) + { + l_rcd_cntl_word_5 = 10; + } + else if ( num_cols == 3 ) + { + l_rcd_cntl_word_5 = 11; + } + } + else if ( num_rows == 16 ) + { + if ( num_cols == 10 ) + { + l_rcd_cntl_word_5 = 12; + } + else if ( num_cols == 11 ) + { + l_rcd_cntl_word_5 = 13; + } + else if ( num_cols == 12 ) + { + l_rcd_cntl_word_5 = 14; + } + else if ( num_cols == 3 ) + { + l_rcd_cntl_word_5 = 15; + } + } + + l_rcd_cntl_word_6 = 0; // MEMBIST control + l_rcd_cntl_word_7 = 2; //Function select + + data_buff_rcd_word.clearBit(0,64); + data_buff_rcd_word.insertFromRight(&l_rcd_cntl_word_0, 0,4); + data_buff_rcd_word.insertFromRight(&l_rcd_cntl_word_1, 4,4); + data_buff_rcd_word.insertFromRight(&l_rcd_cntl_word_2, 8,4); + data_buff_rcd_word.insertFromRight(&l_rcd_cntl_word_3,12,4); + data_buff_rcd_word.insertFromRight(&l_rcd_cntl_word_4,16,4); + data_buff_rcd_word.insertFromRight(&l_rcd_cntl_word_5,20,4); + data_buff_rcd_word.insertFromRight(&l_rcd_cntl_word_6,24,4); + data_buff_rcd_word.insertFromRight(&l_rcd_cntl_word_7, 28,4); + + func_rcd_control_word[dimm_number] = data_buff_rcd_word.getDoubleWord(0); + if(rc) return rc; + } + } + + + FAPI_INF("SELECTING FUNCTION %d", l_rcd_cntl_word_7); + p_func_num_arr = func2_rcd_number_array_u8; + rc = mss_spec_rcd_load(i_target, port_number, p_func_num_arr, + sizeof(func2_rcd_number_array_u8)/sizeof(func2_rcd_number_array_u8[0]), + func_rcd_control_word , ccs_inst_cnt,1); + if(rc) + { + FAPI_ERR(" spec_rcd_load Failed rc = 0x%08X (creator = %d)", uint32_t(rc), rc.getCreator()); + return rc; + } + + // Function 3 + for (dimm_number = 0;dimm_number < MAX_NUM_DIMMS; dimm_number++) + { + if ( num_ranks_array[port_number][dimm_number] != 0 ) + { + data_buff_rcd_word.setDoubleWord(0, att_spd_func_words[port_number][dimm_number]); + data_buff_rcd_word.extractToRight(&l_rcd_cntl_word_8 , 40, 4); // f[3]RC8 is in space RCD10 + data_buff_rcd_word.extractToRight(&l_rcd_cntl_word_9 , 36, 4); + + //F[3]RC0 connector interface DQ RTT_Nom Termination, TDQS control + if ( num_drops_per_port == ENUM_ATTR_EFF_NUM_DROPS_PER_PORT_DUAL ) + { // Single rank, dual drop + if ( dram_width == 8 ) + { + l_rcd_cntl_word_0 = 9; // RTT_Nom 60 Ohm, TDQS enabled + } + else + { + l_rcd_cntl_word_0 = 1; // RTT_NOM 60 Ohm, TDQS disabled + } + } + else + { // Single rank, Single drop + if ( dram_width == 8 ) + { + l_rcd_cntl_word_0 = 9; // RTT_Nom 60 Ohm, TDQS enabled + } + else + { + l_rcd_cntl_word_0 = 1; // RTT_NOM 60 Ohm, TDQS disabled + } + } + + //F[3]RC1 connector interface DQ RTT_WR termination & Reference voltage + if ( num_drops_per_port == ENUM_ATTR_EFF_NUM_DROPS_PER_PORT_DUAL ) + { // Single rank, dual drop + l_rcd_cntl_word_1 = 2; // RTT_WR 120 Ohm , VrefDQ input pin + l_rcd_cntl_word_2 = 1; // Connecter interface DQ/DQS output driver imp 34 Ohm, DQ/DQS drivers enabled + } + else + { // Single rank, Single drop + l_rcd_cntl_word_1 = 0; // RTT_WR disabled, VrefDQ input pin + l_rcd_cntl_word_2 = 1; // Connecter interface DQ/DQS output driver imp 34 Ohm, DQ/DQS drivers enabled + } + + FAPI_INF("Using ATTR_EFF_SCHMOO_TEST_VALID for dq LRDIMM timing mode"); + rc=FAPI_ATTR_GET(ATTR_EFF_SCHMOO_TEST_VALID, &i_target, l_rcd_cntl_word_6); + + l_rcd_cntl_word_7 = 3; //Function select + + data_buff_rcd_word.clearBit(0,64); + data_buff_rcd_word.insertFromRight(&l_rcd_cntl_word_0, 0,4); + data_buff_rcd_word.insertFromRight(&l_rcd_cntl_word_1, 4,4); + data_buff_rcd_word.insertFromRight(&l_rcd_cntl_word_2, 8,4); + data_buff_rcd_word.insertFromRight(&l_rcd_cntl_word_6,24,4); + data_buff_rcd_word.insertFromRight(&l_rcd_cntl_word_7, 28,4); + data_buff_rcd_word.insertFromRight(&l_rcd_cntl_word_8,32,4); + data_buff_rcd_word.insertFromRight(&l_rcd_cntl_word_9, 36,4); + + func_rcd_control_word[dimm_number] = data_buff_rcd_word.getDoubleWord(0); + if(rc) return rc; + } + } + + FAPI_INF("SELECTING FUNCTION %d", l_rcd_cntl_word_7); + p_func_num_arr = func3_rcd_number_array_u8; + rc = mss_spec_rcd_load(i_target, port_number, p_func_num_arr, + sizeof(func3_rcd_number_array_u8)/sizeof(func3_rcd_number_array_u8[0]), + func_rcd_control_word , ccs_inst_cnt,1); + if(rc) + { + FAPI_ERR(" spec_rcd_load Failed rc = 0x%08X (creator = %d)", uint32_t(rc), rc.getCreator()); + return rc; + } + + for ( rank_number = 0; rank_number < MAX_NUM_LR_RANKS; rank_number++ ) + { + for (dimm_number = 0;dimm_number < MAX_NUM_DIMMS; dimm_number++) + { + if ( num_ranks_array[port_number][dimm_number] != 0 ) + { + data_buff_rcd_word.setDoubleWord(0, att_spd_func_words[port_number][dimm_number]); + data_buff_rcd_word.extractToRight(&l_rcd_cntl_word_10 , rank_number/2*8, 4); // RC10 is in space RCD0/2/4/6 + data_buff_rcd_word.extractToRight(&l_rcd_cntl_word_11 , rank_number/2*8+4, 4); // RC11 is in space RCD1/3/5/7 + + l_rcd_cntl_word_7 = rank_number + 3; // Function word select 3:10 for Ranks 0-7 + + data_buff_rcd_word.clearBit(0,64); + data_buff_rcd_word.insertFromRight(&l_rcd_cntl_word_7, 28,4); + data_buff_rcd_word.insertFromRight(&l_rcd_cntl_word_10,40,4); + data_buff_rcd_word.insertFromRight(&l_rcd_cntl_word_11,44,4); + + func_rcd_control_word[dimm_number] = data_buff_rcd_word.getDoubleWord(0); + if(rc) return rc; + } + } + + FAPI_INF("SELECTING FUNCTION %d", l_rcd_cntl_word_7); + p_func_num_arr = funcODT_rcd_number_array_u8; + rc = mss_spec_rcd_load(i_target, port_number, p_func_num_arr, + sizeof(funcODT_rcd_number_array_u8)/sizeof(funcODT_rcd_number_array_u8[0]), + func_rcd_control_word , ccs_inst_cnt,1); + if(rc) + { + FAPI_ERR(" spec_rcd_load Failed rc = 0x%08X (creator = %d)", uint32_t(rc), rc.getCreator()); + return rc; + } + } // end rank loop + + // Function 13 + l_rcd_cntl_word_7 = 13; + FAPI_INF("SELECTING FUNCTION %d", l_rcd_cntl_word_7); + + uint8_t Rx_MR1_2_DATA[2][2]; + rc=FAPI_ATTR_GET(ATTR_LRDIMM_MR12_REG, &i_target, Rx_MR1_2_DATA); + if(rc) return rc; + + uint8_t rcw = 7; + uint64_t rcd0_15[2] = { 0x0000000D00000000ll, // select FN 13 dimm0 + 0x0000000D00000000ll }; // " dimm1 + + // set FN 13 via RC 7 + rc = mss_spec_rcd_load( i_target, port_number, &rcw, 1, rcd0_15, ccs_inst_cnt,1); + if(rc) + { + FAPI_ERR(" spec_rcd_load Failed rc = 0x%08X (creator = %d)", + uint32_t(rc), rc.getCreator()); + return rc; + } + + uint8_t func13_rcd_number_array_size = 4; + uint8_t func13_rcd_number_array_u8[4] = { 10, 11, 14, 15 }; + p_func_num_arr = func13_rcd_number_array_u8; + + data_buff_rcd_word.clearBit(0,64); + data_buff_rcd_word.insertFromRight(&l_rcd_cntl_word_7, 28,4); // select F13 + + const uint8_t num_ecw = 11; // number of external funcs + uint8_t R2_7_MR1_2_DATA[2][2]; + R2_7_MR1_2_DATA[port_number][0] = Rx_MR1_2_DATA[port_number][0] & 0xE3; // disable RTT_NOM on ranks 2:7 + R2_7_MR1_2_DATA[port_number][1] = Rx_MR1_2_DATA[port_number][1] & 0xE3; // disable RTT_NOM on ranks 2:7 + + + // extended control word addr, data + uint8_t ext_funcs[MAX_NUM_DIMMS][num_ecw][2] = { + { + {0xAC, 0x00}, // MRS_CTRL = 0xAC; snoop/forward/store + // MRx_SNOOP = 0xC8-CF MR(0:3) MR to DRAM 0xC8/C9-CE/CF + {0xC8, 0x00}, // MR0_SNOOP(0:7) = 0xC8 MR0 to DRAM + {0xC9, 0x00}, // MR0_SNOOP(8:15) = 0xC9; MR0 to DRAM + // Rx_MR1_2 = 0xB8-BF; R(0:7) ranks, RTT_WR, RTT_NOM, D_IMP + {0xB8, Rx_MR1_2_DATA[port_number][0]}, // rank 0 + {0xB9, Rx_MR1_2_DATA[port_number][0]}, // rank 1 + {0xBA, R2_7_MR1_2_DATA[port_number][0]}, // rank 2 + {0xBB, R2_7_MR1_2_DATA[port_number][0]}, // rank 3 + {0xBC, R2_7_MR1_2_DATA[port_number][0]}, // rank 4 + {0xBD, R2_7_MR1_2_DATA[port_number][0]}, // rank 5 + {0xBE, R2_7_MR1_2_DATA[port_number][0]}, // rank 6 + {0xBF, R2_7_MR1_2_DATA[port_number][0]} // rank 7 + }, + { + {0xAC, 0x00}, // MRS_CTRL = 0xAC; snoop/forward/store + // MRx_SNOOP = 0xC8-CF MR(0:3) MR to DRAM 0xC8/C9-CE/CF + {0xC8, 0x00}, // MR0_SNOOP(0:7) = 0xC8 MR0 to DRAM + {0xC9, 0x00}, // MR0_SNOOP(8:15) = 0xC9; MR0 to DRAM + // Rx_MR1_2 = 0xB8-BF; R(0:7) ranks, RTT_WR, RTT_NOM, D_IMP + {0xB8, Rx_MR1_2_DATA[port_number][1]}, // rank 0 + {0xB9, Rx_MR1_2_DATA[port_number][1]}, // rank 1 + {0xBA, R2_7_MR1_2_DATA[port_number][1]}, // rank 2 + {0xBB, R2_7_MR1_2_DATA[port_number][1]}, // rank 3 + {0xBC, R2_7_MR1_2_DATA[port_number][1]}, // rank 4 + {0xBD, R2_7_MR1_2_DATA[port_number][1]}, // rank 5 + {0xBE, R2_7_MR1_2_DATA[port_number][1]}, // rank 6 + {0xBF, R2_7_MR1_2_DATA[port_number][1]} // rank 7 + } + }; + for (uint8_t i=0; i < num_ecw; i++) + { + // set func_rcd_control_word[dimm_number] + for (dimm_number = 0;dimm_number < MAX_NUM_DIMMS; dimm_number++) + { + if ( num_ranks_array[port_number][dimm_number] != 0 ) + { + // load address + data_buff_rcd_word.insertFromRight(ext_funcs[dimm_number][i][0],40,4); // lsb address + data_buff_rcd_word.insert(ext_funcs[dimm_number][i][0],44,4); // msb address + // load data + data_buff_rcd_word.insertFromRight(ext_funcs[dimm_number][i][1], 56,4); // lsb data + data_buff_rcd_word.insert(ext_funcs[dimm_number][i][1], 60,4); // msb data + + func_rcd_control_word[dimm_number] = data_buff_rcd_word.getDoubleWord(0); + if(rc) return rc; + } // end if has ranks + } // end dimm loop + + + // load CCS with F13 RC 10:11, 14:15 + rc = mss_spec_rcd_load( i_target, port_number, p_func_num_arr, func13_rcd_number_array_size, + func_rcd_control_word , ccs_inst_cnt,1); + if(rc) + { + FAPI_ERR(" spec_rcd_load Failed rc = 0x%08X (creator = %d)", uint32_t(rc), rc.getCreator()); + return rc; + } + } // end # extended control words to write + // end Function 13 + + // set FN 0 via RC 7 + rcd0_15[0] = 0; + rcd0_15[1] = 0; + rc = mss_spec_rcd_load( i_target, port_number, &rcw, 1, rcd0_15, ccs_inst_cnt,1); + if(rc) + { + FAPI_ERR(" spec_rcd_load Failed rc = 0x%08X (creator = %d)", + uint32_t(rc), rc.getCreator()); + return rc; + } + + // force execute of remaining rcd !! not necessary??? !! + // Execute the contents of CCS array + if (ccs_inst_cnt > 0) + { + // Set the End bit on the last CCS Instruction + rc = mss_ccs_set_end_bit( i_target, ccs_inst_cnt-1); + if(rc) + { + FAPI_ERR("CCS_SET_END_BIT FAILED rc = 0x%08X (creator = %d)", uint32_t(rc), rc.getCreator()); + return rc; + } + + rc = mss_execute_ccs_inst_array(i_target, 10, 10); + if(rc) + { + FAPI_ERR(" EXECUTE_CCS_INST_ARRAY FAILED rc = 0x%08X (creator = %d)", + uint32_t(rc), rc.getCreator()); + return rc; + } + + ccs_inst_cnt = 0; + } + // end force execute of rcd + + + return rc; + +} + +fapi::ReturnCode mss_lrdimm_mrs_load( Target& i_target , uint32_t i_port_number,uint32_t dimm_number, uint32_t& io_ccs_inst_cnt) +{ + // For LRDIMM Set Rtt_nom, rtt_wr, driver impedance for R0 and R1 + // turn off MRS broadcast + ReturnCode rc; + ReturnCode rc_buff; + uint32_t rc_num = 0; + ecmdDataBufferBase csn_8(8); + rc_num = rc_num | csn_8.setBit(0,8); + 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 odt_4(4); + rc_num = rc_num | odt_4.setBit(0,4); + ecmdDataBufferBase ddr_cal_type_4(4); + ecmdDataBufferBase csn_setup_8(8); + rc_num = rc_num | csn_setup_8.setBit(0,8); + + ecmdDataBufferBase num_idles_16(16); + rc_num = rc_num | num_idles_16.insertFromRight((uint32_t) 400, 0, 16); + ecmdDataBufferBase num_idles_setup_16(16); + rc_num = rc_num | num_idles_setup_16.insertFromRight((uint32_t) 400, 0, 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); + uint16_t MRS1 = 0; + uint32_t mrs_number; + uint8_t address_mirror_map[2][2]; //address_mirror_map[port][dimm] + uint8_t is_sim = 0; + uint8_t dram_2n_mode = 0; + + uint32_t rank_number; + uint16_t num_ranks = 2; + uint8_t func13_rcd_number_array_size; + uint8_t func13_rcd_number_array_u8[4] = {10,11,14,15}; + ecmdDataBufferBase data_buff_rcd_word(64); + uint8_t l_rcd_cntl_word_7 = 0; + uint64_t func_rcd_control_word[2]; + uint8_t l_rcd_cntl_word_14; + uint64_t rcd_array[2][2]; //[port][dimm] + uint8_t num_ranks_array[2][2]; + + // cs 0:7 R0 R1 R2 R3 R4 R5 R6 R7 + uint8_t lrdimm_cs8n [] = { 0x4, 0x8, 0x6, 0xA, 0x5, 0x9, 0x7, 0xB }; + + rc = FAPI_ATTR_GET(ATTR_EFF_NUM_RANKS_PER_DIMM, &i_target, num_ranks_array); + if(rc) return rc; + rc = FAPI_ATTR_GET(ATTR_EFF_DIMM_RCD_CNTL_WORD_0_15, &i_target, rcd_array); + if(rc) return rc; + rc = FAPI_ATTR_GET(ATTR_EFF_DRAM_ADDRESS_MIRRORING, &i_target, address_mirror_map); + if(rc) return rc; + rc = FAPI_ATTR_GET(ATTR_IS_SIMULATION, NULL, is_sim); + if(rc) return rc; + rc = FAPI_ATTR_GET(ATTR_EFF_DRAM_2N_MODE_ENABLED, &i_target, dram_2n_mode); + if(rc) return rc; + + //MRS1 + uint8_t dll_enable; + rc = FAPI_ATTR_GET(ATTR_EFF_DRAM_DLL_ENABLE, &i_target, dll_enable); + if(rc) return rc; + uint8_t out_drv_imp_cntl[2][2]; + rc = FAPI_ATTR_GET(ATTR_EFF_DRAM_RON, &i_target, out_drv_imp_cntl); + if(rc) return rc; + uint8_t dram_rtt_nom[2][2][4]; + rc = FAPI_ATTR_GET(ATTR_EFF_DRAM_RTT_NOM, &i_target, dram_rtt_nom); + if(rc) return rc; + uint8_t dram_al; + rc = FAPI_ATTR_GET(ATTR_EFF_DRAM_AL, &i_target, dram_al); + if(rc) return rc; + uint8_t wr_lvl; //write leveling enable + rc = FAPI_ATTR_GET(ATTR_EFF_DRAM_WR_LVL_ENABLE, &i_target, wr_lvl); + if(rc) return rc; + uint8_t tdqs_enable; //TDQS Enable + rc = FAPI_ATTR_GET(ATTR_EFF_DRAM_TDQS, &i_target, tdqs_enable); + if(rc) return rc; + uint8_t q_off; //Qoff - Output buffer Enable + rc = FAPI_ATTR_GET(ATTR_EFF_DRAM_OUTPUT_BUFFER, &i_target, q_off); + if(rc) return rc; + + + if (dll_enable == ENUM_ATTR_EFF_DRAM_DLL_ENABLE_ENABLE) + { + dll_enable = 0x00; + } + else if (dll_enable == ENUM_ATTR_EFF_DRAM_DLL_ENABLE_DISABLE) + { + dll_enable = 0xFF; + } + + if (dram_al == ENUM_ATTR_EFF_DRAM_AL_DISABLE) + { + dram_al = 0x00; + } + else if (dram_al == ENUM_ATTR_EFF_DRAM_AL_CL_MINUS_1) + { + dram_al = 0x80; + } + else if (dram_al == ENUM_ATTR_EFF_DRAM_AL_CL_MINUS_2) + { + dram_al = 0x40; + } + + if (wr_lvl == ENUM_ATTR_EFF_DRAM_WR_LVL_ENABLE_DISABLE) + { + wr_lvl = 0x00; + } + else if (wr_lvl == ENUM_ATTR_EFF_DRAM_WR_LVL_ENABLE_ENABLE) + { + wr_lvl = 0xFF; + } + + if (tdqs_enable == ENUM_ATTR_EFF_DRAM_TDQS_DISABLE) + { + tdqs_enable = 0x00; + } + else if (tdqs_enable == ENUM_ATTR_EFF_DRAM_TDQS_ENABLE) + { + tdqs_enable = 0xFF; + } + + if (q_off == ENUM_ATTR_EFF_DRAM_OUTPUT_BUFFER_DISABLE) + { + q_off = 0xFF; + } + else if (q_off == ENUM_ATTR_EFF_DRAM_OUTPUT_BUFFER_ENABLE) + { + q_off = 0x00; + } + + for (uint8_t dimm_num = 0;dimm_num < MAX_NUM_DIMMS; dimm_num++) + { + + if ( num_ranks_array[i_port_number][dimm_num] != 0 ) + { + l_rcd_cntl_word_14 = (rcd_array[i_port_number][dimm_num] & 0xF0) >> 4; // MRS broadcast + FAPI_INF("current F0RC14 = 0x%X",l_rcd_cntl_word_14); + l_rcd_cntl_word_14 = l_rcd_cntl_word_14 | 0x4; + FAPI_INF("setting F0RC14 = 0x%X",l_rcd_cntl_word_14); + data_buff_rcd_word.clearBit(0,64); + data_buff_rcd_word.insertFromRight(&l_rcd_cntl_word_14, 56,4); + func_rcd_control_word[dimm_num] = data_buff_rcd_word.getDoubleWord(0); + if(rc) return rc; + } + } + + FAPI_INF("SELECTING FUNCTION %d", l_rcd_cntl_word_7); + + uint8_t *p_func_num_arr; + uint8_t func0_rcd_number_array_size = 2; + uint8_t func0_rcd_number_array_u8[] = { 7, 14 }; + p_func_num_arr = func0_rcd_number_array_u8; + rc = mss_spec_rcd_load(i_target, i_port_number, p_func_num_arr, func0_rcd_number_array_size, + func_rcd_control_word , io_ccs_inst_cnt,1); + if(rc) + { + FAPI_ERR(" spec_rcd_load Failed rc = 0x%08X (creator = %d)", uint32_t(rc), rc.getCreator()); + return rc; + } + + + // set FN 0 via RC 7 + func_rcd_control_word[0]=0; + func_rcd_control_word[1]=0; + func0_rcd_number_array_u8 [0] = 7; + rc = mss_spec_rcd_load( i_target, i_port_number, p_func_num_arr, 1, + func_rcd_control_word, io_ccs_inst_cnt,1); + + if(rc) + { + FAPI_ERR(" spec_rcd_load Failed rc = 0x%08X (creator = %d)", uint32_t(rc), rc.getCreator()); + return rc; + } + // end turn off MRS broadcast + + // Disable MRS snooping + l_rcd_cntl_word_7 = 13; + FAPI_INF("SELECTING FUNCTION %d", l_rcd_cntl_word_7); + + // extended control word addr, data + uint8_t ext_func[2] = { 0xAC, 0x04}; // MRS_CTRL = 0xAC; snoop/forward/store + uint8_t rcw = 7; + uint64_t rcd0_15[2] = { 0x0000000D00000000ll, // select FN 13 dimm0 + 0x0000000D00000000ll }; // " dimm1 + + // set FN 13 via RC 7 + rc = mss_spec_rcd_load( i_target, i_port_number, &rcw, 1, rcd0_15, io_ccs_inst_cnt,1); + if(rc) + { + FAPI_ERR(" spec_rcd_load Failed rc = 0x%08X (creator = %d)", + uint32_t(rc), rc.getCreator()); + return rc; + } + + func13_rcd_number_array_size = 4; + p_func_num_arr = func13_rcd_number_array_u8; + + data_buff_rcd_word.clearBit(0,64); + data_buff_rcd_word.insertFromRight(&l_rcd_cntl_word_7, 28,4); // select F13 + + // set func_rcd_control_word[dimm_number] + if ( num_ranks_array[i_port_number][dimm_number] != 0 ) { + // load address + data_buff_rcd_word.insertFromRight(ext_func[0],40,4); // lsb address + data_buff_rcd_word.insert(ext_func[0],44,4); // msb address + // load data + data_buff_rcd_word.insertFromRight(ext_func[1], 56,4); // lsb data + data_buff_rcd_word.insert(ext_func[1], 60,4); // msb data + + func_rcd_control_word[dimm_number] = data_buff_rcd_word.getDoubleWord(0); + if(rc) return rc; + } // end if has ranks + + // load CCS with F13 RC 10:11, 14:15 + rc = mss_spec_rcd_load( i_target, i_port_number, p_func_num_arr, func13_rcd_number_array_size, + func_rcd_control_word , io_ccs_inst_cnt,1); + if(rc) + { + FAPI_ERR(" spec_rcd_load Failed rc = 0x%08X (creator = %d)", uint32_t(rc), rc.getCreator()); + return rc; + } + + // set FN 0 via RC 7 + rcd0_15[0] = 0; + rcd0_15[1] = 0; + rc = mss_spec_rcd_load( i_target, i_port_number, &rcw, 1, rcd0_15, io_ccs_inst_cnt,1); + if(rc) + { + FAPI_ERR(" spec_rcd_load Failed rc = 0x%08X (creator = %d)", + uint32_t(rc), rc.getCreator()); + return rc; + } + + // force execute of remaining rcd !! not necessary??? !! + // Execute the contents of CCS array + if (io_ccs_inst_cnt > 0) + { + // Set the End bit on the last CCS Instruction + rc = mss_ccs_set_end_bit( i_target, io_ccs_inst_cnt-1); + if(rc) + { + FAPI_ERR("CCS_SET_END_BIT FAILED rc = 0x%08X (creator = %d)", uint32_t(rc), rc.getCreator()); + return rc; + } + + rc = mss_execute_ccs_inst_array(i_target, 10, 10); + if(rc) + { + FAPI_ERR(" EXECUTE_CCS_INST_ARRAY FAILED rc = 0x%08X (creator = %d)", uint32_t(rc), rc.getCreator()); + return rc; + } + + io_ccs_inst_cnt = 0; + } + // end force execute of rcd + + // Set RTT_nom, rtt_wr, driver impdance through MR1 + for ( rank_number = 0; rank_number < num_ranks; rank_number++) + { + FAPI_INF( "MRS SETTINGS FOR PORT%d DIMM%d RANK%d", i_port_number, dimm_number, rank_number); + + rc_num = rc_num | csn_8.setBit(0,8); + rc_num = rc_num | address_16.clearBit(0, 16); + + if (dram_rtt_nom[i_port_number][dimm_number][rank_number] == ENUM_ATTR_EFF_DRAM_RTT_NOM_DISABLE) + { + dram_rtt_nom[i_port_number][dimm_number][rank_number] = 0x00; + } + else if (dram_rtt_nom[i_port_number][dimm_number][rank_number] == ENUM_ATTR_EFF_DRAM_RTT_NOM_OHM20) + { + dram_rtt_nom[i_port_number][dimm_number][rank_number] = 0x20; + } + else if (dram_rtt_nom[i_port_number][dimm_number][rank_number] == ENUM_ATTR_EFF_DRAM_RTT_NOM_OHM30) + { + dram_rtt_nom[i_port_number][dimm_number][rank_number] = 0xA0; + } + else if (dram_rtt_nom[i_port_number][dimm_number][rank_number] == ENUM_ATTR_EFF_DRAM_RTT_NOM_OHM40) + { + dram_rtt_nom[i_port_number][dimm_number][rank_number] = 0xC0; + } + else if (dram_rtt_nom[i_port_number][dimm_number][rank_number] == ENUM_ATTR_EFF_DRAM_RTT_NOM_OHM60) + { + dram_rtt_nom[i_port_number][dimm_number][rank_number] = 0x80; + } + else if (dram_rtt_nom[i_port_number][dimm_number][rank_number] == ENUM_ATTR_EFF_DRAM_RTT_NOM_OHM120) + { + dram_rtt_nom[i_port_number][dimm_number][rank_number] = 0x40; + } + + if (out_drv_imp_cntl[i_port_number][dimm_number] == ENUM_ATTR_EFF_DRAM_RON_OHM40) + { + out_drv_imp_cntl[i_port_number][dimm_number] = 0x00; + } + else if (out_drv_imp_cntl[i_port_number][dimm_number] == ENUM_ATTR_EFF_DRAM_RON_OHM34) + { + out_drv_imp_cntl[i_port_number][dimm_number] = 0x80; + } + + + rc_num = rc_num | mrs1.insert((uint8_t) dll_enable, 0, 1, 0); + rc_num = rc_num | mrs1.insert((uint8_t) out_drv_imp_cntl[i_port_number][dimm_number], 1, 1, 0); + rc_num = rc_num | mrs1.insert((uint8_t) dram_rtt_nom[i_port_number][dimm_number][rank_number], 2, 1, 0); + rc_num = rc_num | mrs1.insert((uint8_t) dram_al, 3, 2, 0); + rc_num = rc_num | mrs1.insert((uint8_t) out_drv_imp_cntl[i_port_number][dimm_number], 5, 1, 1); + rc_num = rc_num | mrs1.insert((uint8_t) dram_rtt_nom[i_port_number][dimm_number][rank_number], 6, 1, 1); + rc_num = rc_num | mrs1.insert((uint8_t) wr_lvl, 7, 1, 0); + rc_num = rc_num | mrs1.insert((uint8_t) 0x00, 8, 1); + rc_num = rc_num | mrs1.insert((uint8_t) dram_rtt_nom[i_port_number][dimm_number][rank_number], 9, 1, 2); + rc_num = rc_num | mrs1.insert((uint8_t) 0x00, 10, 1); + rc_num = rc_num | mrs1.insert((uint8_t) tdqs_enable, 11, 1, 0); + rc_num = rc_num | mrs1.insert((uint8_t) q_off, 12, 1, 0); + rc_num = rc_num | mrs1.insert((uint8_t) 0x00, 13, 3); + + rc_num = rc_num | mrs1.extractPreserve(&MRS1, 0, 16, 0); + + FAPI_INF( "MRS 1: 0x%04X", MRS1); + + if (rc_num) + { + FAPI_ERR( "mss_mrs_load: Error setting up buffers"); + rc_buff.setEcmdError(rc_num); + return rc_buff; + } + + // Only corresponding CS to rank + rc_num = rc_num | csn_8.setBit(0,8); + rc_num = rc_num | csn_8.insert(lrdimm_cs8n[rank_number],(4*dimm_number),4,4); + mrs_number = 2; + + // Copying the current MRS into address buffer matching the MRS_array order + // Setting the bank address + rc_num = rc_num | address_16.insert(mrs1, 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; + } + + if (( address_mirror_map[i_port_number][dimm_number] & (0x08 >> rank_number) ) && (is_sim == 0)) + { + rc = mss_address_mirror_swizzle(i_target, i_port_number, dimm_number, rank_number, address_16, bank_3); + } + + + if (dram_2n_mode == ENUM_ATTR_EFF_DRAM_2N_MODE_ENABLED_TRUE) + { + + // 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_setup_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_setup_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 ++; + } + + // 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 ++; + + } // end rank loop + + // turn on MRS broadcast + + l_rcd_cntl_word_7 = 0; + + for (uint8_t dimm_num = 0;dimm_num < MAX_NUM_DIMMS; dimm_num++) + { + + if ( num_ranks_array[i_port_number][dimm_num] != 0 ) + { + l_rcd_cntl_word_14 = (rcd_array[i_port_number][dimm_num] & 0xF0) >> 4; // MRS broadcast + FAPI_INF("current F0RC14 = 0x%X",l_rcd_cntl_word_14); + l_rcd_cntl_word_14 = l_rcd_cntl_word_14 & 0xB; + FAPI_INF("setting F0RC14 = 0x%X",l_rcd_cntl_word_14); + ecmdDataBufferBase data_buff_rcd_word(64); + data_buff_rcd_word.clearBit(0,64); + data_buff_rcd_word.insertFromRight(&l_rcd_cntl_word_14, 56,4); + func_rcd_control_word[dimm_num] = data_buff_rcd_word.getDoubleWord(0); + if(rc) return rc; + } + } + + FAPI_INF("SELECTING FUNCTION %d", l_rcd_cntl_word_7); + + func0_rcd_number_array_size = 2; + p_func_num_arr = func0_rcd_number_array_u8; + rc = mss_spec_rcd_load(i_target, i_port_number, p_func_num_arr, func0_rcd_number_array_size, + func_rcd_control_word , io_ccs_inst_cnt,1); + if(rc) + { + FAPI_ERR(" spec_rcd_load Failed rc = 0x%08X (creator = %d)", uint32_t(rc), rc.getCreator()); + return rc; + } + + + // set FN 0 via RC 7 + func_rcd_control_word[0]=0; + func_rcd_control_word[1]=0; + func0_rcd_number_array_u8 [0] = 7; + rc = mss_spec_rcd_load( i_target, i_port_number, p_func_num_arr, 1, + func_rcd_control_word, io_ccs_inst_cnt,1); + + if(rc) + { + FAPI_ERR(" spec_rcd_load Failed rc = 0x%08X (creator = %d)", uint32_t(rc), rc.getCreator()); + return rc; + } + // end turn on MRS broadcast + + // Enable MRS snooping + l_rcd_cntl_word_7 = 13; + FAPI_INF("SELECTING FUNCTION %d", l_rcd_cntl_word_7); + + // extended control word data + ext_func[1] = 0x00; // MRS_CTRL = 0xAC; snoop/forward/store + rcw = 7; + rcd0_15[0] = 0x0000000D00000000ll; // select FN 13 dimm0 + rcd0_15[1] = 0x0000000D00000000ll ; // " dimm1 + + // set FN 13 via RC 7 + rc = mss_spec_rcd_load( i_target, i_port_number, &rcw, 1, rcd0_15, io_ccs_inst_cnt,1); + if(rc) + { + FAPI_ERR(" spec_rcd_load Failed rc = 0x%08X (creator = %d)", + uint32_t(rc), rc.getCreator()); + return rc; + } + + func13_rcd_number_array_size = 4; + p_func_num_arr = func13_rcd_number_array_u8; + + data_buff_rcd_word.clearBit(0,64); + data_buff_rcd_word.insertFromRight(&l_rcd_cntl_word_7, 28,4); // select F13 + + // set func_rcd_control_word[dimm_number] + if ( num_ranks_array[i_port_number][dimm_number] != 0 ) { + // load address + data_buff_rcd_word.insertFromRight(ext_func[0],40,4); // lsb address + data_buff_rcd_word.insert(ext_func[0],44,4); // msb address + // load data + data_buff_rcd_word.insertFromRight(ext_func[1], 56,4); // lsb data + data_buff_rcd_word.insert(ext_func[1], 60,4); // msb data + + func_rcd_control_word[dimm_number] = data_buff_rcd_word.getDoubleWord(0); if(rc) return rc; + } // end if has ranks + + + // load CCS with F13 RC 10:11, 14:15 + rc = mss_spec_rcd_load( i_target, i_port_number, p_func_num_arr, func13_rcd_number_array_size, + func_rcd_control_word , io_ccs_inst_cnt,1); + if(rc) + { + FAPI_ERR(" spec_rcd_load Failed rc = 0x%08X (creator = %d)", uint32_t(rc), rc.getCreator()); + return rc; + } + + // set FN 0 via RC 7 + rcd0_15[0] = 0; + rcd0_15[1] = 0; + rc = mss_spec_rcd_load( i_target, i_port_number, &rcw, 1, rcd0_15, io_ccs_inst_cnt,1); + if(rc) + { + FAPI_ERR(" spec_rcd_load Failed rc = 0x%08X (creator = %d)", + uint32_t(rc), rc.getCreator()); + return rc; + } + + // force execute of remaining rcd !! not necessary??? !! + // Execute the contents of CCS array + if (io_ccs_inst_cnt > 0) + { + // Set the End bit on the last CCS Instruction + rc = mss_ccs_set_end_bit( i_target, io_ccs_inst_cnt-1); + if(rc) + { + FAPI_ERR("CCS_SET_END_BIT FAILED rc = 0x%08X (creator = %d)", uint32_t(rc), rc.getCreator()); + return rc; + } + + rc = mss_execute_ccs_inst_array(i_target, 10, 10); + if(rc) + { + FAPI_ERR(" EXECUTE_CCS_INST_ARRAY FAILED rc = 0x%08X (creator = %d)", uint32_t(rc), rc.getCreator()); + return rc; + } + + io_ccs_inst_cnt = 0; + } + // end force execute of rcd + // End enable MRS snooping + + + return rc; +} + +fapi::ReturnCode mss_execute_lrdimm_mb_dram_training(Target &i_target) +{ + ReturnCode rc; + uint8_t l_rcd_cntl_word_7; + uint8_t l_rcd_cntl_word_12; + ecmdDataBufferBase data_buff_rcd_word(64); + uint32_t port; + uint8_t dimm_number; + const uint8_t MAX_NUM_DIMMS = 2; + const uint8_t MAX_NUM_PORT = 2; + uint8_t num_ranks_array[MAX_NUM_PORT][MAX_NUM_DIMMS]; + uint64_t func_rcd_control_word[2]; + uint8_t *p_func_num_arr; + uint8_t funcTRAIN_rcd_number_array_u8[2] = {7,12}; + + uint32_t ccs_inst_cnt = 0; + 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.setBit(0); + ecmdDataBufferBase casn_1(1); + rc_num = rc_num | casn_1.setBit(0); + ecmdDataBufferBase wen_1(1); + rc_num = rc_num | wen_1.setBit(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,2); + rc_num = rc_num | csn_8.setBit(4,2); + ecmdDataBufferBase odt_4(4); + rc_num = rc_num | odt_4.setBit(0,4); + ecmdDataBufferBase ddr_cal_type_4(4); + + if(rc_num) + { + rc.setEcmdError(rc_num); + return rc; + } + 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); + + uint32_t l_mss_freq; + uint32_t l_num_idles_delay=20; + + fapi::Target l_target_centaur; + rc = fapiGetParentChip(i_target, l_target_centaur); + if(rc) return rc; + + rc = FAPI_ATTR_GET(ATTR_MSS_FREQ, &l_target_centaur, l_mss_freq); + if(rc) return rc; + + rc = FAPI_ATTR_GET(ATTR_EFF_NUM_RANKS_PER_DIMM, &i_target, num_ranks_array); + if(rc) return rc; + + for ( port = 0; port < MAX_NUM_PORT; port++ ) + { + // MB-DRAM training + l_rcd_cntl_word_7 = 0; + l_rcd_cntl_word_12 = 2; // Training control, start DRAM interface training + + data_buff_rcd_word.clearBit(0,64); + data_buff_rcd_word.insertFromRight(&l_rcd_cntl_word_7, 28, 4); + data_buff_rcd_word.insertFromRight(&l_rcd_cntl_word_12, 48, 4); + + for ( dimm_number = 0; dimm_number < MAX_NUM_DIMMS; dimm_number++ ) + { + if ( num_ranks_array[port][dimm_number] != 0 ) + { + func_rcd_control_word[dimm_number] = data_buff_rcd_word.getDoubleWord(0); + if(rc) return rc; + } + } + + FAPI_INF("SELECTING FUNCTION %d", l_rcd_cntl_word_7); + p_func_num_arr = funcTRAIN_rcd_number_array_u8; + rc = mss_spec_rcd_load(i_target, port, p_func_num_arr, + (uint8_t) sizeof(funcTRAIN_rcd_number_array_u8)/(uint8_t)sizeof(funcTRAIN_rcd_number_array_u8[0]), + func_rcd_control_word , ccs_inst_cnt,1); + if(rc) + { + FAPI_ERR(" spec_rcd_load Failed rc = 0x%08X (creator = %d)", uint32_t(rc), rc.getCreator()); + return rc; + } + + + rc_num = rc_num | address_16.clearBit(0, 16); + rc_num = rc_num | num_idles_16.insertFromRight((uint32_t) l_num_idles_delay, 0, 16); + if(rc_num) + { + rc.setEcmdError(rc_num); + return rc; + } + + rc = mss_ccs_inst_arry_0( i_target, + 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, + port); + if(rc) return rc; + rc = mss_ccs_inst_arry_1( i_target, + 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; + ccs_inst_cnt++; + } + + // Execute the contents of CCS array + if (ccs_inst_cnt > 0) + { + // Set the End bit on the last CCS Instruction + rc = mss_ccs_set_end_bit( i_target, ccs_inst_cnt-1); + if(rc) + { + FAPI_ERR("CCS_SET_END_BIT FAILED rc = 0x%08X (creator = %d)", uint32_t(rc), rc.getCreator()); + return rc; + } + + rc = mss_execute_ccs_inst_array(i_target, 10, 10); + if(rc) + { + FAPI_ERR(" EXECUTE_CCS_INST_ARRAY FAILED rc = 0x%08X (creator = %d)", uint32_t(rc), rc.getCreator()); + return rc; + } + + ccs_inst_cnt = 0; + }// end force execute of rcd + return rc; +} + +fapi::ReturnCode mss_lrdimm_eff_config(const Target &i_target_mba, + uint8_t cur_dimm_spd_valid_u8array[PORT_SIZE][DIMM_SIZE], + uint32_t mss_freq, uint8_t eff_num_ranks_per_dimm[PORT_SIZE][DIMM_SIZE]) +{ + ReturnCode rc; + + std::vector<fapi::Target> l_target_dimm_array; + uint8_t l_cur_mba_port = 0; + uint8_t l_cur_mba_dimm = 0; + + mss_lrdimm_spd_data *p_l_lr_spd_data = new mss_lrdimm_spd_data(); + memset( p_l_lr_spd_data, 0, sizeof(mss_lrdimm_spd_data) ); + + uint8_t lrdimm_mr12_reg[PORT_SIZE][DIMM_SIZE]; + uint64_t lrdimm_additional_cntl_words[PORT_SIZE][DIMM_SIZE]; + uint8_t lrdimm_rank_mult_mode; + uint8_t eff_ibm_type[PORT_SIZE][DIMM_SIZE]; + uint64_t eff_dimm_rcd_cntl_word_0_15[PORT_SIZE][DIMM_SIZE]; + + do + { + rc = fapiGetAssociatedDimms(i_target_mba, l_target_dimm_array); + if(rc) + { + FAPI_ERR("Error retrieving assodiated dimms"); + FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR); + break; + } + + for (uint8_t l_dimm_index = 0; l_dimm_index < l_target_dimm_array.size(); l_dimm_index += 1) + { + rc = FAPI_ATTR_GET(ATTR_MBA_PORT, &l_target_dimm_array[l_dimm_index], + l_cur_mba_port); + if(rc) + { + FAPI_ERR("Error retrieving ATTR_MBA_PORT"); + FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR); + break; + } + //------------------------------------------------------------------------ + rc = FAPI_ATTR_GET(ATTR_MBA_DIMM, &l_target_dimm_array[l_dimm_index], l_cur_mba_dimm); + if(rc) + { + FAPI_ERR("Error retrieving ATTR_MBA_DIMM"); + FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR); + break; + } + + // Setup SPD attributes + rc = FAPI_ATTR_GET(ATTR_SPD_LR_ADDR_MIRRORING, &l_target_dimm_array[l_dimm_index], + p_l_lr_spd_data->lr_addr_mirroring[l_cur_mba_port][l_cur_mba_dimm]); + if(rc) break; + rc = FAPI_ATTR_GET(ATTR_SPD_LR_F0RC3_F0RC2, &l_target_dimm_array[l_dimm_index], + p_l_lr_spd_data->lr_f0rc3_f0rc2[l_cur_mba_port][l_cur_mba_dimm]); + if(rc) break; + rc = FAPI_ATTR_GET(ATTR_SPD_LR_F0RC5_F0RC4, &l_target_dimm_array[l_dimm_index], + p_l_lr_spd_data->lr_f0rc5_f0rc4[l_cur_mba_port][l_cur_mba_dimm]); + if(rc) break; + rc = FAPI_ATTR_GET(ATTR_SPD_LR_F1RC11_F1RC8, &l_target_dimm_array[l_dimm_index], + p_l_lr_spd_data->lr_f1rc11_f1rc8[l_cur_mba_port][l_cur_mba_dimm]); + if(rc) break; + rc = FAPI_ATTR_GET(ATTR_SPD_LR_F1RC13_F1RC12, &l_target_dimm_array[l_dimm_index], + p_l_lr_spd_data->lr_f1rc13_f1rc12[l_cur_mba_port][l_cur_mba_dimm]); + if(rc) break; + rc = FAPI_ATTR_GET(ATTR_SPD_LR_F1RC15_F1RC14, &l_target_dimm_array[l_dimm_index], + p_l_lr_spd_data->lr_f1rc15_f1rc14[l_cur_mba_port][l_cur_mba_dimm]); + if(rc) break; + rc = FAPI_ATTR_GET(ATTR_SPD_LR_F3RC9_F3RC8_FOR_800_1066, &l_target_dimm_array[l_dimm_index], + p_l_lr_spd_data->lr_f3rc9_f3rc8_for_800_1066[l_cur_mba_port][l_cur_mba_dimm]); + if(rc) break; + rc = FAPI_ATTR_GET(ATTR_SPD_LR_F34RC11_F34RC10_FOR_800_1066, &l_target_dimm_array[l_dimm_index], + p_l_lr_spd_data->lr_f34rc11_f34rc10_for_800_1066[l_cur_mba_port][l_cur_mba_dimm]); + if(rc) break; + rc = FAPI_ATTR_GET(ATTR_SPD_LR_F56RC11_F56RC10_FOR_800_1066, &l_target_dimm_array[l_dimm_index], + p_l_lr_spd_data->lr_f56rc11_f56rc10_for_800_1066[l_cur_mba_port][l_cur_mba_dimm]); + if(rc) break; + rc = FAPI_ATTR_GET(ATTR_SPD_LR_F78RC11_F78RC10_FOR_800_1066, &l_target_dimm_array[l_dimm_index], + p_l_lr_spd_data->lr_f78rc11_f78rc10_for_800_1066[l_cur_mba_port][l_cur_mba_dimm]); + if(rc) break; + rc = FAPI_ATTR_GET(ATTR_SPD_LR_F910RC11_F910RC10_FOR_800_1066, &l_target_dimm_array[l_dimm_index], + p_l_lr_spd_data->lr_f910rc11_f910rc10_for_800_1066[l_cur_mba_port][l_cur_mba_dimm]); + if(rc) break; + rc = FAPI_ATTR_GET(ATTR_SPD_LR_MR12_FOR_800_1066, &l_target_dimm_array[l_dimm_index], + p_l_lr_spd_data->lr_mr12_for_800_1066[l_cur_mba_port][l_cur_mba_dimm]); + if(rc) break; + rc = FAPI_ATTR_GET(ATTR_SPD_LR_F3RC9_F3RC8_FOR_1333_1600, &l_target_dimm_array[l_dimm_index], + p_l_lr_spd_data->lr_f3rc9_f3rc8_for_1333_1600[l_cur_mba_port][l_cur_mba_dimm]); + if(rc) break; + rc = FAPI_ATTR_GET(ATTR_SPD_LR_F34RC11_F34RC10_FOR_1333_1600, &l_target_dimm_array[l_dimm_index], + p_l_lr_spd_data->lr_f34rc11_f34rc10_for_1333_1600[l_cur_mba_port][l_cur_mba_dimm]); + if(rc) break; + rc = FAPI_ATTR_GET(ATTR_SPD_LR_F56RC11_F56RC10_FOR_1333_1600, &l_target_dimm_array[l_dimm_index], + p_l_lr_spd_data->lr_f56rc11_f56rc10_for_1333_1600[l_cur_mba_port][l_cur_mba_dimm]); + if(rc) break; + rc = FAPI_ATTR_GET(ATTR_SPD_LR_F78RC11_F78RC10_FOR_1333_1600, &l_target_dimm_array[l_dimm_index], + p_l_lr_spd_data->lr_f78rc11_f78rc10_for_1333_1600[l_cur_mba_port][l_cur_mba_dimm]); + if(rc) break; + rc = FAPI_ATTR_GET(ATTR_SPD_LR_F910RC11_F910RC10_FOR_1333_1600, &l_target_dimm_array[l_dimm_index], + p_l_lr_spd_data->lr_f910rc11_f910rc10_for_1333_1600[l_cur_mba_port][l_cur_mba_dimm]); + if(rc) break; + rc = FAPI_ATTR_GET(ATTR_SPD_LR_MR12_FOR_1333_1600, &l_target_dimm_array[l_dimm_index], + p_l_lr_spd_data->lr_mr12_for_1333_1600[l_cur_mba_port][l_cur_mba_dimm]); + if(rc) break; + rc = FAPI_ATTR_GET(ATTR_SPD_LR_F3RC9_F3RC8_FOR_1866_2133, &l_target_dimm_array[l_dimm_index], + p_l_lr_spd_data->lr_f3rc9_f3rc8_for_1866_2133[l_cur_mba_port][l_cur_mba_dimm]); + if(rc) break; + rc = FAPI_ATTR_GET(ATTR_SPD_LR_F34RC11_F34RC10_FOR_1866_2133, &l_target_dimm_array[l_dimm_index], + p_l_lr_spd_data->lr_f34rc11_f34rc10_for_1866_2133[l_cur_mba_port][l_cur_mba_dimm]); + if(rc) break; + rc = FAPI_ATTR_GET(ATTR_SPD_LR_F56RC11_F56RC10_FOR_1866_2133, &l_target_dimm_array[l_dimm_index], + p_l_lr_spd_data->lr_f56rc11_f56rc10_for_1866_2133[l_cur_mba_port][l_cur_mba_dimm]); + if(rc) break; + rc = FAPI_ATTR_GET(ATTR_SPD_LR_F78RC11_F78RC10_FOR_1866_2133, &l_target_dimm_array[l_dimm_index], + p_l_lr_spd_data->lr_f78rc11_f78rc10_for_1866_2133[l_cur_mba_port][l_cur_mba_dimm]); + if(rc) break; + rc = FAPI_ATTR_GET(ATTR_SPD_LR_F910RC11_F910RC10_FOR_1866_2133, &l_target_dimm_array[l_dimm_index], + p_l_lr_spd_data->lr_f910rc11_f910rc10_for_1866_2133[l_cur_mba_port][l_cur_mba_dimm]); + if(rc) break; + rc = FAPI_ATTR_GET(ATTR_SPD_LR_MR12_FOR_1866_2133, &l_target_dimm_array[l_dimm_index], + p_l_lr_spd_data->lr_mr12_for_1866_2133[l_cur_mba_port][l_cur_mba_dimm]); + if(rc) break; + } + + if(rc) + { + FAPI_ERR("Error reading spd data from caller"); + FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR); + break; + } + + + // Setup attributes + for (int l_cur_mba_port = 0; l_cur_mba_port < PORT_SIZE; l_cur_mba_port += 1) + { + for (int l_cur_mba_dimm = 0; l_cur_mba_dimm < DIMM_SIZE; l_cur_mba_dimm += 1) + { + if (cur_dimm_spd_valid_u8array[l_cur_mba_port][l_cur_mba_dimm] == MSS_EFF_VALID) + { + FAPI_INF(" !! LRDIMM Detected -MW"); + + ecmdDataBuffer rcd(64); + rcd.flushTo0(); + + rcd.setDoubleWord(0,eff_dimm_rcd_cntl_word_0_15[l_cur_mba_port][l_cur_mba_dimm]); + FAPI_INF("rcd0_15=0x%016llX",rcd.getDoubleWord(0)); + + rcd.insert(p_l_lr_spd_data->lr_f0rc3_f0rc2[l_cur_mba_port][l_cur_mba_dimm],12,4,0); //rcd3 + rcd.insert(p_l_lr_spd_data->lr_f0rc3_f0rc2[l_cur_mba_port][l_cur_mba_dimm],8,4,4); //rcd2 + + rcd.insert(p_l_lr_spd_data->lr_f0rc5_f0rc4[l_cur_mba_port][l_cur_mba_dimm],20,4,0); //rcd5 + rcd.insert(p_l_lr_spd_data->lr_f0rc5_f0rc4[l_cur_mba_port][l_cur_mba_dimm],16,4,4); //rcd4 + + rcd.insert(p_l_lr_spd_data->lr_addr_mirroring[l_cur_mba_port][l_cur_mba_dimm],59,1,7); // address mirroring + + eff_dimm_rcd_cntl_word_0_15[l_cur_mba_port][l_cur_mba_dimm]=rcd.getDoubleWord(0); + + ecmdDataBuffer rcd_1(64); + rcd_1.flushTo0(); + // F[1]RC11,8 + rcd_1.insert(p_l_lr_spd_data->lr_f1rc11_f1rc8[l_cur_mba_port][l_cur_mba_dimm],44,4,0); //F[1]RC11 -> rcd11 + rcd_1.insert(p_l_lr_spd_data->lr_f1rc11_f1rc8[l_cur_mba_port][l_cur_mba_dimm],32,4,4); //F[1]RC8 -> rcd8 + + // F[1]RC13,12 + rcd_1.insert(p_l_lr_spd_data->lr_f1rc13_f1rc12[l_cur_mba_port][l_cur_mba_dimm],52,4,0); //F[1]RC13 -> rcd13 + rcd_1.insert(p_l_lr_spd_data->lr_f1rc13_f1rc12[l_cur_mba_port][l_cur_mba_dimm],48,4,4); //F[1]RC12 -> rcd12 + + // F[1]RC15,14 + rcd_1.insert(p_l_lr_spd_data->lr_f1rc15_f1rc14[l_cur_mba_port][l_cur_mba_dimm],60,4,0); //F[1]RC15 -> rcd15 + rcd_1.insert(p_l_lr_spd_data->lr_f1rc15_f1rc14[l_cur_mba_port][l_cur_mba_dimm],56,4,4); //F[1]RC14 -> rcd14 + + + if ( mss_freq > 1733 ) { + rcd_1.insert(p_l_lr_spd_data->lr_f3rc9_f3rc8_for_1866_2133[l_cur_mba_port][l_cur_mba_dimm],36,4,0); // F[3]RC9 -> rcd9 + rcd_1.insert(p_l_lr_spd_data->lr_f3rc9_f3rc8_for_1866_2133[l_cur_mba_port][l_cur_mba_dimm],40,4,4); // F[3]RC8 -> rcd10 + rcd_1.insert(p_l_lr_spd_data->lr_f34rc11_f34rc10_for_1866_2133[l_cur_mba_port][l_cur_mba_dimm],4,4,0); // F[3,4]RC11 -> rcd1 + rcd_1.insert(p_l_lr_spd_data->lr_f34rc11_f34rc10_for_1866_2133[l_cur_mba_port][l_cur_mba_dimm],0,4,4); // F[3,4]RC10 -> rcd0 + rcd_1.insert(p_l_lr_spd_data->lr_f56rc11_f56rc10_for_1866_2133[l_cur_mba_port][l_cur_mba_dimm],12,4,0); // F[6,6]RC11 -> rcd3 + rcd_1.insert(p_l_lr_spd_data->lr_f56rc11_f56rc10_for_1866_2133[l_cur_mba_port][l_cur_mba_dimm],8,4,4); // F[5,6]RC10 -> rcd2 + rcd_1.insert(p_l_lr_spd_data->lr_f78rc11_f78rc10_for_1866_2133[l_cur_mba_port][l_cur_mba_dimm],20,4,0); // F[7,8]RC11 -> rcd5 + rcd_1.insert(p_l_lr_spd_data->lr_f78rc11_f78rc10_for_1866_2133[l_cur_mba_port][l_cur_mba_dimm],16,4,4); // F[7,8]RC10 -> rcd4 + rcd_1.insert(p_l_lr_spd_data->lr_f910rc11_f910rc10_for_1866_2133[l_cur_mba_port][l_cur_mba_dimm],28,4,0); // F[9,10]RC11 -> rcd7 + rcd_1.insert(p_l_lr_spd_data->lr_f910rc11_f910rc10_for_1866_2133[l_cur_mba_port][l_cur_mba_dimm],24,4,4); // F[9,10]RC10 -> rcd6 + + lrdimm_mr12_reg[l_cur_mba_port][l_cur_mba_dimm] = p_l_lr_spd_data->lr_mr12_for_1866_2133[l_cur_mba_port][l_cur_mba_dimm]; + + } else if ( mss_freq > 1200 ) { + rcd_1.insert(p_l_lr_spd_data->lr_f3rc9_f3rc8_for_1333_1600[l_cur_mba_port][l_cur_mba_dimm],36,4,0); // F[3]RC9 -> rcd9 + rcd_1.insert(p_l_lr_spd_data->lr_f3rc9_f3rc8_for_1333_1600[l_cur_mba_port][l_cur_mba_dimm],40,4,4); // F[3]RC8 -> rcd10 + rcd_1.insert(p_l_lr_spd_data->lr_f34rc11_f34rc10_for_1333_1600[l_cur_mba_port][l_cur_mba_dimm],4,4,0); // F[3,4]RC11 -> rcd1 + rcd_1.insert(p_l_lr_spd_data->lr_f34rc11_f34rc10_for_1333_1600[l_cur_mba_port][l_cur_mba_dimm],0,4,4); // F[3,4]RC10 -> rcd0 + rcd_1.insert(p_l_lr_spd_data->lr_f56rc11_f56rc10_for_1333_1600[l_cur_mba_port][l_cur_mba_dimm],12,4,0); // F[6,6]RC11 -> rcd3 + rcd_1.insert(p_l_lr_spd_data->lr_f56rc11_f56rc10_for_1333_1600[l_cur_mba_port][l_cur_mba_dimm],8,4,4); // F[5,6]RC10 -> rcd2 + rcd_1.insert(p_l_lr_spd_data->lr_f78rc11_f78rc10_for_1333_1600[l_cur_mba_port][l_cur_mba_dimm],20,4,0); // F[7,8]RC11 -> rcd5 + rcd_1.insert(p_l_lr_spd_data->lr_f78rc11_f78rc10_for_1333_1600[l_cur_mba_port][l_cur_mba_dimm],16,4,4); // F[7,8]RC10 -> rcd4 + rcd_1.insert(p_l_lr_spd_data->lr_f910rc11_f910rc10_for_1333_1600[l_cur_mba_port][l_cur_mba_dimm],28,4,0); // F[9,10]RC11 -> rcd7 + rcd_1.insert(p_l_lr_spd_data->lr_f910rc11_f910rc10_for_1333_1600[l_cur_mba_port][l_cur_mba_dimm],24,4,4); // F[9,10]RC10 -> rcd6 + + lrdimm_mr12_reg[l_cur_mba_port][l_cur_mba_dimm] = p_l_lr_spd_data->lr_mr12_for_1333_1600[l_cur_mba_port][l_cur_mba_dimm]; + + } else { + rcd_1.insert(p_l_lr_spd_data->lr_f3rc9_f3rc8_for_800_1066[l_cur_mba_port][l_cur_mba_dimm],36,4,0); // F[3]RC9 -> rcd9 + rcd_1.insert(p_l_lr_spd_data->lr_f3rc9_f3rc8_for_800_1066[l_cur_mba_port][l_cur_mba_dimm],40,4,4); // F[3]RC8 -> rcd10 + rcd_1.insert(p_l_lr_spd_data->lr_f34rc11_f34rc10_for_800_1066[l_cur_mba_port][l_cur_mba_dimm],4,4,0); // F[3,4]RC11 -> rcd1 + rcd_1.insert(p_l_lr_spd_data->lr_f34rc11_f34rc10_for_800_1066[l_cur_mba_port][l_cur_mba_dimm],0,4,4); // F[3,4]RC10 -> rcd0 + rcd_1.insert(p_l_lr_spd_data->lr_f56rc11_f56rc10_for_800_1066[l_cur_mba_port][l_cur_mba_dimm],12,4,0); // F[6,6]RC11 -> rcd3 + rcd_1.insert(p_l_lr_spd_data->lr_f56rc11_f56rc10_for_800_1066[l_cur_mba_port][l_cur_mba_dimm],8,4,4); // F[5,6]RC10 -> rcd2 + rcd_1.insert(p_l_lr_spd_data->lr_f78rc11_f78rc10_for_800_1066[l_cur_mba_port][l_cur_mba_dimm],20,4,0); // F[7,8]RC11 -> rcd5 + rcd_1.insert(p_l_lr_spd_data->lr_f78rc11_f78rc10_for_800_1066[l_cur_mba_port][l_cur_mba_dimm],16,4,4); // F[7,8]RC10 -> rcd4 + rcd_1.insert(p_l_lr_spd_data->lr_f910rc11_f910rc10_for_800_1066[l_cur_mba_port][l_cur_mba_dimm],28,4,0); // F[9,10]RC11 -> rcd7 + rcd_1.insert(p_l_lr_spd_data->lr_f910rc11_f910rc10_for_800_1066[l_cur_mba_port][l_cur_mba_dimm],24,4,4); // F[9,10]RC10 -> rcd6 + + lrdimm_mr12_reg[l_cur_mba_port][l_cur_mba_dimm] = p_l_lr_spd_data->lr_mr12_for_800_1066[l_cur_mba_port][l_cur_mba_dimm]; + } + + uint64_t rcd1 = rcd_1.getDoubleWord(0); + lrdimm_additional_cntl_words[l_cur_mba_port][l_cur_mba_dimm] = rcd1; + + if ( eff_num_ranks_per_dimm[l_cur_mba_port][l_cur_mba_dimm] == 8 ) { + lrdimm_rank_mult_mode = 4; // Default for 8R is 4x mult mode + } + + // ======================================================================================== + + + // FIX finding stack type properly. + if ( eff_num_ranks_per_dimm[l_cur_mba_port][l_cur_mba_dimm] == 1 ) { + //p_o_atts->eff_stack_type[l_cur_mba_port][l_cur_mba_dimm] = fapi::ENUM_ATTR_EFF_STACK_TYPE_NONE; + eff_ibm_type[l_cur_mba_port][l_cur_mba_dimm] = fapi::ENUM_ATTR_EFF_IBM_TYPE_TYPE_5A; + } else if ( eff_num_ranks_per_dimm[l_cur_mba_port][l_cur_mba_dimm] == 2 ) { + //p_o_atts->eff_stack_type[l_cur_mba_port][l_cur_mba_dimm] = fapi::ENUM_ATTR_EFF_STACK_TYPE_NONE; + eff_ibm_type[l_cur_mba_port][l_cur_mba_dimm] = fapi::ENUM_ATTR_EFF_IBM_TYPE_TYPE_5B; + } else if ( eff_num_ranks_per_dimm[l_cur_mba_port][l_cur_mba_dimm] == 4 ) { + //p_o_atts->eff_stack_type[l_cur_mba_port][l_cur_mba_dimm] = fapi::ENUM_ATTR_EFF_STACK_TYPE_DDP_QDP; + eff_ibm_type[l_cur_mba_port][l_cur_mba_dimm] = fapi::ENUM_ATTR_EFF_IBM_TYPE_TYPE_5C; + } else if ( eff_num_ranks_per_dimm[l_cur_mba_port][l_cur_mba_dimm] == 8 ) { + //p_o_atts->eff_stack_type[l_cur_mba_port][l_cur_mba_dimm] = fapi::ENUM_ATTR_EFF_STACK_TYPE_DDP_QDP; + eff_ibm_type[l_cur_mba_port][l_cur_mba_dimm] = fapi::ENUM_ATTR_EFF_IBM_TYPE_TYPE_5D; + } else { + //p_o_atts->eff_stack_type[l_cur_mba_port][l_cur_mba_dimm] = fapi::ENUM_ATTR_EFF_STACK_TYPE_NONE; + eff_ibm_type[l_cur_mba_port][l_cur_mba_dimm] = fapi::ENUM_ATTR_EFF_IBM_TYPE_UNDEFINED; + FAPI_ERR("Currently unsupported IBM_TYPE on %s!", i_target_mba.toEcmdString()); + FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR); return rc; + } + } // end valid dimm + } // end dimm loop + } // end port loop + + rc = FAPI_ATTR_SET(ATTR_EFF_IBM_TYPE, &i_target_mba, + eff_ibm_type); + rc = FAPI_ATTR_SET(ATTR_LRDIMM_MR12_REG, &i_target_mba, + lrdimm_mr12_reg); + rc = FAPI_ATTR_SET(ATTR_LRDIMM_ADDITIONAL_CNTL_WORDS, &i_target_mba, + lrdimm_additional_cntl_words); + rc = FAPI_ATTR_SET(ATTR_LRDIMM_RANK_MULT_MODE, &i_target_mba, + lrdimm_rank_mult_mode); + rc = FAPI_ATTR_SET(ATTR_EFF_DIMM_RCD_CNTL_WORD_0_15, &i_target_mba, + eff_dimm_rcd_cntl_word_0_15); + + if(rc) + { + FAPI_ERR("Error setting attributes"); + FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR); + break; + } + } while(0); + + return rc; +} + +fapi::ReturnCode mss_lrdimm_rewrite_odt( const Target& i_target_mba, uint32_t * p_b_var_array, uint32_t *var_array_p_array[5]) +{ + ReturnCode rc; + uint8_t l_num_ranks_per_dimm_u8array[PORT_SIZE][DIMM_SIZE]; + uint8_t l_arr_offset; + uint32_t l_mss_freq = 0; + uint8_t l_dram_width_u8; + + uint32_t *odt_array; + + // For dual drop, Set ODT_RD as 2rank (8R LRDIMM) or 4rank (4R LRDIMM) + fapi::Target l_target_centaur; + rc = fapiGetParentChip(i_target_mba, l_target_centaur); if(rc) return rc; + rc = FAPI_ATTR_GET(ATTR_MSS_FREQ, &l_target_centaur, l_mss_freq); if(rc) return rc; + + rc = FAPI_ATTR_GET(ATTR_EFF_NUM_RANKS_PER_DIMM, &i_target_mba, l_num_ranks_per_dimm_u8array); if(rc) return rc; + rc = FAPI_ATTR_GET(ATTR_EFF_DRAM_WIDTH, &i_target_mba, l_dram_width_u8); if(rc) return rc; + + uint8_t l_start=44, l_end=60; + if ( (l_num_ranks_per_dimm_u8array[0][1] == 4) || (l_num_ranks_per_dimm_u8array[1][1] == 4) ) { + odt_array = var_array_p_array[0]; + FAPI_INF("Setting LRDIMM ODT_RD as 4 rank dimm"); + } else if ( (l_num_ranks_per_dimm_u8array[0][1] == 8) || (l_num_ranks_per_dimm_u8array[1][1] == 8) ) { + if ( l_mss_freq <= 1466 ) { // 1333Mbps + if ( l_dram_width_u8 == 4 ) { + odt_array = var_array_p_array[1]; + } else if ( l_dram_width_u8 == 8 ) { + odt_array = var_array_p_array[2]; + } + } else if ( l_mss_freq <= 1733 ) { // 1600 Mbps + if ( l_dram_width_u8 == 4 ) { + odt_array = var_array_p_array[3]; + } else if ( l_dram_width_u8 == 8 ) { + odt_array = var_array_p_array[4]; + } + } + FAPI_INF("Setting LRDIMM ODT_RD as 2 logical rank dimm"); + } + + for ( l_arr_offset = l_start; l_arr_offset < l_end; l_arr_offset++ ) { + *(p_b_var_array + l_arr_offset) = *(odt_array + l_arr_offset); + } + + return rc; +} + +fapi::ReturnCode mss_lrdimm_term_atts(const Target& i_target_mba) +{ + ReturnCode rc; + + uint8_t l_dram_ron[PORT_SIZE][DIMM_SIZE]; + uint8_t l_dram_rtt_wr[PORT_SIZE][DIMM_SIZE]; + uint8_t l_dram_rtt_nom[PORT_SIZE][DIMM_SIZE]; + + uint8_t attr_eff_dram_ron[PORT_SIZE][DIMM_SIZE]; + uint8_t attr_eff_dram_rtt_nom[PORT_SIZE][DIMM_SIZE][RANK_SIZE]; + uint8_t attr_eff_dram_rtt_wr[PORT_SIZE][DIMM_SIZE][RANK_SIZE]; + uint8_t attr_eff_odt_wr[PORT_SIZE][DIMM_SIZE][RANK_SIZE]; + + uint32_t l_mss_freq = 0; + uint32_t l_mss_volt = 0; + uint8_t l_num_ranks_per_dimm_u8array[PORT_SIZE][DIMM_SIZE]; + uint8_t l_num_drops_per_port; + uint8_t l_dram_density; + uint8_t l_dram_width_u8; + + uint8_t l_lrdimm_mr12_u8array[PORT_SIZE][DIMM_SIZE]; + uint8_t l_lrdimm_rank_mult_mode; + + uint8_t l_rcd_cntl_word_0_1; + uint8_t l_rcd_cntl_word_6_7; + uint8_t l_rcd_cntl_word_8_9; + uint8_t l_rcd_cntl_word_10; + uint8_t l_rcd_cntl_word_11; + uint8_t l_rcd_cntl_word_12; + uint8_t l_rcd_cntl_word_13; + uint8_t l_rcd_cntl_word_14; + uint8_t l_rcd_cntl_word_15; + uint64_t l_rcd_cntl_word_0_15; + uint64_t l_rcd_cntl_word_2_5_mask = 0x00FFFF0000000010LL; + ecmdDataBufferBase data_buffer_64(64); + ecmdDataBufferBase data_buffer_8(8); + + // Fetch impacted attributes + uint64_t l_attr_eff_dimm_rcd_cntl_word_0_15[PORT_SIZE][DIMM_SIZE]; + rc = FAPI_ATTR_GET(ATTR_EFF_DIMM_RCD_CNTL_WORD_0_15, &i_target_mba, l_attr_eff_dimm_rcd_cntl_word_0_15); if(rc) return rc; + rc = FAPI_ATTR_GET(ATTR_EFF_DRAM_RON, &i_target_mba, attr_eff_dram_ron); if(rc) return rc; + rc = FAPI_ATTR_GET(ATTR_EFF_DRAM_RTT_NOM, &i_target_mba, attr_eff_dram_rtt_nom); if(rc) return rc; + rc = FAPI_ATTR_GET(ATTR_EFF_DRAM_RTT_WR, &i_target_mba, attr_eff_dram_rtt_wr); if(rc) return rc; + rc = FAPI_ATTR_GET(ATTR_EFF_ODT_WR, &i_target_mba, attr_eff_odt_wr); if(rc) return rc; + + // Fetch impacted attributes + rc = FAPI_ATTR_GET(ATTR_EFF_NUM_DROPS_PER_PORT, &i_target_mba, l_num_drops_per_port); if(rc) return rc; + rc = FAPI_ATTR_GET(ATTR_EFF_DRAM_WIDTH, &i_target_mba, l_dram_width_u8); if(rc) return rc; + rc = FAPI_ATTR_GET(ATTR_EFF_NUM_RANKS_PER_DIMM, &i_target_mba, l_num_ranks_per_dimm_u8array); if(rc) return rc; + rc = FAPI_ATTR_GET(ATTR_EFF_DRAM_DENSITY, &i_target_mba, l_dram_density); if(rc) return rc; + + fapi::Target l_target_centaur; + rc = fapiGetParentChip(i_target_mba, l_target_centaur); if(rc) return rc; + rc = FAPI_ATTR_GET(ATTR_MSS_FREQ, &l_target_centaur, l_mss_freq); if(rc) return rc; + rc = FAPI_ATTR_GET(ATTR_MSS_VOLT, &l_target_centaur, l_mss_volt); if(rc) return rc; + + // Fetch SPD MR1,2 + rc = FAPI_ATTR_GET(ATTR_LRDIMM_MR12_REG, &i_target_mba, l_lrdimm_mr12_u8array); if(rc) return rc; + rc = FAPI_ATTR_GET(ATTR_LRDIMM_RANK_MULT_MODE, &i_target_mba, l_lrdimm_rank_mult_mode); if(rc) return rc; + + for (uint8_t l_port = 0; l_port < PORT_SIZE; l_port++) { + for (uint8_t l_dimm = 0; l_dimm < DIMM_SIZE; l_dimm++) { + + // Set RCD control word + FAPI_INF("before setting: rcd control word 0-15 %.16llX", l_attr_eff_dimm_rcd_cntl_word_0_15[l_port][l_dimm] ); + l_rcd_cntl_word_0_1 = 0x00; // Global features, Clock driver enable + FAPI_INF("rcd control word 0-1 %X", l_rcd_cntl_word_0_1 ); + + // RCD cntl words 2-5 from SPD + + l_rcd_cntl_word_6_7 = 0x00; // CKE & ODT management, Function select + FAPI_INF("rcd control word 6-7 %X", l_rcd_cntl_word_6_7 ); + + if ( l_num_drops_per_port == fapi::ENUM_ATTR_EFF_NUM_DROPS_PER_PORT_DUAL ) { + l_rcd_cntl_word_8_9 = 0x20; // IBT=200 Ohm & Vref settings for address, command, par_in, Power saving settings + } + else { + l_rcd_cntl_word_8_9 = 0x00; // IBT=100 Ohm & Vref settings for address, command, par_in, Power saving settings + } + FAPI_INF("rcd control word 8-9 %X", l_rcd_cntl_word_8_9 ); + + + // RC10 LRDIMM operating speed + if ( l_mss_freq <= 933 ) { // 800Mbps + l_rcd_cntl_word_10 = 0; + } else if ( l_mss_freq <= 1200 ) { // 1066Mbps + l_rcd_cntl_word_10 = 1; + } else if ( l_mss_freq <= 1466 ) { // 1333Mbps + l_rcd_cntl_word_10 = 2; + } else if ( l_mss_freq <= 1733 ) { // 1600Mbps + l_rcd_cntl_word_10 = 3; + } else if ( l_mss_freq <= 2000 ) { // 1866Mbps + l_rcd_cntl_word_10 = 4; + } else { + FAPI_ERR("Invalid LRDIMM ATTR_MSS_FREQ = %d on %s!", l_mss_freq, i_target_mba.toEcmdString()); + FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR); return rc; + } + FAPI_INF("rcd control word 10 %X", l_rcd_cntl_word_10 ); + + // RC11 Operating voltage & parity calculation (buffer does not include A17:16) + if ( l_mss_volt >= 1420 ) { // 1.5V + l_rcd_cntl_word_11 = 4; + } else if ( l_mss_volt >= 1270 ) { // 1.35V + l_rcd_cntl_word_11 = 5; + } else if ( l_mss_volt >= 1170 ) { // 1.25V + l_rcd_cntl_word_11 = 6; + } else { + FAPI_ERR("Invalid LRDIMM ATTR_MSS_VOLT = %d on %s!", l_mss_volt, i_target_mba.toEcmdString()); + FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR); return rc; + } + FAPI_INF("rcd control word 11 %X", l_rcd_cntl_word_11 ); + + l_rcd_cntl_word_12 = 0; //Training + FAPI_INF("rcd control word 12 %X", l_rcd_cntl_word_12 ); + + // rC13 DIMM configuration + if ( l_num_ranks_per_dimm_u8array[l_port][l_dimm] == 8 ) { + l_rcd_cntl_word_13 = 4; // 8 physical ranks, 2 logical ranks, RM=4 + } else if ( l_num_ranks_per_dimm_u8array[l_port][l_dimm] == 4 ) { + l_rcd_cntl_word_13 = 9; // 4 physical ranks, 4 logical ranks, direct rank mapping + // } else if ( l_num_ranks_per_dimm_u8array[l_port][l_dimm] == 2 ) { + // l_rcd_cntl_word_13 = 6; // 2 physical ranks, 2 logical ranks, direct rank mapping + // } else if ( l_num_ranks_per_dimm_u8array[l_port][l_dimm] == 1 ) { + // l_rcd_cntl_word_13 = 3; // 1 physical rank, 1 logical rank, direct rank mapping + } else { + l_rcd_cntl_word_13 = 0; + } + FAPI_INF("rcd control word 13 %X", l_rcd_cntl_word_13 ); + + // RC14 DRAM configuration & DRAM command + if ( l_lrdimm_rank_mult_mode != 0 ) { + data_buffer_8.setBit(2); // turn off refresh broadcast + } + if ( l_dram_width_u8 == 8 ) { + data_buffer_8.setBit(0); + } + data_buffer_8.extractToRight( &l_rcd_cntl_word_14, 0, 4); + FAPI_INF("rcd control word 14 %X", l_rcd_cntl_word_14 ); + + // RC15 Rank multiplication + if ( l_lrdimm_rank_mult_mode == 4 ) { + if ( l_dram_density == 1 ) { + l_rcd_cntl_word_15 = 5; // A[15:14]; 4x multiplication, 1 Gbit DDR3 SDRAM + } else if ( l_dram_density == 2 ) { + l_rcd_cntl_word_15 = 6; // A[16:15]; 4x multiplication, 2 Gbit DDR3 SDRAM + } else if ( l_dram_density == 4 ) { + l_rcd_cntl_word_15 = 7; // A[17:16]; 4x multiplication, 4 Gbit DDR3 SDRAM + } else { + FAPI_ERR("Invalid LRDIMM Rank mult mode =%d, ATTR_EFF_DRAM_DENSITY = %d on %s!", l_lrdimm_rank_mult_mode, l_dram_density, i_target_mba.toEcmdString()); + FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR); return rc; + } + } else if ( l_lrdimm_rank_mult_mode == 2 ) { + if ( l_dram_density == 1 ) { + l_rcd_cntl_word_15 = 1; // A[14]; 2x multiplication, 1 Gbit DDR3 SDRAM + } else if ( l_dram_density == 2 ) { + l_rcd_cntl_word_15 = 2; // A[15]; 2x multiplication, 2 Gbit DDR3 SDRAM + } else if ( l_dram_density == 4 ) { + l_rcd_cntl_word_15 = 3; // A[16]; 2x multiplication, 4 Gbit DDR3 SDRAM + } else { + FAPI_ERR("Invalid LRDIMM Rank Mult mode = %d, ATTR_EFF_DRAM_DENSITY = %d on %s!", l_lrdimm_rank_mult_mode, l_dram_density, i_target_mba.toEcmdString()); + FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR); return rc; + } + } else { + l_rcd_cntl_word_15 = 0; + } + FAPI_INF("rcd control word 15 %X", l_rcd_cntl_word_15 ); + + data_buffer_64.insertFromRight(&l_rcd_cntl_word_0_1, 0, 8); + data_buffer_64.clearBit( 8, 16); + data_buffer_64.insertFromRight(&l_rcd_cntl_word_6_7, 24, 8); + data_buffer_64.insertFromRight(&l_rcd_cntl_word_8_9, 32, 8); + data_buffer_64.insertFromRight(&l_rcd_cntl_word_10, 40, 4); + data_buffer_64.insertFromRight(&l_rcd_cntl_word_11, 44, 4); + data_buffer_64.insertFromRight(&l_rcd_cntl_word_12, 48, 4); + data_buffer_64.insertFromRight(&l_rcd_cntl_word_13, 52, 4); + data_buffer_64.insertFromRight(&l_rcd_cntl_word_14, 56, 4); + data_buffer_64.insertFromRight(&l_rcd_cntl_word_15, 60, 4); + l_rcd_cntl_word_0_15 = data_buffer_64.getDoubleWord(0); if(rc) return rc; + FAPI_INF("from data buffer: rcd control word 0-15 %llX", l_rcd_cntl_word_0_15 ); + l_attr_eff_dimm_rcd_cntl_word_0_15[l_port][l_dimm] = l_attr_eff_dimm_rcd_cntl_word_0_15[l_port][l_dimm] & l_rcd_cntl_word_2_5_mask; + l_attr_eff_dimm_rcd_cntl_word_0_15[l_port][l_dimm] = l_attr_eff_dimm_rcd_cntl_word_0_15[l_port][l_dimm] | l_rcd_cntl_word_0_15; + + FAPI_INF("after mask: rcd control word 0-15 %.16llX", l_attr_eff_dimm_rcd_cntl_word_0_15[l_port][l_dimm] ); + + // Setup LRDIMM drive impedance, rtt nom, rtt wr, odt wr + l_dram_ron[l_port][l_dimm] = l_lrdimm_mr12_u8array[l_port][l_dimm] & 0x03; // Pulled from SPD LR MR1,2 DRAM DriverImpedance [1:0] + l_dram_rtt_nom[l_port][l_dimm] = (l_lrdimm_mr12_u8array[l_port][l_dimm] & 0x1C) >> 2; // Pulled from SPD LR MR1,2 DRAM RTT_nom for ranks 0/1 [4:2] + l_dram_rtt_wr[l_port][l_dimm] = (l_lrdimm_mr12_u8array[l_port][l_dimm] & 0xC0) >> 6; // Pulled from SPD LR MR1,2 DRAM RTT_WR [7:6] + + if ( l_dram_ron[l_port][l_dimm] == 0 ) { + l_dram_ron[l_port][l_dimm] = fapi::ENUM_ATTR_EFF_DRAM_RON_OHM40; + } else if ( l_dram_ron[l_port][l_dimm] == 1 ) { + l_dram_ron[l_port][l_dimm] = fapi::ENUM_ATTR_EFF_DRAM_RON_OHM34; + } else { + FAPI_ERR("Invalid SPD LR MR1,2 DRAM drv imp on %s!", i_target_mba.toEcmdString()); + FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR); return rc; + } + + attr_eff_dram_ron[l_port][l_dimm] = l_dram_ron[l_port][l_dimm]; + FAPI_INF("Set LRDIMM DRAM_RON to SPD LR MR1,2 DRAM drv imp"); + + switch (l_dram_rtt_nom[l_port][l_dimm]) { + case 0 : l_dram_rtt_nom[l_port][l_dimm] = fapi::ENUM_ATTR_EFF_DRAM_RTT_NOM_DISABLE; + break; + case 1 : l_dram_rtt_nom[l_port][l_dimm] = fapi::ENUM_ATTR_EFF_DRAM_RTT_NOM_OHM60; + break; + case 2 : l_dram_rtt_nom[l_port][l_dimm] = fapi::ENUM_ATTR_EFF_DRAM_RTT_NOM_OHM120; + break; + case 3 : l_dram_rtt_nom[l_port][l_dimm] = fapi::ENUM_ATTR_EFF_DRAM_RTT_NOM_OHM40; + break; + case 4 : l_dram_rtt_nom[l_port][l_dimm] = fapi::ENUM_ATTR_EFF_DRAM_RTT_NOM_OHM20; + break; + case 5 : l_dram_rtt_nom[l_port][l_dimm] = fapi::ENUM_ATTR_EFF_DRAM_RTT_NOM_OHM30; + break; + default: FAPI_ERR("Invalid SPD LR MR1,2 DRAM RTT_NOM on %s!", i_target_mba.toEcmdString()); + FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR); return rc; + break; + } + + switch (l_dram_rtt_wr[l_port][l_dimm]) { + case 0 : l_dram_rtt_wr[l_port][l_dimm] = fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_DISABLE; + break; + case 1 : l_dram_rtt_wr[l_port][l_dimm] = fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_OHM60; + break; + case 2 : l_dram_rtt_wr[l_port][l_dimm] = fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_OHM120; + break; + default: FAPI_ERR("Invalid SPD LR MR1,2 DRAM RTT_WR on %s!", i_target_mba.toEcmdString()); + FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR); return rc; + break; + } + + uint8_t l_rank; + for ( l_rank = 0; l_rank < RANK_SIZE; l_rank++ ) { // clear RTT_NOM & RTT_WR + attr_eff_dram_rtt_nom[l_port][l_dimm][l_rank] = fapi::ENUM_ATTR_EFF_DRAM_RTT_NOM_DISABLE; + attr_eff_dram_rtt_wr[l_port][l_dimm][l_rank] = fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_DISABLE; + } + + if ( l_num_ranks_per_dimm_u8array[l_port][l_dimm] > 0 ) { // Set RTT_NOM Rank 0 for multi rank LRDIMM + attr_eff_dram_rtt_nom[l_port][l_dimm][0] = l_dram_rtt_nom[l_port][l_dimm]; // set attr_eff_dram_rtt_nom[0][0][0] + attr_eff_dram_rtt_wr[l_port][l_dimm][0] = l_dram_rtt_wr[l_port][l_dimm]; // set attr_eff_dram_rtt_wr[0][0][0] + + FAPI_INF("Setting Port0 Rank 0 LRDIMM RTT_NOM & RTT_WR from SPD LR MR1,2"); + + if ( l_num_ranks_per_dimm_u8array[l_port][l_dimm] > 1 ) { // Set RTT_NOM Rank 1 for 4rank or 8rank LRDIMM + attr_eff_dram_rtt_nom[l_port][l_dimm][1] = l_dram_rtt_nom[l_port][l_dimm]; // set attr_eff_dram_rtt_nom[0][0][1] + attr_eff_dram_rtt_wr[l_port][l_dimm][1] = l_dram_rtt_wr[l_port][l_dimm]; // set attr_eff_dram_rtt_wr[0][0][1] + + attr_eff_dram_rtt_wr[l_port][l_dimm][2] = l_dram_rtt_wr[l_port][l_dimm]; // set attr_eff_dram_rtt_wr[0][0][2] + attr_eff_dram_rtt_wr[l_port][l_dimm][3] = l_dram_rtt_wr[l_port][l_dimm]; // set attr_eff_dram_rtt_wr[0][0][3] + FAPI_INF("Setting Port0 Rank 1+ LRDIMM RTT_NOM & RTT_WR from SPD LR MR1,2"); + } + } + +//------------------------------------------------------------------------------------------------------------- + + // Set ODT_WR for each valid rank as single RDIMM rank value. + if ( l_num_ranks_per_dimm_u8array[l_port][l_dimm] > 1 ) { // SET ODT_WR Rank 1 for multi rank LRDIMM (8R or 4R) + attr_eff_odt_wr[l_port][l_dimm][1] = attr_eff_odt_wr[l_port][l_dimm][0]; // set attr_eff_odt_wr[0][0][1] to attr_eff_odt_wr[0][0][0] + if ( l_num_ranks_per_dimm_u8array[l_port][l_dimm] == 4 ) { // Set ODT_WR Rankd 2,3 for 4 rank LRDIMM + attr_eff_odt_wr[l_port][l_dimm][2] = attr_eff_odt_wr[l_port][l_dimm][0]; // set attr_eff_odt_wr[0][0][2] to attr_eff_odt_wr[0][0][0] + attr_eff_odt_wr[l_port][l_dimm][3] = attr_eff_odt_wr[l_port][l_dimm][0]; // set attr_eff_odt_wr[0][0][3] to attr_eff_odt_wr[0][0][0] + } + } + + } // end dimm loop + } // end port loop + + // Set adjusted attributes + rc = FAPI_ATTR_SET(ATTR_EFF_DRAM_RON, &i_target_mba, attr_eff_dram_ron); if(rc) return rc; + rc = FAPI_ATTR_SET(ATTR_EFF_DRAM_RTT_NOM, &i_target_mba, attr_eff_dram_rtt_nom); if(rc) return rc; + rc = FAPI_ATTR_SET(ATTR_EFF_DRAM_RTT_WR, &i_target_mba, attr_eff_dram_rtt_wr); if(rc) return rc; + rc = FAPI_ATTR_SET(ATTR_EFF_ODT_WR, &i_target_mba, attr_eff_odt_wr); if(rc) return rc; + + rc = FAPI_ATTR_SET(ATTR_EFF_DIMM_RCD_CNTL_WORD_0_15, &i_target_mba, l_attr_eff_dimm_rcd_cntl_word_0_15); if(rc) return rc; + + return rc; +} + +fapi::ReturnCode mss_spec_rcd_load( Target& i_target, uint32_t i_port_number, uint8_t *p_i_rcd_num_arr, uint8_t i_rcd_num_arr_length, uint64_t i_rcd_word[], uint32_t& io_ccs_inst_cnt,uint8_t i_keep_cke_high) +{ + const uint8_t MAX_NUM_PORTS=2; + const uint8_t MAX_NUM_DIMMS=2; + ReturnCode rc; + ReturnCode rc_buff; + uint32_t rc_num = 0; + uint32_t dimm_number; + uint8_t spec_rcd; + + ecmdDataBufferBase rcd_cntl_wrd_4(8); + ecmdDataBufferBase rcd_cntl_wrd_64(64); + uint16_t num_ranks; + + uint16_t num_idles_delay = 20; // default=12 klc + + ecmdDataBufferBase address_16(16); + ecmdDataBufferBase bank_3(3); + ecmdDataBufferBase activate_1(1); + ecmdDataBufferBase rasn_1(1); + rc_num = rc_num | rasn_1.setBit(0); + ecmdDataBufferBase casn_1(1); + rc_num = rc_num | casn_1.setBit(0); + ecmdDataBufferBase wen_1(1); + rc_num = rc_num | wen_1.setBit(0); + ecmdDataBufferBase cke_4(4); + if (i_keep_cke_high == 1) + rc_num = rc_num | cke_4.setBit(0,4); + else + rc_num = rc_num | cke_4.clearBit(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); + + uint8_t num_ranks_array[MAX_NUM_PORTS][MAX_NUM_DIMMS]; //[port][dimm] + + rc = FAPI_ATTR_GET(ATTR_EFF_NUM_RANKS_PER_DIMM, &i_target, num_ranks_array); + if(rc) return rc; + + FAPI_INF( "+++++++++++++++++++++ LOADING RCD CONTROL WORD FOR PORT %d +++++++++++++++++++++", i_port_number); + + for ( dimm_number = 0; dimm_number < MAX_NUM_DIMMS; dimm_number++) + { + num_ranks = num_ranks_array[i_port_number][dimm_number]; + + if (num_ranks == 0) + { + FAPI_INF( "PORT%d DIMM%d not configured. Num_ranks: %d", i_port_number, dimm_number, num_ranks); + } + else + { + FAPI_INF( "RCD SETTINGS FOR PORT%d DIMM%d ", i_port_number, dimm_number); + FAPI_INF( "RCD Control Word: 0x%016llX", i_rcd_word[dimm_number]); + FAPI_INF( "Loading function specific RCD Control Words"); + + if (rc_num) + { + FAPI_ERR( "mss_spec_rcd_load: Error setting up buffers"); + rc_buff.setEcmdError(rc_num); + return rc_buff; + } + + rc_num = rc_num | csn_8.setBit(0,8); // reset CS lines + // for dimm0 use CS0,1 (active low); for dimm1 use CS4,5 (active low) + rc_num = rc_num | csn_8.clearBit( (dimm_number * 4), 2 ); + // set specific control words + for ( spec_rcd = 0; spec_rcd < i_rcd_num_arr_length; spec_rcd++ ) + { + rc_num = rc_num | bank_3.clearBit(0, 3); + rc_num = rc_num | address_16.clearBit(0, 16); + + rc_num = rc_num | rcd_cntl_wrd_64.setDoubleWord(0, i_rcd_word[dimm_number]); + rc_num = rc_num | rcd_cntl_wrd_64.extract(rcd_cntl_wrd_4, 4*p_i_rcd_num_arr[spec_rcd], 4); + + //control word number code bits A0, A1, A2, BA2 + rc_num = rc_num | bank_3.insert(p_i_rcd_num_arr[spec_rcd], 2, 1, 4); // BA2(MSB) from array bit 4 + rc_num = rc_num | address_16.insert(p_i_rcd_num_arr[spec_rcd], 2, 1, 5); // A2 + rc_num = rc_num | address_16.insert(p_i_rcd_num_arr[spec_rcd], 1, 1, 6); // A1 + rc_num = rc_num | address_16.insert(p_i_rcd_num_arr[spec_rcd], 0, 1, 7); // A0 + + //control word values RCD0 = A3, RCD1 = A4, RCD2 = BA0, RCD3 = BA1 + rc_num = rc_num | bank_3.insert(rcd_cntl_wrd_4, 1, 1, 0); // BA1 (MSB) + rc_num = rc_num | bank_3.insert(rcd_cntl_wrd_4, 0, 1, 1); // BA0 + rc_num = rc_num | address_16.insert(rcd_cntl_wrd_4, 4, 1, 2); // A4 + rc_num = rc_num | address_16.insert(rcd_cntl_wrd_4, 3, 1, 3); // A3 + + FAPI_INF("Loading RCD %d (0x%02x) = 0x%01X", p_i_rcd_num_arr[spec_rcd], + p_i_rcd_num_arr[spec_rcd], + (rcd_cntl_wrd_4.getByte(0)>>4)); + + // Send out to the CCS array + rc_num = rc_num | num_idles_16.insertFromRight((uint32_t) num_idles_delay, 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 ++; + + if (rc_num) + { + FAPI_ERR( "mss_rcd_load: Error setting up buffers"); + rc_buff.setEcmdError(rc_num); + return rc_buff; + } + } //end control word loop + } // end valid rank + } // end dimm loop + return rc; +} + +#endif diff --git a/src/usr/hwpf/hwp/dram_training/mss_lrdimm_funcs/mss_lrdimm_funcs.H b/src/usr/hwpf/hwp/dram_training/mss_lrdimm_funcs/mss_lrdimm_funcs.H new file mode 100644 index 000000000..9d31ba2c8 --- /dev/null +++ b/src/usr/hwpf/hwp/dram_training/mss_lrdimm_funcs/mss_lrdimm_funcs.H @@ -0,0 +1,165 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/hwpf/hwp/dram_training/mss_lrdimm_funcs/mss_lrdimm_funcs.H $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2013 */ +/* */ +/* 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_lrdimm_funcs.H,v 1.2 2013/09/16 13:28:55 bellows Exp $ +//------------------------------------------------------------------------------ +// *! (C) Copyright International Business Machines Corp. 2013 +// *! All Rights Reserved -- Property of IBM +// *! *** IBM Confidential *** +//------------------------------------------------------------------------------ +// *! TITLE : mss_lrdimm_funcs.H +// *! DESCRIPTION : Tools for lrdimm centaur procedures +// *! OWNER NAME : KCOOK +// *! BACKUP NAME : MWUU +// #! ADDITIONAL COMMENTS : +// +// CCS related and general utility functions. + +//------------------------------------------------------------------------------ +// Don't forget to create CVS comments when you check in your changes! +//------------------------------------------------------------------------------ +// CHANGE HISTORY: +//------------------------------------------------------------------------------ +// Version:| Author: | Date: | Comment: +//---------|----------|---------|----------------------------------------------- +// 1.2 | 09/16/13 | bellows | Added ID tag +// 1.1 | 08/27/13 | kcook | First drop of Centaur + +#ifndef _MSS_LRDIMM_FUNCS_H +#define _MSS_LRDIMM_FUNCS_H + +//#define LRDIMM 1 + +//---------------------------------------------------------------------- +// Constants +//---------------------------------------------------------------------- +const uint8_t PORT = 2; +const uint8_t DIMM = 2; +const uint8_t RANK = 4; +//---------------------------------------------------------------------- +// Enums +//---------------------------------------------------------------------- + +struct mss_lrdimm_spd_data +{ + uint8_t lr_addr_mirroring[PORT][DIMM]; + uint8_t lr_f0rc3_f0rc2[PORT][DIMM]; + uint8_t lr_f0rc5_f0rc4[PORT][DIMM]; + uint8_t lr_f1rc11_f1rc8[PORT][DIMM]; + uint8_t lr_f1rc13_f1rc12[PORT][DIMM]; + uint8_t lr_f1rc15_f1rc14[PORT][DIMM]; + uint8_t lr_f3rc9_f3rc8_for_800_1066[PORT][DIMM]; + uint8_t lr_f34rc11_f34rc10_for_800_1066[PORT][DIMM]; + uint8_t lr_f56rc11_f56rc10_for_800_1066[PORT][DIMM]; + uint8_t lr_f78rc11_f78rc10_for_800_1066[PORT][DIMM]; + uint8_t lr_f910rc11_f910rc10_for_800_1066[PORT][DIMM]; + uint8_t lr_mr12_for_800_1066[PORT][DIMM]; + uint8_t lr_f3rc9_f3rc8_for_1333_1600[PORT][DIMM]; + uint8_t lr_f34rc11_f34rc10_for_1333_1600[PORT][DIMM]; + uint8_t lr_f56rc11_f56rc10_for_1333_1600[PORT][DIMM]; + uint8_t lr_f78rc11_f78rc10_for_1333_1600[PORT][DIMM]; + uint8_t lr_f910rc11_f910rc10_for_1333_1600[PORT][DIMM]; + uint8_t lr_mr12_for_1333_1600[PORT][DIMM]; + uint8_t lr_f3rc9_f3rc8_for_1866_2133[PORT][DIMM]; + uint8_t lr_f34rc11_f34rc10_for_1866_2133[PORT][DIMM]; + uint8_t lr_f56rc11_f56rc10_for_1866_2133[PORT][DIMM]; + uint8_t lr_f78rc11_f78rc10_for_1866_2133[PORT][DIMM]; + uint8_t lr_f910rc11_f910rc10_for_1866_2133[PORT][DIMM]; + uint8_t lr_mr12_for_1866_2133[PORT][DIMM]; +}; + + +//---------------------------------------------------------------------- +// LRDIMM FUNCS +//---------------------------------------------------------------------- + +//-------------------------------------------------------------- +// mss_lrimm_rcd_load +// Set Function 1-13 RCD words +// Target = centaur.mba +//-------------------------------------------------------------- +fapi::ReturnCode mss_lrdimm_rcd_load( fapi::Target& i_target, + uint32_t port_number, + uint32_t& ccs_inst_cnt ); + +//-------------------------------------------------------------- +// mss_lrdimm_mrs_load +// Set MRS1 settings for Rank 0 and Rank 1 +// Target = centaur.mba +//-------------------------------------------------------------- +fapi::ReturnCode mss_lrdimm_mrs_load( fapi::Target& i_target, + uint32_t i_port_number, + uint32_t dimm_number, + uint32_t& io_ccs_inst_cnt); +//-------------------------------------------------------------- +// mss_execute_lrdimm_mb_dram_training +// run lrdimm memory buffer training +// Target = centaur.mba +//-------------------------------------------------------------- +fapi::ReturnCode mss_execute_lrdimm_mb_dram_training( fapi::Target& i_target); + +//-------------------------------------------------------------- +// mss_lrdimm_eff_config +// run lrdimm attribute set up +// Target = centaur.mba +//-------------------------------------------------------------- +fapi::ReturnCode mss_lrdimm_eff_config( const fapi::Target& i_target_mba, + uint8_t cur_dimm_spd_valid_u8array[PORT][DIMM], + uint32_t mss_freq, + uint8_t eff_num_ranks_per_dimm[PORT][DIMM]); + +//-------------------------------------------------------------- +// mss_lrdimm_rewrite_odt +// eff config termination rewrite odts for dual drop +// Target = centaur.mba +//-------------------------------------------------------------- +fapi::ReturnCode mss_lrdimm_rewrite_odt( const fapi::Target& i_target_mba, + uint32_t *p_b_var_array, + uint32_t *var_array_p_array[5]); + + +//-------------------------------------------------------------- +// mss_lrdimm_term_atts +// eff config termination rewrite odts for dual drop +// Target = centaur.mba +//-------------------------------------------------------------- +fapi::ReturnCode mss_lrdimm_term_atts( const fapi::Target& i_target_mba); + + + +//----------------------------------------- +// mss_spec_rcd_load +// execute RCD loads of specific control words. For LRDIMM. +// Target = centaur.mba +//----------------------------------------- +fapi::ReturnCode mss_spec_rcd_load(fapi::Target& i_target, + uint32_t i_port_number, + uint8_t * p_i_rcd_num_arr, + uint8_t i_rcd_num_arr_length, + uint64_t i_rcd_word[], + uint32_t& io_ccs_inst_cnt, + uint8_t i_keep_cke_high=0); + + + +#endif /* _MSS_LRDIMM_FUNCS_H */ + diff --git a/src/usr/hwpf/hwp/mc_config/makefile b/src/usr/hwpf/hwp/mc_config/makefile index 5ee0e53c8..f415c29b8 100644 --- a/src/usr/hwpf/hwp/mc_config/makefile +++ b/src/usr/hwpf/hwp/mc_config/makefile @@ -39,6 +39,8 @@ EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/include EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/mc_config/mss_eff_config EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/mc_config/mss_volt EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/mc_config/mss_freq +EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/dram_training/mss_lrdimm_funcs +EXTRAINCDIR += ${ROOTPATH}/src/usr/hwpf/hwp/mc_config/mss_eff_pre_config OBJS = mc_config.o \ mss_volt.o \ @@ -61,6 +63,6 @@ OBJS = mc_config.o \ VPATH += ${ROOTPATH}/src/usr/hwpf/hwp/mc_config/mss_eff_config VPATH += ${ROOTPATH}/src/usr/hwpf/hwp/mc_config/mss_volt VPATH += ${ROOTPATH}/src/usr/hwpf/hwp/mc_config/mss_freq - +VPATH += ${ROOTPATH}/src/usr/hwpf/hwp/mc_config/mss_eff_pre_config include ${ROOTPATH}/config.mk diff --git a/src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_eff_config.C b/src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_eff_config.C index 10668787a..5c346d576 100644 --- a/src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_eff_config.C +++ b/src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_eff_config.C @@ -20,7 +20,7 @@ /* Origin: 30 */ /* */ /* IBM_PROLOG_END_TAG */ -// $Id: mss_eff_config.C,v 1.28 2013/08/06 23:38:34 asaetow Exp $ +// $Id: mss_eff_config.C,v 1.33 2013/09/16 13:56:33 bellows Exp $ // $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/ // centaur/working/procedures/ipl/fapi/mss_eff_config.C,v $ //------------------------------------------------------------------------------ @@ -44,7 +44,11 @@ //------------------------------------------------------------------------------ // Version:| Author: | Date: | Comment: //---------|----------|---------|----------------------------------------------- -// 1.29 | | | +// 1.33 | bellows |16-SEP-13| Hostboot compile update +// 1.32 | kcook |13-SEP-13| Added using namespace fapi. +// 1.31 | kcook |13-SEP-13| Updated define FAPI_LRDIMM token. +// 1.30 | kcook |27-AUG-13| Removed LRDIMM support to mss_lrdimm_funcs.C. +// 1.29 | kcook |16-AUG-13| Added LRDIMM support. // 1.28 | asaetow |06-AUG-13| Added call to mss_eff_pre_config(). // | | | Removed call to mss_eff_config_thermal(). // | | | NOTE: Do NOT pickup without mss_eff_pre_config.C v1.1 or newer. @@ -136,6 +140,7 @@ // 1.1 | asaetow |01-NOV-11| First Draft. //------------------------------------------------------------------------------ +#include <fapi.H> //------------------------------------------------------------------------------ // My Includes @@ -143,15 +148,18 @@ #include <mss_eff_config.H> #include <mss_eff_config_rank_group.H> #include <mss_eff_config_cke_map.H> -#include <mss_eff_config_termination.H> #include <mss_eff_pre_config.H> #include <mss_eff_config_shmoo.H> +#include <mss_lrdimm_funcs.H> + +#include <mss_eff_config_termination.H> + + //------------------------------------------------------------------------------ // Includes //------------------------------------------------------------------------------ -#include <fapi.H> //------------------------------------------------------------------------------ // Constants @@ -163,6 +171,22 @@ const uint8_t PORT_SIZE = 2; const uint8_t DIMM_SIZE = 2; const uint8_t RANK_SIZE = 4; +#ifndef FAPI_LRDIMM +using namespace fapi; +fapi::ReturnCode mss_lrdimm_eff_config( const Target& i_target_mba, + uint8_t cur_dimm_spd_valid_u8array[PORT_SIZE][DIMM_SIZE], + uint32_t mss_freq, + uint8_t eff_num_ranks_per_dimm[PORT_SIZE][DIMM_SIZE]) +{ + ReturnCode rc; + + FAPI_ERR("Invalid exec of LRDIMM function on %s!", i_target_mba.toEcmdString()); + FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR); + return rc; + +} +#endif + //------------------------------------------------------------------------------ // Structure // @brief struct mss_eff_config_data @@ -236,8 +260,8 @@ struct mss_eff_config_spd_data uint8_t fine_offset_trcdmin[PORT_SIZE][DIMM_SIZE]; uint8_t fine_offset_trpmin[PORT_SIZE][DIMM_SIZE]; uint8_t fine_offset_trcmin[PORT_SIZE][DIMM_SIZE]; - // HERE uint8_t module_specific_section[PORT_SIZE][DIMM_SIZE] - // [SPD_ATTR_SIZE_57]; + + //uint8_t module_specific_section[PORT_SIZE][DIMM_SIZE][57]; //uint32_t module_id_module_manufacturers_jedec_id_code // [PORT_SIZE][DIMM_SIZE]; //uint8_t module_id_module_manufacturing_location[PORT_SIZE] @@ -554,7 +578,9 @@ fapi::ReturnCode mss_eff_config_read_spd_data(fapi::Target i_target_dimm, rc = FAPI_ATTR_GET(ATTR_SPD_FINE_OFFSET_TRCMIN, &i_target_dimm, p_o_spd_data->fine_offset_trcmin[i_port][i_dimm]); if(rc) break; - // HERE rc = FAPI_ATTR_GET(ATTR_SPD_MODULE_SPECIFIC_SECTION, + + + //rc = FAPI_ATTR_GET(ATTR_SPD_MODULE_SPECIFIC_SECTION, // LRDIMM needed. //&i_target_dimm, //p_o_spd_data->module_specific_section[i_port][i_dimm]); //if(rc) break; @@ -1574,7 +1600,16 @@ fapi::ReturnCode mss_eff_config_setup_eff_atts( if (p_i_mss_eff_config_data-> cur_dimm_spd_valid_u8array[l_cur_mba_port][l_cur_mba_dimm] == MSS_EFF_VALID) { - if (p_i_data->num_ranks[l_cur_mba_port] + if (p_i_data->num_ranks[l_cur_mba_port] + [l_cur_mba_dimm] == 0x04) // for 8R LRDIMM since no ENUM defined yet for SPD of 8R +// [l_cur_mba_dimm] == fapi::ENUM_ATTR_SPD_NUM_RANKS_R8) + { + p_o_atts->eff_num_ranks_per_dimm[l_cur_mba_port] + [l_cur_mba_dimm] = 8; + p_o_atts->eff_dimm_ranks_configed[l_cur_mba_port] + [l_cur_mba_dimm] = 0x80; // DD0/1: 1 master rank + } + else if (p_i_data->num_ranks[l_cur_mba_port] [l_cur_mba_dimm] == fapi::ENUM_ATTR_SPD_NUM_RANKS_R4) { p_o_atts->eff_num_ranks_per_dimm[l_cur_mba_port] @@ -1654,6 +1689,9 @@ fapi::ReturnCode mss_eff_config_setup_eff_atts( FAPI_ERR("Currently unsupported IBM_TYPE on %s!", i_target_mba.toEcmdString()); FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR); return rc; } + } else if ( p_o_atts->eff_dimm_type == fapi::ENUM_ATTR_EFF_DIMM_TYPE_LRDIMM ) { + FAPI_INF("Will set LR atts after orig eff_config functions"); + } else { p_o_atts->eff_ibm_type[l_cur_mba_port][l_cur_mba_dimm] = fapi::ENUM_ATTR_EFF_IBM_TYPE_UNDEFINED; FAPI_ERR("Currently unsupported DIMM_TYPE on %s!", i_target_mba.toEcmdString()); @@ -1722,12 +1760,24 @@ fapi::ReturnCode mss_eff_config_setup_eff_atts( [l_cur_mba_dimm] = 0; } - // AST HERE: Needs SPD byte33[7,1:0], - // currently hard coded to no stacking - p_o_atts->eff_num_master_ranks_per_dimm[l_cur_mba_port] - [l_cur_mba_dimm] = - p_o_atts->eff_num_ranks_per_dimm[l_cur_mba_port] - [l_cur_mba_dimm]; + + if ( (p_o_atts->eff_dimm_type == fapi::ENUM_ATTR_EFF_DIMM_TYPE_LRDIMM) && + (p_i_data->dram_device_type[l_cur_mba_port][l_cur_mba_dimm] == + fapi::ENUM_ATTR_SPD_DRAM_DEVICE_TYPE_DDR3) && + (p_o_atts->eff_num_ranks_per_dimm[l_cur_mba_port][l_cur_mba_dimm] == 8) ) + { + p_o_atts->eff_num_master_ranks_per_dimm[l_cur_mba_port] + [l_cur_mba_dimm] = 1; + } + else + { + // AST HERE: Needs SPD byte33[7,1:0], + // currently hard coded to no stacking + p_o_atts->eff_num_master_ranks_per_dimm[l_cur_mba_port] + [l_cur_mba_dimm] = + p_o_atts->eff_num_ranks_per_dimm[l_cur_mba_port] + [l_cur_mba_dimm]; + } // DEBUG HERE: //FAPI_INF("size=%d density=%d ranks=%d width=%d on %s", @@ -2113,6 +2163,20 @@ fapi::ReturnCode mss_eff_config(const fapi::Target i_target_mba) break; } + // LRDIMM attributes + if ( p_l_atts->eff_dimm_type == fapi::ENUM_ATTR_EFF_DIMM_TYPE_LRDIMM ) + { + rc = mss_lrdimm_eff_config(i_target_mba, p_l_mss_eff_config_data->cur_dimm_spd_valid_u8array, + p_l_mss_eff_config_data->mss_freq, p_l_atts->eff_num_ranks_per_dimm); + if(rc) + { + FAPI_ERR("Error from mss_lrdimm_eff_config()"); + FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR); + break; + } + + } + // Calls to sub-procedures rc = mss_eff_config_rank_group(i_target_mba); if(rc) break; rc = mss_eff_config_cke_map(i_target_mba); if(rc) break; diff --git a/src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_eff_config_termination.C b/src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_eff_config_termination.C index 674535c78..62b76a038 100644 --- a/src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_eff_config_termination.C +++ b/src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_eff_config_termination.C @@ -20,7 +20,7 @@ /* Origin: 30 */ /* */ /* IBM_PROLOG_END_TAG */ -// $Id: mss_eff_config_termination.C,v 1.30 2013/08/07 15:57:38 lapietra Exp $ +// $Id: mss_eff_config_termination.C,v 1.32 2013/08/27 22:25:29 kcook Exp $ // $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/centaur/working/procedures/ipl/fapi/mss_eff_config_termination.C,v $ //------------------------------------------------------------------------------ // *! (C) Copyright International Business Machines Corp. 2011 @@ -42,6 +42,8 @@ //------------------------------------------------------------------------------ // Version:| Author: | Date: | Comment: //---------|----------|---------|----------------------------------------------- +// 1.32 | kcook |27-AUG-13| Removed LRDIMM support to mss_lrdimm_funcs.C. +// 1.31 | kcook |16-AUG-13| Added LRDIMM support. // 1.30 | dcadiga |07-AUG-13| Fixed hostboot compile issue // 1.29 | dcadiga |05-AUG-13| KG3 allowed, ifdef removed for lab card uint declaration, added 4R support to 1600, changed 4Rx4 / 4Rx8 RCD Drive Settings // 1.28 | asaetow |05-AUG-13| Added temp workaround for incorrect byte33 SPD data in early lab OLD 16G/32G CDIMMs. @@ -90,8 +92,35 @@ //---------------------------------------------------------------------- #include <fapi.H> +#include <mss_lrdimm_funcs.H> + + +#ifndef LRDIMM +using namespace fapi; +ReturnCode mss_lrdimm_rewrite_odt( const Target& i_target_mba, + uint32_t *p_b_var_array, + uint32_t *var_array_p_array[5]) +{ + ReturnCode rc; + + FAPI_ERR("Invalid exec of LRDIMM function on %s!", i_target_mba.toEcmdString()); + FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR); + return rc; + +} +ReturnCode mss_lrdimm_term_atts(const Target& i_target_mba) +{ + ReturnCode rc; + + FAPI_ERR("Invalid exec of LRDIMM function on %s!", i_target_mba.toEcmdString()); + FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR); + return rc; + +} +#endif + //---------------------------------------------------------------------- // ENUMs and CONSTs //---------------------------------------------------------------------- @@ -690,6 +719,8 @@ fapi::ReturnCode mss_eff_config_termination(const fapi::Target i_target_mba) { uint8_t l_dimm_custom_u8; uint8_t l_num_drops_per_port; uint8_t l_dram_width_u8; + +// this statement makes only lab version of this code have a raw card attribute #ifdef FAPIECMD uint8_t l_lab_raw_card_u8 = 0; #endif @@ -721,7 +752,6 @@ fapi::ReturnCode mss_eff_config_termination(const fapi::Target i_target_mba) { rc = FAPI_ATTR_GET(ATTR_EFF_DRAM_WIDTH, &i_target_mba, l_dram_width_u8); if(rc) return rc; rc = FAPI_ATTR_GET(ATTR_EFF_DIMM_SIZE, &i_target_mba, l_dimm_size_u8array); if(rc) return rc; - // Temp workaround for incorrect byte33 SPD data "ATTR_EFF_STACK_TYPE" in early lab CDIMMs. uint8_t l_stack_type_modified = 0; for (uint8_t cur_port = 0; cur_port < PORT_SIZE; cur_port += 1) { @@ -783,16 +813,19 @@ fapi::ReturnCode mss_eff_config_termination(const fapi::Target i_target_mba) { //KG3 //FAPI_ERR("RUNNING AS KG3 LAB CARD TYPE, KG3 IS DISABLED UNTIL THE INITIAL SETTINGS ARE VERIFIED\n"); //FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR); return rc; - if( l_target_mba_pos == 0){ if ( l_mss_freq <= 1466 ) { // 1333Mbps - - if((l_num_ranks_per_dimm_u8array[0][0] == 2) && (l_num_ranks_per_dimm_u8array[0][1] == 0) && (l_dram_width_u8 == 4)){ + if( l_dimm_type_u8 == fapi::ENUM_ATTR_EFF_DIMM_TYPE_LRDIMM ) { + //Removed Width Check, use settings for either x8 or x4, use 1600 settings for 1333! + memcpy(base_var_array,rdimm_kg3_1333_r1_mba0,210*sizeof(uint32_t)); + FAPI_INF("LRDIMM: Base - KG3 RDIMM r10 %d MBA%s\n",l_mss_freq,i_target_mba.toEcmdString()); + } + else if((l_num_ranks_per_dimm_u8array[0][0] == 2) && (l_num_ranks_per_dimm_u8array[0][1] == 0) && (l_dram_width_u8 == 4)){ memcpy(base_var_array,rdimm_kg3_1333_r2e_mba0,210*sizeof(uint32_t)); FAPI_INF("KG3 r2e %d MBA%s\n",l_mss_freq,i_target_mba.toEcmdString()); } - else if((l_num_ranks_per_dimm_u8array[0][0] == 1) && (l_num_ranks_per_dimm_u8array[0][1] == 0)){ - //Removed Width Check, use settings for either x8 or x4, use 1600 settings for 1333! + else if((l_num_ranks_per_dimm_u8array[0][0] == 1) && (l_num_ranks_per_dimm_u8array[0][1] == 0)){ + //Removed Width Check, use settings for either x8 or x4, use 1600 settings for 1333! memcpy(base_var_array,rdimm_kg3_1333_r1_mba0,210*sizeof(uint32_t)); FAPI_INF("KG3 r1 %d MBA%s\n",l_mss_freq,i_target_mba.toEcmdString()); } @@ -811,23 +844,28 @@ fapi::ReturnCode mss_eff_config_termination(const fapi::Target i_target_mba) { } else if ( l_mss_freq <= 1733 ) { // 1600Mbps - if((l_num_ranks_per_dimm_u8array[0][0] == 1) && (l_num_ranks_per_dimm_u8array[0][1] == 0)){ - //Removed Width Check, use settings for either x8 or x4 + if( l_dimm_type_u8 == fapi::ENUM_ATTR_EFF_DIMM_TYPE_LRDIMM ) { + //Removed Width Check, use settings for either x8 or x4 + memcpy(base_var_array,rdimm_kg3_1600_r1_mba0,210*sizeof(uint32_t)); + FAPI_INF("LRDIMM: Base - KG3 LRDIMM r10 %d MBA%s\n",l_mss_freq,i_target_mba.toEcmdString()); + } + else if((l_num_ranks_per_dimm_u8array[0][0] == 1) && (l_num_ranks_per_dimm_u8array[0][1] == 0)){ + //Removed Width Check, use settings for either x8 or x4 memcpy(base_var_array,rdimm_kg3_1600_r1_mba0,210*sizeof(uint32_t)); FAPI_INF("KG3 r10 %d MBA%s\n",l_mss_freq,i_target_mba.toEcmdString()); } else if((l_num_ranks_per_dimm_u8array[0][0] == 2) && (l_num_ranks_per_dimm_u8array[0][1] == 0) && (l_dram_width_u8 == 4)){ - + memcpy(base_var_array,rdimm_kg3_1600_r2e_mba0,210*sizeof(uint32_t)); FAPI_INF("KG3 r20e %d MBA%s\n",l_mss_freq,i_target_mba.toEcmdString()); - + } else if((l_num_ranks_per_dimm_u8array[0][0] == 2) && (l_num_ranks_per_dimm_u8array[0][1] == 0) && (l_dram_width_u8 == 8)){ memcpy(base_var_array,rdimm_kg3_1600_r2b_mba0,210*sizeof(uint32_t)); FAPI_INF("KG3 r20b %d MBA%s\n",l_mss_freq,i_target_mba.toEcmdString()); } - else if((l_num_ranks_per_dimm_u8array[0][0] == 4) && (l_num_ranks_per_dimm_u8array[0][1] == 0)){ - memcpy(base_var_array,rdimm_kg3_1600_r4_mba0,210*sizeof(uint32_t)); + else if((l_num_ranks_per_dimm_u8array[0][0] == 4) && (l_num_ranks_per_dimm_u8array[0][1] == 0)){ + memcpy(base_var_array,rdimm_kg3_1600_r4_mba0,210*sizeof(uint32_t)); FAPI_INF("KG3 r40 %d MBA%s Using 1333 Settings\n",l_mss_freq,i_target_mba.toEcmdString()); } @@ -839,13 +877,17 @@ fapi::ReturnCode mss_eff_config_termination(const fapi::Target i_target_mba) { }//MBA0 else{ if ( l_mss_freq <= 1466 ) { // 1333Mbps - - if((l_num_ranks_per_dimm_u8array[0][0] == 2) && (l_num_ranks_per_dimm_u8array[0][1] == 0) && (l_dram_width_u8 == 4)){ + if( l_dimm_type_u8 == fapi::ENUM_ATTR_EFF_DIMM_TYPE_LRDIMM ) { + //Removed Width Check, use settings for either x8 or x4, + memcpy(base_var_array,rdimm_kg3_1333_r1_mba1,210*sizeof(uint32_t)); + FAPI_INF("LRDIMM: Base - KG3 RDIMM r10 %d MBA%s\n",l_mss_freq,i_target_mba.toEcmdString()); + } + else if((l_num_ranks_per_dimm_u8array[0][0] == 2) && (l_num_ranks_per_dimm_u8array[0][1] == 0) && (l_dram_width_u8 == 4)){ memcpy(base_var_array,rdimm_kg3_1333_r2e_mba1,210*sizeof(uint32_t)); FAPI_INF("KG3 r2e %d MBA%s\n",l_mss_freq,i_target_mba.toEcmdString()); } - else if((l_num_ranks_per_dimm_u8array[0][0] == 1) && (l_num_ranks_per_dimm_u8array[0][1] == 0)){ - //Removed Width Check, use settings for either x8 or x4, use 1600 settings for 1333! + else if((l_num_ranks_per_dimm_u8array[0][0] == 1) && (l_num_ranks_per_dimm_u8array[0][1] == 0)){ + //Removed Width Check, use settings for either x8 or x4, use 1600 settings for 1333! memcpy(base_var_array,rdimm_kg3_1333_r1_mba1,210*sizeof(uint32_t)); FAPI_INF("KG3 r1 %d MBA%s\n",l_mss_freq,i_target_mba.toEcmdString()); } @@ -864,23 +906,28 @@ fapi::ReturnCode mss_eff_config_termination(const fapi::Target i_target_mba) { } else if ( l_mss_freq <= 1733 ) { // 1600Mbps - if((l_num_ranks_per_dimm_u8array[0][0] == 1) && (l_num_ranks_per_dimm_u8array[0][1] == 0)){ - //Removed Width Check, use settings for either x8 or x4 + if( l_dimm_type_u8 == fapi::ENUM_ATTR_EFF_DIMM_TYPE_LRDIMM ) { + //Removed Width Check, use settings for either x8 or x4 + memcpy(base_var_array,rdimm_kg3_1600_r1_mba1,210*sizeof(uint32_t)); + FAPI_INF("LRDIMM: Base - KG3 RDIMM r10 %d MBA%s\n",l_mss_freq,i_target_mba.toEcmdString()); + } + else if((l_num_ranks_per_dimm_u8array[0][0] == 1) && (l_num_ranks_per_dimm_u8array[0][1] == 0)){ + //Removed Width Check, use settings for either x8 or x4 memcpy(base_var_array,rdimm_kg3_1600_r1_mba1,210*sizeof(uint32_t)); FAPI_INF("KG3 r10 %d MBA%s\n",l_mss_freq,i_target_mba.toEcmdString()); } else if((l_num_ranks_per_dimm_u8array[0][0] == 2) && (l_num_ranks_per_dimm_u8array[0][1] == 0) && (l_dram_width_u8 == 4)){ - + memcpy(base_var_array,rdimm_kg3_1600_r2e_mba1,210*sizeof(uint32_t)); FAPI_INF("KG3 r20e %d MBA%s\n",l_mss_freq,i_target_mba.toEcmdString()); - + } else if((l_num_ranks_per_dimm_u8array[0][0] == 2) && (l_num_ranks_per_dimm_u8array[0][1] == 0) && (l_dram_width_u8 == 8)){ memcpy(base_var_array,rdimm_kg3_1600_r2b_mba1,210*sizeof(uint32_t)); FAPI_INF("KG3 r20b %d MBA%s\n",l_mss_freq,i_target_mba.toEcmdString()); } - else if((l_num_ranks_per_dimm_u8array[0][0] == 4) && (l_num_ranks_per_dimm_u8array[0][1] == 0)){ - memcpy(base_var_array,rdimm_kg3_1600_r4_mba1,210*sizeof(uint32_t)); + else if((l_num_ranks_per_dimm_u8array[0][0] == 4) && (l_num_ranks_per_dimm_u8array[0][1] == 0)){ + memcpy(base_var_array,rdimm_kg3_1600_r4_mba1,210*sizeof(uint32_t)); FAPI_INF("KG3 r40 %d MBA%s Using 1333 Settings\n",l_mss_freq,i_target_mba.toEcmdString()); } @@ -890,7 +937,6 @@ fapi::ReturnCode mss_eff_config_termination(const fapi::Target i_target_mba) { } }//1600 }//MBA1 - } #endif @@ -1312,11 +1358,75 @@ fapi::ReturnCode mss_eff_config_termination(const fapi::Target i_target_mba) { }//MBA1 }//End RDIMM else if( l_dimm_type_u8 == fapi::ENUM_ATTR_EFF_DIMM_TYPE_LRDIMM ){ - FAPI_ERR("Invalid Dimm Type LRDIMM FREQ %d MBA0\n",l_mss_freq); - FAPI_ERR("Invalid Dimm Type LRDIMM FREQ %d MBA1\n",l_mss_freq); - FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR); return rc; + l_dimm_rc_u8 = 7; + // Set LRDIMM base var array as 1Rank RDIMM + if( l_target_mba_pos == 0){ + if ( l_mss_freq <= 1466 ) { // 1333Mbps + //Removed Width Check, use settings for either x8 or x4, use 1600 settings for 1333! + memcpy(base_var_array,rdimm_glacier_1600_r10_mba0,200*sizeof(uint32_t)); + FAPI_INF("LRDIMM: Base - RDIMM r10 %d MBA%s\n",l_mss_freq,i_target_mba.toEcmdString()); - } + } else if ( l_mss_freq <= 1733 ) { // 1600Mbps + //Removed Width Check, use settings for either x8 or x4 + memcpy(base_var_array,rdimm_glacier_1600_r10_mba0,200*sizeof(uint32_t)); + FAPI_INF("LRDIMM: Base - LRDIMM r10 %d MBA%s\n",l_mss_freq,i_target_mba.toEcmdString()); + } + }//MBA0 + else{ + if ( l_mss_freq <= 1466 ) { // 1333Mbps + if( (l_num_drops_per_port == fapi::ENUM_ATTR_EFF_NUM_DROPS_PER_PORT_SINGLE)){ + memcpy(base_var_array,rdimm_glacier_1333_r10_mba1,200*sizeof(uint32_t)); + FAPI_INF("LRDIMM: Base - RDIMM r10 %d MBA%s\n",l_mss_freq,i_target_mba.toEcmdString()); + } + else if( (l_num_drops_per_port == fapi::ENUM_ATTR_EFF_NUM_DROPS_PER_PORT_DUAL)){ + memcpy(base_var_array,rdimm_glacier_1333_r11_mba1,200*sizeof(uint32_t)); + FAPI_INF("LRDIMM: Base - RDIMM r11 %d MBA%s\n",l_mss_freq,i_target_mba.toEcmdString()); + } + else{ + FAPI_ERR("Invalid Dimm Type LRDIMM FREQ %d HERE MBA1\n",l_mss_freq); + FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR); return rc; + } + } else if ( l_mss_freq <= 1733 ) { // 1600Mbps + + if( (l_num_drops_per_port == fapi::ENUM_ATTR_EFF_NUM_DROPS_PER_PORT_SINGLE)){ + memcpy(base_var_array,rdimm_glacier_1600_r10_mba1,200*sizeof(uint32_t)); + FAPI_INF("LRDIMM: Base - RDIMM r10 %d MBA%s\n",l_mss_freq,i_target_mba.toEcmdString()); + } + else if( (l_num_drops_per_port == fapi::ENUM_ATTR_EFF_NUM_DROPS_PER_PORT_DUAL)){ + memcpy(base_var_array,rdimm_glacier_1600_r11_mba1,200*sizeof(uint32_t)); + FAPI_INF("LRDIMM: Base - RDIMM r11 %d MBA%s\n",l_mss_freq,i_target_mba.toEcmdString()); + } + else{ + FAPI_ERR("Invalid Dimm Type LRDIMM FREQ %d MBA1\n",l_mss_freq); + FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR); return rc; + } + } + }//MBA1 + +//---------------------------------------------------------------------------------------------------------------- + + // For dual drop, Set ODT_RD as 2rank (8R LRDIMM) or 4rank (4R LRDIMM) + if ( l_num_drops_per_port == fapi::ENUM_ATTR_EFF_NUM_DROPS_PER_PORT_DUAL ) { + uint32_t *p_1066_mba1_array = &rdimm_glacier_1066_r44_mba1[0]; + uint32_t *p_1333_x4_mba1_array = &rdimm_glacier_1333_r22e_mba1[0]; + uint32_t *p_1333_x8_mba1_array = &rdimm_glacier_1333_r22b_mba1[0]; + uint32_t *p_1600_x4_mba1_array = &rdimm_glacier_1600_r22e_mba1[0]; + uint32_t *p_1600_x8_mba1_array = &rdimm_glacier_1600_r22b_mba1[0]; + + uint32_t *p_b_var_array = &base_var_array[0]; + + uint32_t *var_array_p_array[] = {p_1066_mba1_array, p_1333_x4_mba1_array, p_1333_x8_mba1_array, + p_1600_x4_mba1_array, p_1600_x8_mba1_array}; + + rc = mss_lrdimm_rewrite_odt(i_target_mba, p_b_var_array, var_array_p_array); + + if(rc) + { + FAPI_ERR("FAILED LRDIMM rewrite ODT_RD"); + FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR); return rc; + } + } + } // LRDIMM else{ FAPI_ERR("Invalid Dimm Type"); FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR); return rc; @@ -1608,7 +1718,6 @@ fapi::ReturnCode mss_eff_config_termination(const fapi::Target i_target_mba) { attr_eff_cen_phase_rot_m1_cntl_odt0[1] = base_var_array[i++]; attr_eff_cen_phase_rot_m1_cntl_odt1[1] = base_var_array[i++]; attr_eff_dram_2n_mode_enabled = base_var_array[i++]; - //Now Setup the RCD - Done Here to Steal Code From Anuwats Version Of Eff Config Termination @@ -1688,14 +1797,17 @@ fapi::ReturnCode mss_eff_config_termination(const fapi::Target i_target_mba) { } } - - - // For DUAL DROP CDIMM + // Address mirroring uint8_t attr_eff_dram_address_mirroring[PORT_SIZE][DIMM_SIZE]; for( int l_port = 0; l_port < PORT_SIZE; l_port += 1 ) { for( int l_dimm = 0; l_dimm < DIMM_SIZE; l_dimm += 1 ) { if ((l_dimm_custom_u8 == fapi::ENUM_ATTR_EFF_CUSTOM_DIMM_YES) && (l_num_drops_per_port == fapi::ENUM_ATTR_EFF_NUM_DROPS_PER_PORT_DUAL) && (l_dimm == 1) && (l_dimm_rc_u8 !=3) && (l_stack_type_u8array[l_port][l_dimm] == fapi::ENUM_ATTR_EFF_STACK_TYPE_NONE)) { + // For DUAL DROP CDIMM attr_eff_dram_address_mirroring[l_port][l_dimm] = 0x0F; + } else if ( (l_dimm_type_u8 == fapi::ENUM_ATTR_EFF_DIMM_TYPE_LRDIMM) && (l_attr_eff_dimm_rcd_cntl_word_0_15[l_port][l_dimm] & 0x0000000000000010LL) ) { + // For LRDIMM SPD file , == 1 Odd ranks are mirrored + attr_eff_dram_address_mirroring[l_port][l_dimm] = 0x05; + } else { attr_eff_dram_address_mirroring[l_port][l_dimm] = 0x00; } @@ -1793,6 +1905,17 @@ fapi::ReturnCode mss_eff_config_termination(const fapi::Target i_target_mba) { attr_eff_gpo[1] = (uint8_t)5; } + else if(l_dimm_type_u8 == fapi::ENUM_ATTR_EFF_DIMM_TYPE_LRDIMM){ + //LRDIMM + attr_eff_rlo[0] = (uint8_t)6; + attr_eff_rlo[1] = (uint8_t)6; + //Set WLO and GPO + attr_eff_wlo[0] = (uint8_t)255; // WLO = -1, 2's complement + attr_eff_wlo[1] = (uint8_t)255; + attr_eff_gpo[0] = (uint8_t)7; + attr_eff_gpo[1] = (uint8_t)7; + + } else{ FAPI_ERR("Invalid Card Type RLO Settings \n"); FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR); return rc; @@ -1928,6 +2051,15 @@ fapi::ReturnCode mss_eff_config_termination(const fapi::Target i_target_mba) { rc = FAPI_ATTR_SET(ATTR_EFF_DRAM_ADDRESS_MIRRORING, &i_target_mba, attr_eff_dram_address_mirroring); if(rc) return rc; + if(l_dimm_type_u8 == fapi::ENUM_ATTR_EFF_DIMM_TYPE_LRDIMM) + { + rc = mss_lrdimm_term_atts(i_target_mba); + if (rc) + { + FAPI_ERR("Setting LR term atts failed \n"); + FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR); return rc; + } + } FAPI_INF("%s on %s COMPLETE", PROCEDURE_NAME, i_target_mba.toEcmdString()); return rc; diff --git a/src/usr/hwpf/hwp/mc_config/mss_eff_pre_config/mss_eff_pre_config.C b/src/usr/hwpf/hwp/mc_config/mss_eff_pre_config/mss_eff_pre_config.C new file mode 100644 index 000000000..de0b4e1fa --- /dev/null +++ b/src/usr/hwpf/hwp/mc_config/mss_eff_pre_config/mss_eff_pre_config.C @@ -0,0 +1,157 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/hwpf/hwp/mc_config/mss_eff_pre_config/mss_eff_pre_config.C $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2013 */ +/* */ +/* 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_eff_pre_config.C,v 1.1 2013/08/06 23:30:21 asaetow Exp $ +// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/centaur/working/procedures/ipl/fapi/mss_eff_pre_config.C,v $ +//------------------------------------------------------------------------------ +// *! (C) Copyright International Business Machines Corp. 2011 +// *! All Rights Reserved -- Property of IBM +// *! *** IBM Confidential *** +//------------------------------------------------------------------------------ +// *! TITLE : mss_eff_pre_config +// *! DESCRIPTION : see additional comments below +// *! OWNER NAME : Michael Pardeik Email: pardeik@us.ibm.com +// *! BACKUP NAME : Anuwat Saetow Email: asaetow@us.ibm.com +// *! ADDITIONAL COMMENTS : +// +// This procedure puts in required attributes for mss_eff_config_thermal which are based on "worst case" config in case these attributes were not able to be setup by mss_eff_config. +// +//------------------------------------------------------------------------------ +// Don't forget to create CVS comments when you check in your changes! +//------------------------------------------------------------------------------ +// CHANGE HISTORY: +//------------------------------------------------------------------------------ +// Version:| Author: | Date: | Comment: +//---------|----------|---------|----------------------------------------------- +// 1.2 | | | +// 1.1 | asaetow |02-AUG-13| First Draft. + + + +//---------------------------------------------------------------------- +// My Includes +//---------------------------------------------------------------------- + + + +//---------------------------------------------------------------------- +// Includes +//---------------------------------------------------------------------- +#include <fapi.H> + + + +//---------------------------------------------------------------------- +// ENUMs +//---------------------------------------------------------------------- + + + +extern "C" { + + + +//****************************************************************************** +//* name=mss_eff_pre_config, param=i_target_mba, return=ReturnCode +//****************************************************************************** +fapi::ReturnCode mss_eff_pre_config(const fapi::Target i_target_mba) { + fapi::ReturnCode rc = fapi::FAPI_RC_SUCCESS; + const char * const PROCEDURE_NAME = "mss_eff_pre_config"; + FAPI_INF("*** Running %s on %s ... ***", PROCEDURE_NAME, i_target_mba.toEcmdString()); + + + const uint32_t MSS_EFF_EMPTY = 0; + const uint32_t MSS_EFF_VALID = 255; + const uint8_t PORT_SIZE = 2; + const uint8_t DIMM_SIZE = 2; + + // Grab DIMM/SPD data. + uint8_t cur_dimm_spd_valid_u8array[PORT_SIZE][DIMM_SIZE]; + uint8_t spd_custom[PORT_SIZE][DIMM_SIZE]; + for (uint8_t cur_port = 0; cur_port < PORT_SIZE; cur_port += 1) { + for (uint8_t cur_dimm = 0; cur_dimm < DIMM_SIZE; cur_dimm += 1) { + cur_dimm_spd_valid_u8array[cur_port][cur_dimm] = MSS_EFF_EMPTY; + spd_custom[cur_port][cur_dimm] = 0; + } + } + uint8_t cur_mba_port = 0; + uint8_t cur_mba_dimm = 0; + std::vector<fapi::Target> l_target_dimm_array; + rc = fapiGetAssociatedDimms(i_target_mba, l_target_dimm_array); if(rc) return rc; + for (uint8_t dimm_index = 0; dimm_index < l_target_dimm_array.size(); dimm_index += 1) { + rc = FAPI_ATTR_GET(ATTR_MBA_PORT, &l_target_dimm_array[dimm_index], cur_mba_port); if(rc) return rc; + rc = FAPI_ATTR_GET(ATTR_MBA_DIMM, &l_target_dimm_array[dimm_index], cur_mba_dimm); if(rc) return rc; + cur_dimm_spd_valid_u8array[cur_mba_port][cur_mba_dimm] = MSS_EFF_VALID; + rc = FAPI_ATTR_GET(ATTR_SPD_CUSTOM, &l_target_dimm_array[dimm_index], spd_custom[cur_mba_port][cur_mba_dimm]); if(rc) return rc; + } + + uint32_t eff_cen_rcv_imp_dq_dqs_schmoo[PORT_SIZE]; + uint32_t eff_cen_drv_imp_dq_dqs_schmoo[PORT_SIZE]; + uint8_t eff_dram_gen = fapi::ENUM_ATTR_EFF_DRAM_GEN_DDR3; + uint8_t eff_dimm_type = fapi::ENUM_ATTR_EFF_DIMM_TYPE_LRDIMM; + uint8_t eff_custom_dimm = fapi::ENUM_ATTR_EFF_CUSTOM_DIMM_YES; + uint8_t eff_dram_width = fapi::ENUM_ATTR_EFF_DRAM_WIDTH_X4; + uint8_t eff_dram_tdqs = fapi::ENUM_ATTR_EFF_DRAM_TDQS_DISABLE; + uint8_t eff_num_ranks_per_dimm[PORT_SIZE][DIMM_SIZE]; + uint8_t eff_num_master_ranks_per_dimm[PORT_SIZE][DIMM_SIZE]; + uint8_t eff_dimm_ranks_configed[PORT_SIZE][DIMM_SIZE]; + uint8_t eff_num_drops_per_port = fapi::ENUM_ATTR_EFF_NUM_DROPS_PER_PORT_SINGLE; + + if (cur_dimm_spd_valid_u8array[0][0] == MSS_EFF_VALID) { + if (spd_custom[0][0] == fapi::ENUM_ATTR_SPD_CUSTOM_YES) { + eff_custom_dimm = fapi::ENUM_ATTR_EFF_CUSTOM_DIMM_YES; + } else { + eff_custom_dimm = fapi::ENUM_ATTR_EFF_CUSTOM_DIMM_NO; + } + } else { + FAPI_INF("WARNING: Plug rule violation at %s!", i_target_mba.toEcmdString()); + FAPI_INF("WARNING: Do NOT trust ATTR_EFF_CUSTOM_DIMM for %s!", i_target_mba.toEcmdString()); + } + + for (uint8_t cur_port = 0; cur_port < PORT_SIZE; cur_port += 1) { + eff_cen_rcv_imp_dq_dqs_schmoo[cur_port] = 0; + eff_cen_drv_imp_dq_dqs_schmoo[cur_port] = 0; + for (uint8_t cur_dimm = 0; cur_dimm < DIMM_SIZE; cur_dimm += 1) { + eff_num_ranks_per_dimm[cur_port][cur_dimm] = 8; + eff_num_master_ranks_per_dimm[cur_port][cur_dimm] = 8; + eff_dimm_ranks_configed[cur_port][cur_dimm] = 0xFF; + } + } + + rc = FAPI_ATTR_SET(ATTR_EFF_CEN_RCV_IMP_DQ_DQS_SCHMOO, &i_target_mba, eff_cen_rcv_imp_dq_dqs_schmoo); if(rc) return rc; + rc = FAPI_ATTR_SET(ATTR_EFF_CEN_DRV_IMP_DQ_DQS_SCHMOO, &i_target_mba, eff_cen_drv_imp_dq_dqs_schmoo); if(rc) return rc; + rc = FAPI_ATTR_SET(ATTR_EFF_DRAM_GEN, &i_target_mba, eff_dram_gen); if(rc) return rc; + rc = FAPI_ATTR_SET(ATTR_EFF_DIMM_TYPE, &i_target_mba, eff_dimm_type); if(rc) return rc; + rc = FAPI_ATTR_SET(ATTR_EFF_CUSTOM_DIMM, &i_target_mba, eff_custom_dimm); if(rc) return rc; + rc = FAPI_ATTR_SET(ATTR_EFF_DRAM_WIDTH, &i_target_mba, eff_dram_width); if(rc) return rc; + rc = FAPI_ATTR_SET(ATTR_EFF_DRAM_TDQS, &i_target_mba, eff_dram_tdqs); if(rc) return rc; + rc = FAPI_ATTR_SET(ATTR_EFF_NUM_RANKS_PER_DIMM, &i_target_mba, eff_num_ranks_per_dimm); if(rc) return rc; + rc = FAPI_ATTR_SET(ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM, &i_target_mba, eff_num_master_ranks_per_dimm); if(rc) return rc; + rc = FAPI_ATTR_SET(ATTR_EFF_DIMM_RANKS_CONFIGED, &i_target_mba, eff_dimm_ranks_configed); if(rc) return rc; + rc = FAPI_ATTR_SET(ATTR_EFF_NUM_DROPS_PER_PORT, &i_target_mba, eff_num_drops_per_port); if(rc) return rc; + + return rc; +} + + + +} // extern "C" diff --git a/src/usr/hwpf/hwp/mc_config/mss_eff_pre_config/mss_eff_pre_config.H b/src/usr/hwpf/hwp/mc_config/mss_eff_pre_config/mss_eff_pre_config.H new file mode 100755 index 000000000..bb1393467 --- /dev/null +++ b/src/usr/hwpf/hwp/mc_config/mss_eff_pre_config/mss_eff_pre_config.H @@ -0,0 +1,74 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/hwpf/hwp/mc_config/mss_eff_pre_config/mss_eff_pre_config.H $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2013 */ +/* */ +/* 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_eff_pre_config.H,v 1.1 2013/08/06 23:30:39 asaetow Exp $ +// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/centaur/working/procedures/ipl/fapi/mss_eff_pre_config.H,v $ +//------------------------------------------------------------------------------ +// *! (C) Copyright International Business Machines Corp. 2011 +// *! All Rights Reserved -- Property of IBM +// *! *** IBM Confidential *** +//------------------------------------------------------------------------------ +// *! TITLE : mss_eff_pre_config.H +// *! DESCRIPTION : Header file for mss_eff_pre_config. +// *! OWNER NAME : Michael Pardeik Email: pardeik@us.ibm.com +// *! BACKUP NAME : Anuwat Saetow Email: asaetow@us.ibm.com +// *! ADDITIONAL COMMENTS : +// +// +// +//------------------------------------------------------------------------------ +// Don't forget to create CVS comments when you check in your changes! +//------------------------------------------------------------------------------ +// CHANGE HISTORY: +//------------------------------------------------------------------------------ +// Version:| Author: | Date: | Comment: +//---------|----------|---------|----------------------------------------------- +// 1.2 | | | +// 1.1 | asaetow |02-AUG-13| First Draft. + + +#ifndef MSS_EFF_PRE_CONFIG_H_ +#define MSS_EFF_PRE_CONFIG_H_ + +//---------------------------------------------------------------------- +// My Includes +//---------------------------------------------------------------------- + + +//---------------------------------------------------------------------- +// Includes +//---------------------------------------------------------------------- +#include <fapi.H> + + +typedef fapi::ReturnCode (*mss_eff_pre_config_FP_t)(const fapi::Target i_target_mba); + +extern "C" { + +//****************************************************************************** +//* name=mss_eff_pre_config, param=i_target_mba, return=ReturnCode +//****************************************************************************** +fapi::ReturnCode mss_eff_pre_config(const fapi::Target i_target_mba); + +} // extern "C" + +#endif // MSS_EFF_PRE_CONFIG_H_ |