summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorThi Tran <thi@us.ibm.com>2013-09-16 16:09:48 -0500
committerA. Patrick Williams III <iawillia@us.ibm.com>2013-09-18 10:46:25 -0500
commit44933fc2a399c991c7ef31b1a29219f808c4395e (patch)
treef6fa7ad0b47c91bf7d5c37bd88f24fa72654270b /src
parentaf0bcac5124a4c54ec38e6d00d14f2cec19d5c77 (diff)
downloadtalos-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')
-rw-r--r--src/usr/hwpf/hwp/centaur_ec_attributes.xml74
-rw-r--r--src/usr/hwpf/hwp/dram_training/makefile5
-rwxr-xr-xsrc/usr/hwpf/hwp/dram_training/mss_draminit/mss_draminit.C136
-rw-r--r--src/usr/hwpf/hwp/dram_training/mss_draminit_training/mss_draminit_training.C167
-rw-r--r--src/usr/hwpf/hwp/dram_training/mss_funcs.C21
-rw-r--r--src/usr/hwpf/hwp/dram_training/mss_funcs.H5
-rw-r--r--src/usr/hwpf/hwp/dram_training/mss_lrdimm_funcs/mss_lrdimm_funcs.C1965
-rw-r--r--src/usr/hwpf/hwp/dram_training/mss_lrdimm_funcs/mss_lrdimm_funcs.H165
-rw-r--r--src/usr/hwpf/hwp/mc_config/makefile4
-rw-r--r--src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_eff_config.C92
-rw-r--r--src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_eff_config_termination.C196
-rw-r--r--src/usr/hwpf/hwp/mc_config/mss_eff_pre_config/mss_eff_pre_config.C157
-rwxr-xr-xsrc/usr/hwpf/hwp/mc_config/mss_eff_pre_config/mss_eff_pre_config.H74
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_
OpenPOWER on IntegriCloud