summaryrefslogtreecommitdiffstats
path: root/src/usr/hwpf/hwp/mc_config
diff options
context:
space:
mode:
authorMike Jones <mjjones@us.ibm.com>2012-12-13 22:02:00 -0600
committerA. Patrick Williams III <iawillia@us.ibm.com>2012-12-14 17:08:50 -0600
commit79224c14f497d5994e999533921068961f80c071 (patch)
tree7d0a06cdb60fa5c08d5e6ef41eae540b239d7d38 /src/usr/hwpf/hwp/mc_config
parent0a2247cec574fc6c8b33ade659b336282324ddc5 (diff)
downloadtalos-hostboot-79224c14f497d5994e999533921068961f80c071.tar.gz
talos-hostboot-79224c14f497d5994e999533921068961f80c071.zip
Refresh Memory HWPs
Change-Id: Id15d99072821587d1abd2c399042b5b64f859cef RTC: 59193 Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/2690 Tested-by: Jenkins Server Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src/usr/hwpf/hwp/mc_config')
-rw-r--r--src/usr/hwpf/hwp/mc_config/makefile5
-rw-r--r--src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_bulk_pwr_throttles.C343
-rw-r--r--src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_bulk_pwr_throttles.H75
-rw-r--r--src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_eff_config.C293
-rw-r--r--src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_eff_config_cke_map.C335
-rwxr-xr-xsrc/usr/hwpf/hwp/mc_config/mss_eff_config/mss_eff_config_cke_map.H74
-rw-r--r--src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_eff_config_termination.C1043
-rw-r--r--src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_eff_config_thermal.C1483
-rw-r--r--src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_eff_config_thermal.H9
-rw-r--r--src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_eff_grouping.C564
-rw-r--r--src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_throttle_to_power.C293
-rw-r--r--src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_throttle_to_power.H104
-rw-r--r--src/usr/hwpf/hwp/mc_config/mss_freq/mss_freq.C108
-rw-r--r--src/usr/hwpf/hwp/mc_config/mss_volt/mss_volt.C149
14 files changed, 4318 insertions, 560 deletions
diff --git a/src/usr/hwpf/hwp/mc_config/makefile b/src/usr/hwpf/hwp/mc_config/makefile
index cab13d0af..821bdfcb9 100644
--- a/src/usr/hwpf/hwp/mc_config/makefile
+++ b/src/usr/hwpf/hwp/mc_config/makefile
@@ -48,7 +48,10 @@ OBJS = mc_config.o \
opt_memmap.o \
mss_eff_config_thermal.o \
mss_eff_config_termination.o \
- mss_eff_config_rank_group.o
+ mss_eff_config_rank_group.o \
+ mss_eff_config_cke_map.o \
+ mss_bulk_pwr_throttles.o \
+ mss_throttle_to_power.o
## NOTE: add a new directory onto the vpaths when you add a new HWP
##@ VPATH += ${ROOTPATH}/src/usr/hwpf/hwp/???
diff --git a/src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_bulk_pwr_throttles.C b/src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_bulk_pwr_throttles.C
new file mode 100644
index 000000000..c7407f789
--- /dev/null
+++ b/src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_bulk_pwr_throttles.C
@@ -0,0 +1,343 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_bulk_pwr_throttles.C $ */
+/* */
+/* IBM CONFIDENTIAL */
+/* */
+/* COPYRIGHT International Business Machines Corp. 2012 */
+/* */
+/* p1 */
+/* */
+/* Object Code Only (OCO) source materials */
+/* Licensed Internal Code Source Materials */
+/* IBM HostBoot Licensed Internal Code */
+/* */
+/* The source code for this program is not published or otherwise */
+/* divested of its trade secrets, irrespective of what has been */
+/* deposited with the U.S. Copyright Office. */
+/* */
+/* Origin: 30 */
+/* */
+/* IBM_PROLOG_END_TAG */
+// $Id: mss_bulk_pwr_throttles.C,v 1.10 2012/11/13 16:45:28 bellows Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/centaur/working/procedures/ipl/fapi/mss_bulk_pwr_throttles.C,v $
+//------------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2011
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//------------------------------------------------------------------------------
+// *! TITLE : mss_bulk_pwr_throttles
+// *! DESCRIPTION : see additional comments below
+// *! OWNER NAME : Joab Henderson Email: joabhend@us.ibm.com
+// *! BACKUP NAME : Michael Pardeik Email: pardeik@us.ibm.com
+// *! ADDITIONAL COMMENTS :
+//
+// applicable CQ component memory_screen
+//
+// DESCRIPTION:
+// The purpose of this procedure is to set the throttle attributes based on a power limit for the dimms on the channel pair
+// At the end, output attributes will be updated with throttle values that will have dimms at or below the limit
+// NOTE: ISDIMMs and CDIMMs are handled differently
+// ISDIMMs use a power per DIMM for the thermal power limit from the MRW
+// CDIMM will use power per CDIMM (power for all virtual dimms) for the thermal power limit from the MRW
+// Plan is to have ISDIMM use the per-slot throttles (thermal throttles) or per-mba throttles (power throttles), and CDIMM to use the per-chip throttles
+// Note that throttle_n_per_mba takes on different meanings depending on how cfg_nm_per_slot_enabled is set
+// Can be slot0/slot1 OR slot0/MBA throttling
+// Note that throttle_n_per_chip takes on different meaning depending on how cfg_count_other_mba_dis is set
+// Can be per-chip OR per-mba throttling
+// ISDIMM: These registers need to be setup to these values, will be able to do per slot or per MBA throttling
+// cfg_nm_per_slot_enabled = 1
+// cfg_count_other_mba_dis = 1
+// CDIMM: These registers need to be setup to these values, will be able to do per slot or per chip throttling
+// cfg_nm_per_slot_enabled = 1
+// cfg_count_other_mba_dis = 0
+//
+//
+//------------------------------------------------------------------------------
+// Don't forget to create CVS comments when you check in your changes!
+//------------------------------------------------------------------------------
+// CHANGE HISTORY:
+//------------------------------------------------------------------------------
+// Version:| Author: | Date: | Comment:
+//---------|----------|---------|-----------------------------------------------
+// 1.10 | pardeik |08-NOV-12| attribute name update for runtime per chip throttles
+// 1.9 | pardeik |25-OCT-12| updated FAPI_ERR sections, use per_chip variables (in if statements) in the throttle update section when channel pair power is greater than the limit, added CQ component comment line
+// 1.8 | pardeik |19-OCT-12| Changed throttle_n_per_chip to be based on num_mba_with_dimms
+// | pardeik |19-OCT-12| Updated default throttle values to represent cmd bus utilization instead of dram bus utilization
+// | pardeik |19-OCT-12| multiple throttle N values by 4 to get dram utilization
+// 1.7 | pardeik |10-OCT-12| Changed throttle attributes and call new function (mss_throttle_to_power) to calculate the power
+// 1.6 | pardeik |10-APR-12| power calculation fixes and updates
+// 1.5 | pardeik |04-APR-12| moved cdimm power calculation to end of section instead of having it in multiple places
+// 1.4 | pardeik |04-APR-12| do channel throttle denominator check as zero only if there are ranks present
+// | pardeik |04-APR-12| use else if instead of if after checking throttle denominator to zero
+// 1.3 | pardeik |03-APR-12| added cdimm power calculation for half of cdimm, changed i_target from mbs to mba
+// 1.2 | pardeik |03-APR-12| call mss_eff_config_thermal directly
+// 1.1 | pardeik |28-MAR-12| Updated to use Attributes
+// | pardeik |11-NOV-11| First Draft.
+
+
+//------------------------------------------------------------------------------
+// My Includes
+//------------------------------------------------------------------------------
+#include <mss_bulk_pwr_throttles.H>
+#include <mss_throttle_to_power.H>
+
+//------------------------------------------------------------------------------
+// Includes
+//------------------------------------------------------------------------------
+#include <fapi.H>
+
+
+extern "C" {
+
+ using namespace fapi;
+
+
+//------------------------------------------------------------------------------
+// Funtions in this file
+//------------------------------------------------------------------------------
+ fapi::ReturnCode mss_bulk_pwr_throttles(const fapi::Target & i_target_mba);
+
+
+//------------------------------------------------------------------------------
+// @brief mss_bulk_pwr_throttles(): This function determines the throttle values from a MBA channel pair power limit
+//
+// @param const fapi::Target & i_target_mba: MBA Target passed in
+//
+// @return fapi::ReturnCode
+//------------------------------------------------------------------------------
+
+ fapi::ReturnCode mss_bulk_pwr_throttles(const fapi::Target & i_target_mba)
+ {
+ fapi::ReturnCode rc;
+
+ char procedure_name[32];
+ sprintf(procedure_name, "mss_bulk_pwr_throttles");
+ FAPI_INF("*** Running %s ***", procedure_name);
+
+ enum
+ {
+ CDIMM = fapi::ENUM_ATTR_EFF_DIMM_TYPE_CDIMM,
+ RDIMM = fapi::ENUM_ATTR_EFF_DIMM_TYPE_RDIMM,
+ UDIMM = fapi::ENUM_ATTR_EFF_DIMM_TYPE_UDIMM,
+ LRDIMM = fapi::ENUM_ATTR_EFF_DIMM_TYPE_LRDIMM,
+ };
+
+// other variables used in this procedure
+ const uint8_t MAX_NUM_PORTS = 2; // number of ports per MBA
+ const uint8_t MAX_NUM_DIMMS = 2; // number of dimms per MBA port
+ const float MIN_UTIL = 1; // Minimum percent data bus utilization (percent of max) allowed (for floor)
+// If this is changed, also change mss_throttle_to_power MAX_UTIL
+ const float MAX_UTIL = 75; // Maximum theoretical data bus utilization (percent of max) (for ceiling)
+ const uint32_t MEM_THROTTLE_D_DEFAULT = 512; // default throttle denominator (unthrottled) for cfg_nm_m
+ const uint32_t MEM_THROTTLE_N_DEFAULT_PER_MBA = (int)(MEM_THROTTLE_D_DEFAULT * (MAX_UTIL / 100) / 4); // default throttle numerator (unthrottled) for cfg_nm_n_per_mba
+ const uint32_t MEM_THROTTLE_N_DEFAULT_PER_CHIP = (int)(MEM_THROTTLE_D_DEFAULT * (MAX_UTIL / 100) / 4); // default throttle numerator (unthrottled) for cfg_nm_n_per_chip
+ fapi::Target target_chip;
+ std::vector<fapi::Target> target_mba_array;
+ std::vector<fapi::Target> target_dimm_array;
+ uint32_t channel_pair_watt_target;
+ uint32_t throttle_n_per_mba;
+ uint32_t throttle_n_per_chip;
+ uint32_t throttle_d;
+ uint8_t port;
+ uint8_t dimm;
+ bool not_enough_available_power;
+ bool channel_pair_throttle_done;
+ float channel_pair_power;
+ uint8_t dimm_type;
+ uint8_t num_mba_with_dimms;
+ uint32_t power_int_array[MAX_NUM_PORTS][MAX_NUM_DIMMS];
+ bool thermal_throttle_active;
+ uint8_t mba_index;
+
+// Get input attributes
+ rc = FAPI_ATTR_GET(ATTR_EFF_DIMM_TYPE, &i_target_mba, dimm_type);
+ if(rc) return rc;
+ rc = FAPI_ATTR_GET(ATTR_MSS_MEM_WATT_TARGET, &i_target_mba, channel_pair_watt_target);
+ if(rc) return rc;
+ rc = FAPI_ATTR_GET(ATTR_MSS_POWER_INT, &i_target_mba, power_int_array);
+ if(rc) return rc;
+// runtime throttles will be the thermal throttle values (or zero if not initialized yet)
+ rc = FAPI_ATTR_GET(ATTR_MSS_RUNTIME_MEM_THROTTLE_NUMERATOR_PER_MBA, &i_target_mba, throttle_n_per_mba);
+ if(rc) return rc;
+ rc = FAPI_ATTR_GET(ATTR_MSS_RUNTIME_MEM_THROTTLE_NUMERATOR_PER_CHIP, &i_target_mba, throttle_n_per_chip);
+ if(rc) return rc;
+ rc = FAPI_ATTR_GET(ATTR_MSS_RUNTIME_MEM_THROTTLE_DENOMINATOR, &i_target_mba, throttle_d);
+ if(rc) return rc;
+
+// get number of mba's with dimms for a CDIMM
+ if (dimm_type == CDIMM)
+ {
+// Get Centaur target for the given MBA
+ rc = fapiGetParentChip(i_target_mba, target_chip);
+ if(rc) return rc;
+// Get MBA targets from the parent chip centaur
+ rc = fapiGetChildChiplets(target_chip, fapi::TARGET_TYPE_MBA_CHIPLET, target_mba_array, fapi::TARGET_STATE_PRESENT);
+ if(rc) return rc;
+ num_mba_with_dimms = 0;
+ for (mba_index=0; mba_index < target_mba_array.size(); mba_index++)
+ {
+ rc = fapiGetAssociatedDimms(target_mba_array[mba_index], target_dimm_array, fapi::TARGET_STATE_PRESENT);
+ if(rc) return rc;
+ if (target_dimm_array.size() > 0)
+ {
+ num_mba_with_dimms++;
+ }
+ }
+
+ }
+ else
+ {
+ // ISDIMMs, set to a value of one since they are handled on a per MBA basis
+ num_mba_with_dimms = 1;
+ }
+
+///////////////////////////////
+// THROTTLE SECTION
+///////////////////////////////
+
+// Determine if the channel pair power for this MBA is over the limit when the runtime memory throttle settings are used
+// If not over the limit, then use the runtime throttle settings (defined in mss_eff_config_thermal)
+// If over limit, then increase throttle value until it is at or below limit
+// If unable to get power below limit, then call out an error
+
+// Determine whether to base throttles on thermal or power reasons (power throttles can give you better performance than thermal throttles)
+ if ((throttle_n_per_mba == 0) && (throttle_n_per_chip == 0) && (throttle_d == 0))
+ {
+ // runtime throttles are all zero here, they have not been defined yet and need to be
+ thermal_throttle_active = true;
+ // Set runtime throttles to default values as a starting value
+ throttle_n_per_mba = MEM_THROTTLE_N_DEFAULT_PER_MBA;
+ throttle_n_per_chip = MEM_THROTTLE_N_DEFAULT_PER_CHIP * num_mba_with_dimms;
+ throttle_d = MEM_THROTTLE_D_DEFAULT;
+ }
+ else if ((throttle_n_per_mba != MEM_THROTTLE_N_DEFAULT_PER_MBA) || (throttle_n_per_chip != (MEM_THROTTLE_N_DEFAULT_PER_CHIP * num_mba_with_dimms)) || (throttle_d != MEM_THROTTLE_D_DEFAULT))
+ {
+ // if runtime throttles are not equal to the default values, then thermal throttles are in place
+ thermal_throttle_active = true;
+ }
+ else
+ {
+ // runtime throttles are not all zero and equal to the defaults, so no thermal throttles are in place - so now any throttles will be power based
+ thermal_throttle_active = false;
+ }
+
+// Adjust power limit value as needed here
+// For CDIMM, we want the throttles to be per-chip, and to allow all commands to go to one MBA to get to the power limit
+ if (dimm_type == CDIMM)
+ {
+// Set channel pair power limit to whole CDIMM power limit (multiply by number of MBAs used) and subtract off idle power for dimms on other MBA
+ channel_pair_watt_target = channel_pair_watt_target * num_mba_with_dimms;
+ for (port=0; port < MAX_NUM_PORTS; port++)
+ {
+ for (dimm=0; dimm < MAX_NUM_DIMMS; dimm++)
+ {
+ channel_pair_watt_target = channel_pair_watt_target - ((num_mba_with_dimms - 1) * (power_int_array[port][dimm]));
+ }
+ }
+ }
+
+// calculate power and change throttle values in this while loop until limit has been satisfied or throttles have reached the minimum limit
+ not_enough_available_power = false;
+ channel_pair_throttle_done = false;
+ while (channel_pair_throttle_done == false)
+ {
+ rc = mss_throttle_to_power_calc(
+ i_target_mba,
+ throttle_n_per_mba,
+ throttle_n_per_chip,
+ throttle_d,
+ channel_pair_power
+ );
+ if(rc)
+ {
+ FAPI_ERR("Error (0x%x) calling mss_throttle_to_power_calc", static_cast<uint32_t>(rc));
+ return rc;
+ }
+
+// compare channel pair power to mss_watt_target for channel and decrease throttles if it is above this limit
+// throttle decrease will decrement throttle numerator by one (or increase throttle denominator) and recalculate power until utilization (N/M) reaches a lower limit
+
+ if (channel_pair_power > channel_pair_watt_target)
+ {
+// check to see if dimm utilization is greater than the min utilization limit, continue if it is, error if it is not
+ if ((((((float)throttle_n_per_chip * 100 * 4) / throttle_d) > MIN_UTIL) && (dimm_type != CDIMM) && (thermal_throttle_active == false)) || (((((float)throttle_n_per_chip * 100 * 4) / throttle_d) > MIN_UTIL) && (dimm_type != CDIMM) && (thermal_throttle_active == true)) || (((((float)throttle_n_per_chip * 100 * 4) / throttle_d) > MIN_UTIL) && (dimm_type == CDIMM)))
+ {
+ if (((throttle_n_per_chip > 1) && (dimm_type != CDIMM) && (thermal_throttle_active == false)) || ((throttle_n_per_chip > 1) && (dimm_type != CDIMM) && (thermal_throttle_active == true)) || ((throttle_n_per_chip > 1) && (dimm_type == CDIMM)))
+ {
+ if (dimm_type == CDIMM)
+ {
+ // CDIMMs, use per chip throttling for any thermal or available power limits
+ throttle_n_per_chip--;
+ }
+ else
+ {
+ // ISDIMMs, use per slot throttling for thermal power limits
+ if (thermal_throttle_active == true)
+ {
+// per_mba throttling (ie. per dimm for ISDIMMs) will limit performance if all traffic is sent to one dimm, so use the per_chip
+// This works as long as the other dimm is providing termination (for 2 dimms per channel)
+// If the other dimm is not providing termination, then we would want to redefine the power curve in mss_eff_config_thermal and use the per_mba throttle here
+// It there is only one dimm on channel, then it will provide its own termination and the per_mba and per_chip will effectively do the same throttling (ie. doesn't matter which one we do in this case)
+// Warning: If this changes, then the two if statements above need to be modified
+// throttle_n_per_mba--;
+ throttle_n_per_chip--;
+ }
+ else
+ {
+ // ISDIMMs, use per mba throttling for available power limit
+// Warning: If this changes, then the two if statements above need to be modified
+ throttle_n_per_chip--;
+ }
+ }
+ }
+// increment throttle denominator if numerator is at one (its lowest setting)
+ else
+ {
+ throttle_d++;
+ }
+ FAPI_DBG("Throttle update [N_per_mba/N_per_chip/M %d/%d/%d]", throttle_n_per_mba, throttle_n_per_chip, throttle_d);
+ }
+// minimum utilization limit was reached for this throttle N/M value
+ else
+ {
+// Throttles can't be changed anymore (already at or below MIN_UTIL)
+ channel_pair_throttle_done = true;
+ not_enough_available_power = true;
+ }
+ }
+// channel pair power is less than limit, so keep existing throttles
+ else
+ {
+ FAPI_DBG("There is enough available memory power [Channel Pair Power %4.2f/%d cW]", channel_pair_power, channel_pair_watt_target);
+ channel_pair_throttle_done = true;
+ }
+ }
+
+ FAPI_DBG("Final Throttle Settings [N_per_mba/N_per_chip/M %d/%d/%d]", throttle_n_per_mba, throttle_n_per_chip, throttle_d);
+
+
+// update output attributes
+ rc = FAPI_ATTR_SET(ATTR_MSS_MEM_THROTTLE_NUMERATOR_PER_MBA, &i_target_mba, throttle_n_per_mba);
+ if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_MSS_MEM_THROTTLE_NUMERATOR_PER_CHIP, &i_target_mba, throttle_n_per_chip);
+ if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_MSS_MEM_THROTTLE_DENOMINATOR, &i_target_mba, throttle_d);
+ if(rc) return rc;
+
+ if (not_enough_available_power == true)
+ {
+ FAPI_ERR("Not enough available memory power [Channel Pair Power %4.2f/%d cW]", channel_pair_power, channel_pair_watt_target);
+ FAPI_SET_HWP_ERROR(rc, RC_MSS_NOT_ENOUGH_AVAILABLE_DIMM_POWER);
+ if (rc) fapiLogError(rc);
+ }
+ FAPI_INF("*** %s COMPLETE ***", procedure_name);
+ return rc;
+
+ }
+
+
+} //end extern C
+
+
diff --git a/src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_bulk_pwr_throttles.H b/src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_bulk_pwr_throttles.H
new file mode 100644
index 000000000..2b86242c8
--- /dev/null
+++ b/src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_bulk_pwr_throttles.H
@@ -0,0 +1,75 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_bulk_pwr_throttles.H $ */
+/* */
+/* IBM CONFIDENTIAL */
+/* */
+/* COPYRIGHT International Business Machines Corp. 2012 */
+/* */
+/* p1 */
+/* */
+/* Object Code Only (OCO) source materials */
+/* Licensed Internal Code Source Materials */
+/* IBM HostBoot Licensed Internal Code */
+/* */
+/* The source code for this program is not published or otherwise */
+/* divested of its trade secrets, irrespective of what has been */
+/* deposited with the U.S. Copyright Office. */
+/* */
+/* Origin: 30 */
+/* */
+/* IBM_PROLOG_END_TAG */
+// $Id: mss_bulk_pwr_throttles.H,v 1.3 2012/10/15 13:05:17 pardeik Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/centaur/working/procedures/ipl/fapi/mss_bulk_pwr_throttles.H,v $
+//------------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2011
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//------------------------------------------------------------------------------
+// *! TITLE : mss_bulk_pwr_throttles.H
+// *! DESCRIPTION : see additional comments below
+// *! OWNER NAME : Joab Henderson Email: joabhend@us.ibm.com
+// *! BACKUP NAME : Michael Pardeik Email: pardeik@us.ibm.com
+// *! ADDITIONAL COMMENTS :
+//
+// Header file for mss_bulk_pwr_throttles.
+//
+//------------------------------------------------------------------------------
+// Don't forget to create CVS comments when you check in your changes!
+//------------------------------------------------------------------------------
+// CHANGE HISTORY:
+//------------------------------------------------------------------------------
+// Version:| Author: | Date: | Comment:
+//---------|----------|---------|-----------------------------------------------
+// 1.3 | pardeik |11-OCT-12| change i_target to i_target_mba
+// 1.2 | pardeik |03-APR-12| use mba target intead of mbs
+// 1.1 | pardeik |11-NOV-11| First Draft.
+
+
+
+#ifndef MSS_BULK_PWR_THROTTLES_H_
+#define MSS_BULK_PWR_THROTTLES_H_
+
+//----------------------------------------------------------------------
+// Includes
+//----------------------------------------------------------------------
+#include <fapi.H>
+
+typedef fapi::ReturnCode (*mss_bulk_pwr_throttles_FP_t)(const fapi::Target & i_target_mba);
+
+extern "C"
+{
+/**
+ * @brief mss_bulk_pwr_throttles procedure. Set dimm and channel throttle attributes based on available centaur mba port power
+ *
+ * @param[in] i_target_mba Reference to centaur mba target
+ *
+ * @return ReturnCode
+ */
+
+ fapi::ReturnCode mss_bulk_pwr_throttles(const fapi::Target & i_target_mba);
+
+} // extern "C"
+
+#endif // MSS_BULK_PWR_THROTTLES_H_
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 d95469964..51abb1a37 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.11 2012/09/25 17:58:32 mjjones Exp $
+// $Id: mss_eff_config.C,v 1.15 2012/11/16 14:44:04 asaetow Exp $
// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/
// centaur/working/procedures/ipl/fapi/mss_eff_config.C,v $
//------------------------------------------------------------------------------
@@ -44,8 +44,38 @@
//------------------------------------------------------------------------------
// Version:| Author: | Date: | Comment:
//---------|----------|---------|-----------------------------------------------
-// 1.12 | | |
-// 1.11 | kjpower |27-AUG-12| Restructured code, added modularity
+// 1.16 | | |
+// 1.15 | asaetow |15-NOV-12| Added call to mss_eff_config_cke_map().
+// | | | NOTE: DO NOT pick-up without
+// | | | mss_eff_config_cke_map.C v1.3 or newer.
+// | | | Added ATTR_MSS_ALLOW_SINGLE_PORT check.
+// | | | Added ATTR_EFF_DIMM_SPARE.
+// | | | Fixed NUM_RANKS_PER_DIMM for single drop.
+// | | | Fixed calc_timing_in_clk() for negative.
+// | | | Fixed IBM_TYPE and STACK_TYPE.
+// 1.14 | asaetow |08-NOV-12| Changed to match new memory_attributes.xml
+// | | | v1.45 or newer.
+// | | | NOTE: DO NOT pick-up without
+// | | | memory_attributes.xml v1.45 or newer.
+// 1.13 | asaetow |11-OCT-12| Added ATTR_EFF_SCHMOO_ADDR_MODE,
+// | | | ATTR_EFF_SCHMOO_WR_EYE_MIN_MARGIN,
+// | | | ATTR_EFF_SCHMOO_RD_EYE_MIN_MARGIN,
+// | | | ATTR_EFF_SCHMOO_DQS_CLK_MIN_MARGIN,
+// | | | ATTR_EFF_SCHMOO_RD_GATE_MIN_MARGIN,
+// | | | ATTR_EFF_SCHMOO_ADDR_CMD_MIN_MARGIN,
+// | | | ATTR_EFF_DRAM_WR_VREF_SCHMOO,
+// | | | ATTR_EFF_CEN_RD_VREF_SCHMOO,
+// | | | ATTR_EFF_CEN_DRV_IMP_DQ_DQS_SCHMOO,
+// | | | ATTR_EFF_CEN_DRV_IMP_CMD_SCHMOO,
+// | | | ATTR_EFF_CEN_DRV_IMP_CNTL_SCHMOO,
+// | | | ATTR_EFF_CEN_RCV_IMP_DQ_DQS_SCHMOO,
+// | | | ATTR_EFF_CEN_SLEW_RATE_DQ_DQS_SCHMOO,
+// | | | ATTR_EFF_CEN_SLEW_RATE_CMD_SCHMOO,
+// | | | and ATTR_EFF_CEN_SLEW_RATE_CNTL_SCHMOO.
+// 1.12 | asaetow |26-SEP-12| Added initial equation for
+// | | | ATTR_EFF_ZQCAL_INTERVAL and
+// | | | ATTR_EFF_MEMCAL_INTERVAL from Ken.
+// 1.11 | kjpower |26-SEP-12| Restructured code, added modularity
// 1.10 | bellows |02-AUG-12| Added in DIMM functional vector for Daniel
// 1.9 | asaetow |29-MAY-12| Added divide by 0 check for mss_freq.
// | | | Added 9 new attributes from
@@ -93,6 +123,7 @@
//------------------------------------------------------------------------------
#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_config_thermal.H>
@@ -109,6 +140,7 @@ const uint32_t MSS_EFF_VALID = 255;
const uint32_t TWO_MHZ = 2000000;
const uint8_t PORT_SIZE = 2;
const uint8_t DIMM_SIZE = 2;
+const uint8_t RANK_SIZE = 4;
//------------------------------------------------------------------------------
// Structure
@@ -120,6 +152,7 @@ struct mss_eff_config_data
{
uint8_t cur_dimm_spd_valid_u8array[PORT_SIZE][DIMM_SIZE];
uint8_t dimm_functional;
+ uint8_t allow_single_port;
uint8_t cur_dram_density;
uint32_t mss_freq;
uint32_t mtb_in_ps_u32array[PORT_SIZE][DIMM_SIZE];
@@ -211,6 +244,7 @@ struct mss_eff_config_atts
// AST HERE: Needs SPD byte68:76
uint64_t eff_dimm_rcd_cntl_word_0_15[PORT_SIZE][DIMM_SIZE];
uint8_t eff_dimm_size[PORT_SIZE][DIMM_SIZE];
+ uint8_t eff_dimm_spare[PORT_SIZE][DIMM_SIZE][RANK_SIZE];
uint8_t eff_dimm_type;
uint8_t eff_dram_al; // initialized to 1
uint8_t eff_dram_asr;
@@ -248,8 +282,6 @@ struct mss_eff_config_atts
uint8_t eff_dram_width;
uint8_t eff_dram_wr;
uint8_t eff_dram_wr_lvl_enable;
- // AST HERE: Needs SPD byte33[7,1:0], currently hard coded to TYPE_1B
- // initialized to {{2,2},{2,2}}
uint8_t eff_ibm_type[PORT_SIZE][DIMM_SIZE];
uint32_t eff_memcal_interval;
uint8_t eff_mpr_loc;
@@ -262,10 +294,28 @@ struct mss_eff_config_atts
uint8_t eff_num_packages_per_rank[PORT_SIZE][DIMM_SIZE];
uint8_t eff_num_ranks_per_dimm[PORT_SIZE][DIMM_SIZE];
uint8_t eff_schmoo_mode;
+
+ uint8_t eff_schmoo_addr_mode;
+ uint8_t eff_schmoo_wr_eye_min_margin;
+ uint8_t eff_schmoo_rd_eye_min_margin;
+ uint8_t eff_schmoo_dqs_clk_min_margin;
+ uint8_t eff_schmoo_rd_gate_min_margin;
+ uint8_t eff_schmoo_addr_cmd_min_margin;
+ uint32_t eff_cen_rd_vref_schmoo[PORT_SIZE];
+ uint32_t eff_dram_wr_vref_schmoo[PORT_SIZE];
+ 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_cen_drv_imp_cntl_schmoo[PORT_SIZE];
+ uint8_t eff_cen_drv_imp_clk_schmoo[PORT_SIZE];
+ uint8_t eff_cen_drv_imp_spcke_schmoo[PORT_SIZE];
+ uint8_t eff_cen_slew_rate_dq_dqs_schmoo[PORT_SIZE];
+ uint8_t eff_cen_slew_rate_cntl_schmoo[PORT_SIZE];
+ uint8_t eff_cen_slew_rate_addr_schmoo[PORT_SIZE];
+ uint8_t eff_cen_slew_rate_clk_schmoo[PORT_SIZE];
+ uint8_t eff_cen_slew_rate_spcke_schmoo[PORT_SIZE];
+
uint8_t eff_schmoo_param_valid;
uint8_t eff_schmoo_test_valid;
- // AST HERE: Needs SPD byte33[7,1:0], currently hard coded to 1
- // initialized to {{1,1},{1,1}}
uint8_t eff_stack_type[PORT_SIZE][DIMM_SIZE];
uint32_t eff_zqcal_interval;
uint8_t dimm_functional_vector;
@@ -330,7 +380,12 @@ uint32_t calc_timing_in_clk(uint32_t i_mtb_in_ps, uint32_t i_ftb_in_fs,
uint32_t l_tCK_in_ps;
// perform calculations
l_tCK_in_ps = TWO_MHZ/i_mss_freq;
- l_timing = (i_unit * i_mtb_in_ps) + (i_offset * i_ftb_in_fs);
+ if ( i_offset >= 128 ) {
+ i_offset = 256 - i_offset;
+ l_timing = (i_unit * i_mtb_in_ps) - (i_offset * i_ftb_in_fs);
+ } else {
+ l_timing = (i_unit * i_mtb_in_ps) + (i_offset * i_ftb_in_fs);
+ }
// ceiling()
l_timing_in_clk = l_timing / l_tCK_in_ps;
// check l_timing
@@ -339,9 +394,7 @@ uint32_t calc_timing_in_clk(uint32_t i_mtb_in_ps, uint32_t i_ftb_in_fs,
l_timing_in_clk += 1;
}
// DEBUG HERE:
- //FAPI_INF("calc_timing_in_clk: l_timing_in_clk = %d, l_tCK_in_ps = %d,
- // i_mtb_in_ps = %d, i_ftb_in_fs = %d, i_unit = %d, i_offset = %d",
- //l_timing_in_clk, l_tCK_in_ps, i_mtb_in_ps, i_ftb_in_fs, i_unit, i_offset);
+ //FAPI_INF("calc_timing_in_clk: l_timing_in_clk = %d, l_tCK_in_ps = %d, i_mtb_in_ps = %d, i_ftb_in_fs = %d, i_unit = %d, i_offset = %d", l_timing_in_clk, l_tCK_in_ps, i_mtb_in_ps, i_ftb_in_fs, i_unit, i_offset);
return l_timing_in_clk;
} // end calc_timing_in_clk()
@@ -651,7 +704,7 @@ fapi::ReturnCode mss_eff_config_verify_plug_rules(
FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR);
return rc;
}
- if (
+ if ( (
((p_i_mss_eff_config_data->
cur_dimm_spd_valid_u8array[0][0] == MSS_EFF_VALID)
&& (p_i_mss_eff_config_data->
@@ -661,7 +714,20 @@ fapi::ReturnCode mss_eff_config_verify_plug_rules(
cur_dimm_spd_valid_u8array[0][1] == MSS_EFF_VALID)
&& (p_i_mss_eff_config_data->
cur_dimm_spd_valid_u8array[1][1] == MSS_EFF_EMPTY))
- )
+ ) && (p_i_mss_eff_config_data->allow_single_port == fapi::ENUM_ATTR_MSS_ALLOW_SINGLE_PORT_FALSE) )
+ {
+ FAPI_ERR("Plug rule violation on %s!", i_target_mba.toEcmdString());
+ FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR);
+ return rc;
+ }
+ if ( (
+ (p_i_mss_eff_config_data->
+ cur_dimm_spd_valid_u8array[0][1] == MSS_EFF_VALID)
+ || (p_i_mss_eff_config_data->
+ cur_dimm_spd_valid_u8array[1][0] == MSS_EFF_VALID)
+ || (p_i_mss_eff_config_data->
+ cur_dimm_spd_valid_u8array[1][1] == MSS_EFF_VALID)
+ ) && (p_i_mss_eff_config_data->allow_single_port == fapi::ENUM_ATTR_MSS_ALLOW_SINGLE_PORT_TRUE) )
{
FAPI_ERR("Plug rule violation on %s!", i_target_mba.toEcmdString());
FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR);
@@ -979,13 +1045,19 @@ fapi::ReturnCode mss_eff_config_setup_eff_atts(
for(int j = 0; j < DIMM_SIZE; j++)
{
// i <-> PORT_SIZE, j <-> DIMM_SIZE
- // initializes to {{1,1},{1,1}} and {{2,2},{2,2}} respectively
- p_o_atts->eff_stack_type[i][j] = 1;
- p_o_atts->eff_ibm_type[i][j] = 2;
+ p_o_atts->eff_stack_type[i][j] = 0;
+ p_o_atts->eff_ibm_type[i][j] = 0;
}
}
// Assigning values to attributes
+//------------------------------------------------------------------------------
+ p_o_atts->eff_schmoo_wr_eye_min_margin = 70;
+ p_o_atts->eff_schmoo_rd_eye_min_margin = 70;
+ p_o_atts->eff_schmoo_dqs_clk_min_margin = 140;
+ p_o_atts->eff_schmoo_rd_gate_min_margin = 100;
+ p_o_atts->eff_schmoo_addr_cmd_min_margin = 140;
+//------------------------------------------------------------------------------
switch(p_i_data->dram_device_type[0][0])
{
case fapi::ENUM_ATTR_SPD_DRAM_DEVICE_TYPE_DDR3:
@@ -1009,7 +1081,20 @@ fapi::ReturnCode mss_eff_config_setup_eff_atts(
p_o_atts->eff_dimm_type = fapi::ENUM_ATTR_EFF_DIMM_TYPE_RDIMM;
break;
case fapi::ENUM_ATTR_SPD_MODULE_TYPE_UDIMM:
- p_o_atts->eff_dimm_type = fapi::ENUM_ATTR_EFF_DIMM_TYPE_UDIMM;
+ // TODO RTC Task 60572
+ // DIMM SPD Module Type in byte 3 can be 0x82.
+ // 0x80 is CDIMM, 0x02 is unbuffered
+ // Problem 1: Firmware SPD DD only returns the lower 4 bits because
+ // the top 4 bits are reserved in the spec. There needs to be a
+ // new SPD attribute for the top bit that can be queried by this
+ // HWP. HW team to provide updated dimm_spd_attributes.xml. FW
+ // team to support the new attribute.
+ // Problem 2: This HWP and mss_eff_config_termination fail if
+ // eff_dimm_type is not CDIMM or RDIMM. Depending on the fix for
+ // Problem 1, the HWPs need fixing to recognize Unbuffered-CDIMM
+ // The workaround is to treat UDIMM(0x02) as a CDIMM
+ //OLD: p_o_atts->eff_dimm_type = fapi::ENUM_ATTR_EFF_DIMM_TYPE_UDIMM;
+ p_o_atts->eff_dimm_type = fapi::ENUM_ATTR_EFF_DIMM_TYPE_CDIMM;
break;
case fapi::ENUM_ATTR_SPD_MODULE_TYPE_LRDIMM:
p_o_atts->eff_dimm_type = fapi::ENUM_ATTR_EFF_DIMM_TYPE_LRDIMM;
@@ -1123,7 +1208,11 @@ fapi::ReturnCode mss_eff_config_setup_eff_atts(
//------------------------------------------------------------------------------
p_o_atts->eff_dram_density = 16;
- for (int l_cur_mba_port = 0; l_cur_mba_port < PORT_SIZE; l_cur_mba_port += 1)
+ uint8_t allow_port_size = 1;
+ if (p_i_mss_eff_config_data->allow_single_port == fapi::ENUM_ATTR_MSS_ALLOW_SINGLE_PORT_FALSE) {
+ allow_port_size = PORT_SIZE;
+ }
+ for (int l_cur_mba_port = 0; l_cur_mba_port < allow_port_size; l_cur_mba_port += 1)
{
for (int l_cur_mba_dimm = 0; l_cur_mba_dimm <
p_o_atts->eff_num_drops_per_port; l_cur_mba_dimm += 1)
@@ -1155,10 +1244,13 @@ fapi::ReturnCode mss_eff_config_setup_eff_atts(
}
else
{
- FAPI_ERR("Unsupported DRAM density on %s!",
- i_target_mba.toEcmdString());
- FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR);
- return rc;
+ p_i_mss_eff_config_data->cur_dram_density = 1;
+ if (p_i_mss_eff_config_data->allow_single_port == fapi::ENUM_ATTR_MSS_ALLOW_SINGLE_PORT_FALSE) {
+ FAPI_ERR("Unsupported DRAM density on %s!",
+ i_target_mba.toEcmdString());
+ FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR);
+ return rc;
+ }
}
//------------------------------------------------------------------------------
if (p_o_atts->eff_dram_density >
@@ -1415,6 +1507,17 @@ fapi::ReturnCode mss_eff_config_setup_eff_atts(
return rc;
}
//------------------------------------------------------------------------------
+ // Calculate ZQCAL Interval based on the following equation from Ken:
+ // 0.5
+ // ------------------------------ = 13.333ms
+ // (1.5 * 10) + (0.15 * 150)
+ p_o_atts->eff_zqcal_interval = ( 13333 *
+ p_i_mss_eff_config_data->mss_freq) / 2;
+//------------------------------------------------------------------------------
+ // Calculate MEMCAL Interval based on 1sec interval across all bits per DP18
+ p_o_atts->eff_memcal_interval = (62500 *
+ p_i_mss_eff_config_data->mss_freq) / 2;
+//------------------------------------------------------------------------------
// Calculate tRFI
p_o_atts->eff_dram_trfi = (3900 *
p_i_mss_eff_config_data->mss_freq) / 2000;
@@ -1426,6 +1529,9 @@ fapi::ReturnCode mss_eff_config_setup_eff_atts(
for (int l_cur_mba_dimm = 0; l_cur_mba_dimm <
DIMM_SIZE; l_cur_mba_dimm += 1)
{
+ 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]
[l_cur_mba_dimm] == fapi::ENUM_ATTR_SPD_NUM_RANKS_R4)
{
@@ -1456,6 +1562,74 @@ fapi::ReturnCode mss_eff_config_setup_eff_atts(
p_o_atts->eff_dimm_ranks_configed[l_cur_mba_port]
[l_cur_mba_dimm] = 0x00;
}
+ for (int l_cur_mba_rank = 0; l_cur_mba_rank <
+ RANK_SIZE; l_cur_mba_rank += 1)
+ {
+ if (( p_o_atts->eff_dimm_type == fapi::ENUM_ATTR_EFF_DIMM_TYPE_CDIMM)
+ && ( l_cur_mba_rank < p_o_atts->eff_num_ranks_per_dimm[l_cur_mba_port][l_cur_mba_dimm] ))
+ {
+ p_o_atts->
+ eff_dimm_spare[l_cur_mba_port][l_cur_mba_dimm][l_cur_mba_rank]
+ = fapi::ENUM_ATTR_EFF_DIMM_SPARE_FULL_BYTE;
+ } else {
+ p_o_atts->
+ eff_dimm_spare[l_cur_mba_port][l_cur_mba_dimm][l_cur_mba_rank]
+ = fapi::ENUM_ATTR_EFF_DIMM_SPARE_NO_SPARE;
+ }
+ }
+ // AST HERE: Needs SPD byte33[7,1:0], for expanded IBM_TYPE and STACK_TYPE
+ if ( p_o_atts->eff_dimm_type == fapi::ENUM_ATTR_EFF_DIMM_TYPE_RDIMM ) {
+ if (p_o_atts->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;
+ p_o_atts->eff_ibm_type[l_cur_mba_port][l_cur_mba_dimm] = fapi::ENUM_ATTR_EFF_IBM_TYPE_TYPE_1A;
+ } else if (p_o_atts->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;
+ p_o_atts->eff_ibm_type[l_cur_mba_port][l_cur_mba_dimm] = fapi::ENUM_ATTR_EFF_IBM_TYPE_TYPE_1B;
+ } else if (p_o_atts->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;
+ p_o_atts->eff_ibm_type[l_cur_mba_port][l_cur_mba_dimm] = fapi::ENUM_ATTR_EFF_IBM_TYPE_TYPE_1D;
+ } else {
+ p_o_atts->eff_stack_type[l_cur_mba_port][l_cur_mba_dimm] = fapi::ENUM_ATTR_EFF_STACK_TYPE_NONE;
+ 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 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_CDIMM ) {
+ if (p_o_atts->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;
+ p_o_atts->eff_ibm_type[l_cur_mba_port][l_cur_mba_dimm] = fapi::ENUM_ATTR_EFF_IBM_TYPE_TYPE_1A;
+ } else if (p_o_atts->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_DDP_QDP;
+ p_o_atts->eff_ibm_type[l_cur_mba_port][l_cur_mba_dimm] = fapi::ENUM_ATTR_EFF_IBM_TYPE_TYPE_1B;
+ } else {
+ p_o_atts->eff_stack_type[l_cur_mba_port][l_cur_mba_dimm] = fapi::ENUM_ATTR_EFF_STACK_TYPE_NONE;
+ 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 IBM_TYPE on %s!", i_target_mba.toEcmdString());
+ FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR); return rc;
+ }
+ } else {
+ p_o_atts->eff_stack_type[l_cur_mba_port][l_cur_mba_dimm] = fapi::ENUM_ATTR_EFF_STACK_TYPE_NONE;
+ 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());
+ FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR); return rc;
+ }
+ } else {
+ p_o_atts->eff_num_ranks_per_dimm[l_cur_mba_port]
+ [l_cur_mba_dimm] = 0;
+ p_o_atts->eff_dimm_ranks_configed[l_cur_mba_port]
+ [l_cur_mba_dimm] = 0x00;
+ for (int l_cur_mba_rank = 0; l_cur_mba_rank <
+ RANK_SIZE; l_cur_mba_rank += 1)
+ {
+ p_o_atts->
+ eff_dimm_spare[l_cur_mba_port][l_cur_mba_dimm][l_cur_mba_rank]
+ = fapi::ENUM_ATTR_EFF_DIMM_SPARE_NO_SPARE;
+ }
+ p_o_atts->eff_stack_type[l_cur_mba_port][l_cur_mba_dimm] = fapi::ENUM_ATTR_EFF_STACK_TYPE_NONE;
+ p_o_atts->eff_ibm_type[l_cur_mba_port][l_cur_mba_dimm] = fapi::ENUM_ATTR_EFF_IBM_TYPE_UNDEFINED;
+ }
+//------------------------------------------------------------------------------
+
//------------------------------------------------------------------------------
if (p_o_atts->eff_num_ranks_per_dimm[l_cur_mba_port]
[l_cur_mba_dimm] != 0)
@@ -1552,7 +1726,11 @@ fapi::ReturnCode mss_eff_config_write_eff_atts(
p_i_atts->eff_dimm_rcd_cntl_word_0_15);
if(rc) break;
rc = FAPI_ATTR_SET(ATTR_EFF_DIMM_SIZE, &i_target_mba,
- p_i_atts->eff_dimm_size); if(rc) break;
+ p_i_atts->eff_dimm_size);
+ if(rc) break;
+ rc = FAPI_ATTR_SET(ATTR_EFF_DIMM_SPARE, &i_target_mba,
+ p_i_atts->eff_dimm_spare);
+ if(rc) break;
rc = FAPI_ATTR_SET(ATTR_EFF_DIMM_TYPE, &i_target_mba,
p_i_atts->eff_dimm_type);
if(rc) break;
@@ -1683,12 +1861,70 @@ fapi::ReturnCode mss_eff_config_write_eff_atts(
rc = FAPI_ATTR_SET(ATTR_EFF_SCHMOO_MODE, &i_target_mba,
p_i_atts->eff_schmoo_mode);
if(rc) break;
+ rc = FAPI_ATTR_SET(ATTR_EFF_SCHMOO_ADDR_MODE, &i_target_mba,
+ p_i_atts->eff_schmoo_addr_mode);
+ if(rc) break;
rc = FAPI_ATTR_SET(ATTR_EFF_SCHMOO_PARAM_VALID, &i_target_mba,
p_i_atts->eff_schmoo_param_valid);
if(rc) break;
rc = FAPI_ATTR_SET(ATTR_EFF_SCHMOO_TEST_VALID, &i_target_mba,
p_i_atts->eff_schmoo_test_valid);
if(rc) break;
+ rc = FAPI_ATTR_SET(ATTR_EFF_SCHMOO_WR_EYE_MIN_MARGIN, &i_target_mba,
+ p_i_atts->eff_schmoo_wr_eye_min_margin);
+ if(rc) break;
+ rc = FAPI_ATTR_SET(ATTR_EFF_SCHMOO_RD_EYE_MIN_MARGIN, &i_target_mba,
+ p_i_atts->eff_schmoo_rd_eye_min_margin);
+ if(rc) break;
+ rc = FAPI_ATTR_SET(ATTR_EFF_SCHMOO_DQS_CLK_MIN_MARGIN, &i_target_mba,
+ p_i_atts->eff_schmoo_dqs_clk_min_margin);
+ if(rc) break;
+ rc = FAPI_ATTR_SET(ATTR_EFF_SCHMOO_RD_GATE_MIN_MARGIN, &i_target_mba,
+ p_i_atts->eff_schmoo_rd_gate_min_margin);
+ if(rc) break;
+ rc = FAPI_ATTR_SET(ATTR_EFF_SCHMOO_ADDR_CMD_MIN_MARGIN, &i_target_mba,
+ p_i_atts->eff_schmoo_addr_cmd_min_margin);
+ if(rc) break;
+
+ rc = FAPI_ATTR_SET(ATTR_EFF_CEN_RD_VREF_SCHMOO, &i_target_mba,
+ p_i_atts->eff_cen_rd_vref_schmoo);
+ if(rc) break;
+ rc = FAPI_ATTR_SET(ATTR_EFF_DRAM_WR_VREF_SCHMOO, &i_target_mba,
+ p_i_atts->eff_dram_wr_vref_schmoo);
+ if(rc) break;
+
+ rc = FAPI_ATTR_SET(ATTR_EFF_CEN_RCV_IMP_DQ_DQS_SCHMOO, &i_target_mba,
+ p_i_atts->eff_cen_rcv_imp_dq_dqs_schmoo);
+ if(rc) break;
+ rc = FAPI_ATTR_SET(ATTR_EFF_CEN_DRV_IMP_DQ_DQS_SCHMOO, &i_target_mba,
+ p_i_atts->eff_cen_drv_imp_dq_dqs_schmoo);
+ if(rc) break;
+ rc = FAPI_ATTR_SET(ATTR_EFF_CEN_DRV_IMP_CNTL_SCHMOO, &i_target_mba,
+ p_i_atts->eff_cen_drv_imp_cntl_schmoo);
+ if(rc) break;
+ rc = FAPI_ATTR_SET(ATTR_EFF_CEN_DRV_IMP_CLK_SCHMOO, &i_target_mba,
+ p_i_atts->eff_cen_drv_imp_clk_schmoo);
+ if(rc) break;
+ rc = FAPI_ATTR_SET(ATTR_EFF_CEN_DRV_IMP_SPCKE_SCHMOO, &i_target_mba,
+ p_i_atts->eff_cen_drv_imp_spcke_schmoo);
+ if(rc) break;
+
+ rc = FAPI_ATTR_SET(ATTR_EFF_CEN_SLEW_RATE_DQ_DQS_SCHMOO, &i_target_mba,
+ p_i_atts->eff_cen_slew_rate_dq_dqs_schmoo);
+ if(rc) break;
+ rc = FAPI_ATTR_SET(ATTR_EFF_CEN_SLEW_RATE_CNTL_SCHMOO, &i_target_mba,
+ p_i_atts->eff_cen_slew_rate_cntl_schmoo);
+ if(rc) break;
+ rc = FAPI_ATTR_SET(ATTR_EFF_CEN_SLEW_RATE_ADDR_SCHMOO, &i_target_mba,
+ p_i_atts->eff_cen_slew_rate_addr_schmoo);
+ if(rc) break;
+ rc = FAPI_ATTR_SET(ATTR_EFF_CEN_SLEW_RATE_CLK_SCHMOO, &i_target_mba,
+ p_i_atts->eff_cen_slew_rate_clk_schmoo);
+ if(rc) break;
+ rc = FAPI_ATTR_SET(ATTR_EFF_CEN_SLEW_RATE_SPCKE_SCHMOO, &i_target_mba,
+ p_i_atts->eff_cen_slew_rate_spcke_schmoo);
+ if(rc) break;
+
rc = FAPI_ATTR_SET(ATTR_EFF_STACK_TYPE, &i_target_mba,
p_i_atts->eff_stack_type);
if(rc) break;
@@ -1737,6 +1973,13 @@ fapi::ReturnCode mss_eff_config(const fapi::Target i_target_mba)
do
{
//------------------------------------------------------------------------------
+ // Grab allow single port data
+ rc = FAPI_ATTR_GET(ATTR_MSS_ALLOW_SINGLE_PORT, &i_target_mba, p_l_mss_eff_config_data->allow_single_port);
+ if(rc) break;
+ if ( p_l_mss_eff_config_data->allow_single_port == fapi::ENUM_ATTR_MSS_ALLOW_SINGLE_PORT_TRUE ) {
+ FAPI_INF("WARNING: allow_single_port = %d on %s.", p_l_mss_eff_config_data->allow_single_port, i_target_mba.toEcmdString());
+ }
+//------------------------------------------------------------------------------
// Grab freq/volt data
rc = fapiGetParentChip(i_target_mba, l_target_centaur);
if(rc) break;
@@ -1783,8 +2026,9 @@ fapi::ReturnCode mss_eff_config(const fapi::Target i_target_mba)
}
// verify SPD data
- if( p_l_atts->eff_num_drops_per_port
+ if(( p_l_atts->eff_num_drops_per_port
!= fapi::ENUM_ATTR_EFF_NUM_DROPS_PER_PORT_EMPTY )
+ && ( p_l_mss_eff_config_data->allow_single_port == fapi::ENUM_ATTR_MSS_ALLOW_SINGLE_PORT_FALSE ))
{
rc = mss_eff_config_verify_spd_data( i_target_mba,
p_l_atts, p_l_spd_data );
@@ -1818,6 +2062,7 @@ fapi::ReturnCode mss_eff_config(const fapi::Target i_target_mba)
// 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;
rc = mss_eff_config_termination(i_target_mba); if(rc) break;
rc = mss_eff_config_thermal(i_target_mba); if(rc) break;
diff --git a/src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_eff_config_cke_map.C b/src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_eff_config_cke_map.C
new file mode 100644
index 000000000..6d250915a
--- /dev/null
+++ b/src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_eff_config_cke_map.C
@@ -0,0 +1,335 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_eff_config_cke_map.C $ */
+/* */
+/* IBM CONFIDENTIAL */
+/* */
+/* COPYRIGHT International Business Machines Corp. 2012 */
+/* */
+/* p1 */
+/* */
+/* Object Code Only (OCO) source materials */
+/* Licensed Internal Code Source Materials */
+/* IBM HostBoot Licensed Internal Code */
+/* */
+/* The source code for this program is not published or otherwise */
+/* divested of its trade secrets, irrespective of what has been */
+/* deposited with the U.S. Copyright Office. */
+/* */
+/* Origin: 30 */
+/* */
+/* IBM_PROLOG_END_TAG */
+// $Id: mss_eff_config_cke_map.C,v 1.3 2012/11/16 14:39:15 asaetow Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/centaur/working/procedures/ipl/fapi/mss_eff_config_cke_map.C,v $
+//------------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2011
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//------------------------------------------------------------------------------
+// *! TITLE : mss_eff_config_cke_map
+// *! DESCRIPTION : see additional comments below
+// *! OWNER NAME : Anuwat Saetow Email: asaetow@us.ibm.com
+// *! BACKUP NAME : Mark Bellows Email: bellows@us.ibm.com
+// *! ADDITIONAL COMMENTS :
+//
+// This procedure takes in attributes and determines proper cke map.
+//
+//------------------------------------------------------------------------------
+// Don't forget to create CVS comments when you check in your changes!
+//------------------------------------------------------------------------------
+// CHANGE HISTORY:
+//------------------------------------------------------------------------------
+// Version:| Author: | Date: | Comment:
+//---------|----------|---------|-----------------------------------------------
+// 1.4 | | |
+// 1.3 | asaetow |14-NOV-12| Added ATTR_EFF_SPCKE_MAP.
+// 1.2 | asaetow |13-NOV-12| Added FAPI_ERR for else "Undefined IBM_TYPE".
+// | | | Removed outter NUM_DROPS_PER_PORT check.
+// 1.1 | asaetow |07-NOV-12| First Draft.
+
+
+
+//----------------------------------------------------------------------
+// My Includes
+//----------------------------------------------------------------------
+
+
+
+//----------------------------------------------------------------------
+// Includes
+//----------------------------------------------------------------------
+#include <fapi.H>
+
+
+
+extern "C" {
+
+
+
+//----------------------------------------------------------------------
+// ENUMs and CONSTs
+//----------------------------------------------------------------------
+
+// Define attribute array size
+const uint8_t PORT_SIZE = 2;
+const uint8_t DIMM_SIZE = 2;
+const uint8_t RANK_SIZE = 4;
+const uint8_t IBM_TYPE_SIZE = 27;
+
+const uint8_t l_cke_map_u8array[IBM_TYPE_SIZE][DIMM_SIZE][RANK_SIZE] = {
+ // UNDEFINED = 0, TYPE_1A = 1, TYPE_1B = 2, TYPE_1C = 3, TYPE_1D = 4, TYPE_2A = 5, TYPE_2B = 6, TYPE_2C = 7, TYPE_3A = 8, TYPE_3B = 9, TYPE_3C = 10, TYPE_4A = 11, TYPE_4B = 12, TYPE_4C = 13, TYPE_5A = 14, TYPE_5B = 15, TYPE_5C = 16, TYPE_5D = 17, TYPE_6A = 18, TYPE_6B = 19, TYPE_6C = 20, TYPE_7A = 21, TYPE_7B = 22, TYPE_7C = 23, TYPE_8A = 24, TYPE_8B = 25, TYPE_8C = 26
+ // DIMM0 , DIMM1
+ // 0 1 2 3 , 0 1 2 3
+ {{0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x00, 0x00}}, // UNDEFINED
+ {{0x80, 0x00, 0x00, 0x00}, {0x08, 0x00, 0x00, 0x00}}, // TYPE_1A
+ {{0x80, 0x40, 0x00, 0x00}, {0x08, 0x04, 0x00, 0x00}}, // TYPE_1B
+ {{0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x00, 0x00}}, // TYPE_1C <-- UNDEFINED
+ {{0x80, 0x40, 0x80, 0x40}, {0x08, 0x04, 0x08, 0x04}}, // TYPE_1D
+ {{0x80, 0x00, 0x00, 0x00}, {0x08, 0x00, 0x00, 0x00}}, // TYPE_2A
+ {{0x80, 0x00, 0x00, 0x00}, {0x08, 0x00, 0x00, 0x00}}, // TYPE_2B
+ {{0x80, 0x00, 0x00, 0x00}, {0x08, 0x00, 0x00, 0x00}}, // TYPE_2C
+ {{0x80, 0x40, 0x00, 0x00}, {0x08, 0x04, 0x00, 0x00}}, // TYPE_3A
+ {{0x80, 0x40, 0x00, 0x00}, {0x08, 0x04, 0x00, 0x00}}, // TYPE_3B
+ {{0x80, 0x40, 0x00, 0x00}, {0x08, 0x04, 0x00, 0x00}}, // TYPE_3C
+ {{0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x00, 0x00}}, // TYPE_4A <-- UNDEFINED
+ {{0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x00, 0x00}}, // TYPE_4B <-- UNDEFINED
+ {{0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x00, 0x00}}, // TYPE_4C <-- UNDEFINED
+ {{0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x00, 0x00}}, // TYPE_5A <-- UNDEFINED
+ {{0x80, 0x40, 0x00, 0x00}, {0x08, 0x04, 0x00, 0x00}}, // TYPE_5B
+ {{0x80, 0x40, 0x80, 0x40}, {0x08, 0x04, 0x08, 0x04}}, // TYPE_5C
+ {{0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x00, 0x00}}, // TYPE_5D <-- NOT YET SUPPORTED for LRDIMM DDR3
+ {{0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x00, 0x00}}, // TYPE_6A <-- UNDEFINED
+ {{0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x00, 0x00}}, // TYPE_6B <-- UNDEFINED
+ {{0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x00, 0x00}}, // TYPE_6C <-- UNDEFINED
+ {{0x80, 0x40, 0x00, 0x00}, {0x08, 0x04, 0x00, 0x00}}, // TYPE_7A
+ {{0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x00, 0x00}}, // TYPE_7B <-- NOT YET SUPPORTED for LRDIMM DDR3
+ {{0x80, 0x40, 0x00, 0x00}, {0x08, 0x04, 0x00, 0x00}}, // TYPE_7C
+ {{0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x00, 0x00}}, // TYPE_8A <-- UNDEFINED
+ {{0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x00, 0x00}}, // TYPE_8B <-- UNDEFINED
+ {{0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x00, 0x00}}}; // TYPE_8C <-- UNDEFINED
+
+const uint8_t l_spcke_map_u8array[IBM_TYPE_SIZE][DIMM_SIZE][RANK_SIZE] = {
+ // DIMM0 , DIMM1
+ // 0 1 2 3 , 0 1 2 3
+ {{0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x00, 0x00}}, // UNDEFINED
+ {{0x20, 0x00, 0x00, 0x00}, {0x02, 0x00, 0x00, 0x00}}, // TYPE_1A
+ {{0x20, 0x10, 0x00, 0x00}, {0x02, 0x01, 0x00, 0x00}}, // TYPE_1B
+ {{0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x00, 0x00}}, // TYPE_1C <-- UNDEFINED
+ {{0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x00, 0x00}}, // TYPE_1D <-- NOT SUPPORTED for CDIMM
+ {{0x20, 0x00, 0x00, 0x00}, {0x02, 0x00, 0x00, 0x00}}, // TYPE_2A
+ {{0x20, 0x00, 0x00, 0x00}, {0x02, 0x00, 0x00, 0x00}}, // TYPE_2B
+ {{0x20, 0x00, 0x00, 0x00}, {0x02, 0x00, 0x00, 0x00}}, // TYPE_2C
+ {{0x20, 0x10, 0x00, 0x00}, {0x02, 0x01, 0x00, 0x00}}, // TYPE_3A
+ {{0x20, 0x10, 0x00, 0x00}, {0x02, 0x01, 0x00, 0x00}}, // TYPE_3B
+ {{0x20, 0x10, 0x00, 0x00}, {0x02, 0x01, 0x00, 0x00}}, // TYPE_3C
+ {{0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x00, 0x00}}, // TYPE_4A <-- UNDEFINED
+ {{0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x00, 0x00}}, // TYPE_4B <-- UNDEFINED
+ {{0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x00, 0x00}}, // TYPE_4C <-- UNDEFINED
+ {{0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x00, 0x00}}, // TYPE_5A <-- UNDEFINED
+ {{0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x00, 0x00}}, // TYPE_5B <-- NOT SUPPORTED for CDIMM
+ {{0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x00, 0x00}}, // TYPE_5C <-- NOT SUPPORTED for CDIMM
+ {{0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x00, 0x00}}, // TYPE_5D <-- NOT SUPPORTED for CDIMM, NOT YET SUPPORTED for LRDIMM DDR3
+ {{0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x00, 0x00}}, // TYPE_6A <-- UNDEFINED
+ {{0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x00, 0x00}}, // TYPE_6B <-- UNDEFINED
+ {{0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x00, 0x00}}, // TYPE_6C <-- UNDEFINED
+ {{0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x00, 0x00}}, // TYPE_7A <-- NOT SUPPORTED for CDIMM
+ {{0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x00, 0x00}}, // TYPE_7B <-- NOT SUPPORTED for CDIMM, NOT YET SUPPORTED for LRDIMM DDR3
+ {{0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x00, 0x00}}, // TYPE_7C <-- NOT SUPPORTED for CDIMM
+ {{0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x00, 0x00}}, // TYPE_8A <-- UNDEFINED
+ {{0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x00, 0x00}}, // TYPE_8B <-- UNDEFINED
+ {{0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x00, 0x00}}}; // TYPE_8C <-- UNDEFINED
+
+
+
+//******************************************************************************
+//* name=mss_eff_config_cke_map, param=i_target_mba, return=ReturnCode
+//******************************************************************************
+fapi::ReturnCode mss_eff_config_cke_map(const fapi::Target i_target_mba) {
+ fapi::ReturnCode rc = fapi::FAPI_RC_SUCCESS;
+ const char * const PROCEDURE_NAME = "mss_eff_config_cke_map";
+ FAPI_INF("*** Running %s on %s ... ***", PROCEDURE_NAME, i_target_mba.toEcmdString());
+
+
+ // Define attribute array size
+
+
+ // Fetch dependent attributes
+ uint8_t l_num_ranks_per_dimm_u8array[PORT_SIZE][DIMM_SIZE];
+ // ATTR_EFF_DRAM_GEN: EMPTY = 0, DDR3 = 1, DDR4 = 2,
+ uint8_t l_dram_gen_u8;
+ // ATTR_EFF_DIMM_TYPE: CDIMM = 0, RDIMM = 1, UDIMM = 2, LRDIMM = 3,
+ uint8_t l_dimm_type_u8;
+ uint8_t l_num_drops_per_port_u8;
+ uint8_t l_ibm_type_u8array[PORT_SIZE][DIMM_SIZE];
+ 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_GEN, &i_target_mba, l_dram_gen_u8); if(rc) return rc;
+ rc = FAPI_ATTR_GET(ATTR_EFF_DIMM_TYPE, &i_target_mba, l_dimm_type_u8); if(rc) return rc;
+ rc = FAPI_ATTR_GET(ATTR_EFF_NUM_DROPS_PER_PORT, &i_target_mba, l_num_drops_per_port_u8); if(rc) return rc;
+ rc = FAPI_ATTR_GET(ATTR_EFF_IBM_TYPE, &i_target_mba, l_ibm_type_u8array); if(rc) return rc;
+
+
+ // Define local attribute variables
+ uint8_t l_attr_eff_cke_map[PORT_SIZE][DIMM_SIZE][RANK_SIZE];
+ uint8_t l_attr_eff_spcke_map[PORT_SIZE][DIMM_SIZE][RANK_SIZE];
+
+
+ for (uint8_t l_cur_port = 0; l_cur_port < PORT_SIZE; l_cur_port += 1) {
+ for (uint8_t l_cur_dimm = 0; l_cur_dimm < DIMM_SIZE; l_cur_dimm += 1) {
+ uint8_t l_ibm_type_index = 0;
+ // UNDEFINED = 0, TYPE_1A = 1, TYPE_1B = 2, TYPE_1C = 3, TYPE_1D = 4, TYPE_2A = 5, TYPE_2B = 6, TYPE_2C = 7, TYPE_3A = 8, TYPE_3B = 9, TYPE_3C = 10, TYPE_4A = 11, TYPE_4B = 12, TYPE_4C = 13, TYPE_5A = 14, TYPE_5B = 15, TYPE_5C = 16, TYPE_5D = 17, TYPE_6A = 18, TYPE_6B = 19, TYPE_6C = 20, TYPE_7A = 21, TYPE_7B = 22, TYPE_7C = 23, TYPE_8A = 24, TYPE_8B = 25, TYPE_8C = 26
+ if ( l_ibm_type_u8array[l_cur_port][l_cur_dimm] == fapi::ENUM_ATTR_EFF_IBM_TYPE_UNDEFINED ) {
+ l_ibm_type_index = 0;
+ } else if ( l_ibm_type_u8array[l_cur_port][l_cur_dimm] == fapi::ENUM_ATTR_EFF_IBM_TYPE_TYPE_1A ) {
+ l_ibm_type_index = 1;
+ } else if ( l_ibm_type_u8array[l_cur_port][l_cur_dimm] == fapi::ENUM_ATTR_EFF_IBM_TYPE_TYPE_1B ) {
+ l_ibm_type_index = 2;
+ } else if ( l_ibm_type_u8array[l_cur_port][l_cur_dimm] == fapi::ENUM_ATTR_EFF_IBM_TYPE_TYPE_1C ) {
+ l_ibm_type_index = 3;
+ FAPI_ERR("Undefined IBM_TYPE on %s!", i_target_mba.toEcmdString());
+ FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR); return rc;
+ } else if ( l_ibm_type_u8array[l_cur_port][l_cur_dimm] == fapi::ENUM_ATTR_EFF_IBM_TYPE_TYPE_1D ) {
+ l_ibm_type_index = 4;
+ if ( l_dimm_type_u8 == fapi::ENUM_ATTR_EFF_DIMM_TYPE_CDIMM ) {
+ FAPI_ERR("Invalid IBM_TYPE for CDIMM on %s!", i_target_mba.toEcmdString());
+ FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR); return rc;
+ }
+ } else if ( l_ibm_type_u8array[l_cur_port][l_cur_dimm] == fapi::ENUM_ATTR_EFF_IBM_TYPE_TYPE_2A ) {
+ l_ibm_type_index = 5;
+ } else if ( l_ibm_type_u8array[l_cur_port][l_cur_dimm] == fapi::ENUM_ATTR_EFF_IBM_TYPE_TYPE_2B ) {
+ l_ibm_type_index = 6;
+ } else if ( l_ibm_type_u8array[l_cur_port][l_cur_dimm] == fapi::ENUM_ATTR_EFF_IBM_TYPE_TYPE_2C ) {
+ l_ibm_type_index = 7;
+ } else if ( l_ibm_type_u8array[l_cur_port][l_cur_dimm] == fapi::ENUM_ATTR_EFF_IBM_TYPE_TYPE_3A ) {
+ l_ibm_type_index = 8;
+ } else if ( l_ibm_type_u8array[l_cur_port][l_cur_dimm] == fapi::ENUM_ATTR_EFF_IBM_TYPE_TYPE_3B ) {
+ l_ibm_type_index = 9;
+ } else if ( l_ibm_type_u8array[l_cur_port][l_cur_dimm] == fapi::ENUM_ATTR_EFF_IBM_TYPE_TYPE_3C ) {
+ l_ibm_type_index = 10;
+ } else if ( l_ibm_type_u8array[l_cur_port][l_cur_dimm] == fapi::ENUM_ATTR_EFF_IBM_TYPE_TYPE_4A ) {
+ l_ibm_type_index = 11;
+ FAPI_ERR("Undefined IBM_TYPE on %s!", i_target_mba.toEcmdString());
+ FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR); return rc;
+ } else if ( l_ibm_type_u8array[l_cur_port][l_cur_dimm] == fapi::ENUM_ATTR_EFF_IBM_TYPE_TYPE_4B ) {
+ l_ibm_type_index = 12;
+ FAPI_ERR("Undefined IBM_TYPE on %s!", i_target_mba.toEcmdString());
+ FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR); return rc;
+ } else if ( l_ibm_type_u8array[l_cur_port][l_cur_dimm] == fapi::ENUM_ATTR_EFF_IBM_TYPE_TYPE_4C ) {
+ l_ibm_type_index = 13;
+ FAPI_ERR("Undefined IBM_TYPE on %s!", i_target_mba.toEcmdString());
+ FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR); return rc;
+ } else if ( l_ibm_type_u8array[l_cur_port][l_cur_dimm] == fapi::ENUM_ATTR_EFF_IBM_TYPE_TYPE_5A ) {
+ l_ibm_type_index = 14;
+ FAPI_ERR("Undefined IBM_TYPE on %s!", i_target_mba.toEcmdString());
+ FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR); return rc;
+ } else if ( l_ibm_type_u8array[l_cur_port][l_cur_dimm] == fapi::ENUM_ATTR_EFF_IBM_TYPE_TYPE_5B ) {
+ l_ibm_type_index = 15;
+ if ( l_dimm_type_u8 == fapi::ENUM_ATTR_EFF_DIMM_TYPE_CDIMM ) {
+ FAPI_ERR("Invalid IBM_TYPE for CDIMM on %s!", i_target_mba.toEcmdString());
+ FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR); return rc;
+ }
+ } else if ( l_ibm_type_u8array[l_cur_port][l_cur_dimm] == fapi::ENUM_ATTR_EFF_IBM_TYPE_TYPE_5C ) {
+ l_ibm_type_index = 16;
+ if ( l_dimm_type_u8 == fapi::ENUM_ATTR_EFF_DIMM_TYPE_CDIMM ) {
+ FAPI_ERR("Invalid IBM_TYPE for CDIMM on %s!", i_target_mba.toEcmdString());
+ FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR); return rc;
+ }
+ } else if ( l_ibm_type_u8array[l_cur_port][l_cur_dimm] == fapi::ENUM_ATTR_EFF_IBM_TYPE_TYPE_5D ) {
+ l_ibm_type_index = 17;
+ if ( l_dimm_type_u8 == fapi::ENUM_ATTR_EFF_DIMM_TYPE_CDIMM ) {
+ FAPI_ERR("Invalid IBM_TYPE for CDIMM on %s!", i_target_mba.toEcmdString());
+ FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR); return rc;
+ }
+ 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 ( l_ibm_type_u8array[l_cur_port][l_cur_dimm] == fapi::ENUM_ATTR_EFF_IBM_TYPE_TYPE_6A ) {
+ l_ibm_type_index = 18;
+ FAPI_ERR("Undefined IBM_TYPE on %s!", i_target_mba.toEcmdString());
+ FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR); return rc;
+ } else if ( l_ibm_type_u8array[l_cur_port][l_cur_dimm] == fapi::ENUM_ATTR_EFF_IBM_TYPE_TYPE_6B ) {
+ l_ibm_type_index = 19;
+ FAPI_ERR("Undefined IBM_TYPE on %s!", i_target_mba.toEcmdString());
+ FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR); return rc;
+ } else if ( l_ibm_type_u8array[l_cur_port][l_cur_dimm] == fapi::ENUM_ATTR_EFF_IBM_TYPE_TYPE_6C ) {
+ l_ibm_type_index = 20;
+ FAPI_ERR("Undefined IBM_TYPE on %s!", i_target_mba.toEcmdString());
+ FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR); return rc;
+ } else if ( l_ibm_type_u8array[l_cur_port][l_cur_dimm] == fapi::ENUM_ATTR_EFF_IBM_TYPE_TYPE_7A ) {
+ l_ibm_type_index = 21;
+ if ( l_dimm_type_u8 == fapi::ENUM_ATTR_EFF_DIMM_TYPE_CDIMM ) {
+ FAPI_ERR("Invalid IBM_TYPE for CDIMM on %s!", i_target_mba.toEcmdString());
+ FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR); return rc;
+ }
+ } else if ( l_ibm_type_u8array[l_cur_port][l_cur_dimm] == fapi::ENUM_ATTR_EFF_IBM_TYPE_TYPE_7B ) {
+ l_ibm_type_index = 22;
+ if ( l_dimm_type_u8 == fapi::ENUM_ATTR_EFF_DIMM_TYPE_CDIMM ) {
+ FAPI_ERR("Invalid IBM_TYPE for CDIMM on %s!", i_target_mba.toEcmdString());
+ FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR); return rc;
+ }
+ 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 ( l_ibm_type_u8array[l_cur_port][l_cur_dimm] == fapi::ENUM_ATTR_EFF_IBM_TYPE_TYPE_7C ) {
+ l_ibm_type_index = 23;
+ if ( l_dimm_type_u8 == fapi::ENUM_ATTR_EFF_DIMM_TYPE_CDIMM ) {
+ FAPI_ERR("Invalid IBM_TYPE for CDIMM on %s!", i_target_mba.toEcmdString());
+ FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR); return rc;
+ }
+ } else if ( l_ibm_type_u8array[l_cur_port][l_cur_dimm] == fapi::ENUM_ATTR_EFF_IBM_TYPE_TYPE_8A ) {
+ l_ibm_type_index = 24;
+ FAPI_ERR("Undefined IBM_TYPE on %s!", i_target_mba.toEcmdString());
+ FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR); return rc;
+ } else if ( l_ibm_type_u8array[l_cur_port][l_cur_dimm] == fapi::ENUM_ATTR_EFF_IBM_TYPE_TYPE_8B ) {
+ l_ibm_type_index = 25;
+ FAPI_ERR("Undefined IBM_TYPE on %s!", i_target_mba.toEcmdString());
+ FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR); return rc;
+ } else if ( l_ibm_type_u8array[l_cur_port][l_cur_dimm] == fapi::ENUM_ATTR_EFF_IBM_TYPE_TYPE_8C ) {
+ l_ibm_type_index = 26;
+ FAPI_ERR("Undefined IBM_TYPE on %s!", i_target_mba.toEcmdString());
+ FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR); return rc;
+ } else {
+ l_ibm_type_index = 0;
+ FAPI_ERR("Undefined IBM_TYPE on %s!", i_target_mba.toEcmdString());
+ FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR); return rc;
+ }
+
+ for (uint8_t l_cur_rank = 0; l_cur_rank < RANK_SIZE; l_cur_rank += 1) {
+ if ( l_num_drops_per_port_u8 == fapi::ENUM_ATTR_EFF_NUM_DROPS_PER_PORT_SINGLE ) {
+ if ( l_cur_dimm == 0 ) {
+ l_attr_eff_cke_map[l_cur_port][l_cur_dimm][l_cur_rank] = l_cke_map_u8array[l_ibm_type_index][l_cur_dimm][l_cur_rank];
+ if ( l_dimm_type_u8 == fapi::ENUM_ATTR_EFF_DIMM_TYPE_CDIMM ) {
+ l_attr_eff_spcke_map[l_cur_port][l_cur_dimm][l_cur_rank] = l_spcke_map_u8array[l_ibm_type_index][l_cur_dimm][l_cur_rank];
+ FAPI_INF("WARNING: NUM_DROPS_PER_PORT = SINGLE for a CDIMM on %s!", i_target_mba.toEcmdString());
+ } else {
+ l_attr_eff_spcke_map[l_cur_port][l_cur_dimm][l_cur_rank] = 0;
+ }
+ } else {
+ l_attr_eff_cke_map[l_cur_port][l_cur_dimm][l_cur_rank] = 0;
+ l_attr_eff_spcke_map[l_cur_port][l_cur_dimm][l_cur_rank] = 0;
+ }
+ } else if ( l_num_drops_per_port_u8 == fapi::ENUM_ATTR_EFF_NUM_DROPS_PER_PORT_DUAL ) {
+ l_attr_eff_cke_map[l_cur_port][l_cur_dimm][l_cur_rank] = l_cke_map_u8array[l_ibm_type_index][l_cur_dimm][l_cur_rank];
+ if ( l_dimm_type_u8 == fapi::ENUM_ATTR_EFF_DIMM_TYPE_CDIMM ) {
+ l_attr_eff_spcke_map[l_cur_port][l_cur_dimm][l_cur_rank] = l_spcke_map_u8array[l_ibm_type_index][l_cur_dimm][l_cur_rank];
+ } else {
+ l_attr_eff_spcke_map[l_cur_port][l_cur_dimm][l_cur_rank] = 0;
+ }
+ } else {
+ l_attr_eff_cke_map[l_cur_port][l_cur_dimm][l_cur_rank] = 0;
+ l_attr_eff_spcke_map[l_cur_port][l_cur_dimm][l_cur_rank] = 0;
+ }
+ }
+ }
+ }
+
+
+ // Set attributes
+ rc = FAPI_ATTR_SET(ATTR_EFF_CKE_MAP, &i_target_mba, l_attr_eff_cke_map); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_SPCKE_MAP, &i_target_mba, l_attr_eff_spcke_map); if(rc) return rc;
+
+ FAPI_INF("%s on %s COMPLETE", PROCEDURE_NAME, i_target_mba.toEcmdString());
+ return rc;
+}
+
+
+
+} // extern "C"
diff --git a/src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_eff_config_cke_map.H b/src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_eff_config_cke_map.H
new file mode 100755
index 000000000..6656efad5
--- /dev/null
+++ b/src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_eff_config_cke_map.H
@@ -0,0 +1,74 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_eff_config_cke_map.H $ */
+/* */
+/* IBM CONFIDENTIAL */
+/* */
+/* COPYRIGHT International Business Machines Corp. 2012 */
+/* */
+/* p1 */
+/* */
+/* Object Code Only (OCO) source materials */
+/* Licensed Internal Code Source Materials */
+/* IBM HostBoot Licensed Internal Code */
+/* */
+/* The source code for this program is not published or otherwise */
+/* divested of its trade secrets, irrespective of what has been */
+/* deposited with the U.S. Copyright Office. */
+/* */
+/* Origin: 30 */
+/* */
+/* IBM_PROLOG_END_TAG */
+// $Id: mss_eff_config_cke_map.H,v 1.1 2012/11/14 01:28:48 asaetow Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/centaur/working/procedures/ipl/fapi/mss_eff_config_cke_map.H,v $
+//------------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2011
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//------------------------------------------------------------------------------
+// *! TITLE : mss_eff_config_cke_map.H
+// *! DESCRIPTION : Header file for mss_eff_config_cke_map.
+// *! OWNER NAME : Anuwat Saetow Email: asaetow@us.ibm.com
+// *! BACKUP NAME : Mark Bellows Email: bellows@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 |13-NOV-12| First Draft.
+
+
+#ifndef MSS_EFF_CONFIG_CKE_MAP_H_
+#define MSS_EFF_CONFIG_CKE_MAP_H_
+
+//----------------------------------------------------------------------
+// My Includes
+//----------------------------------------------------------------------
+
+
+//----------------------------------------------------------------------
+// Includes
+//----------------------------------------------------------------------
+#include <fapi.H>
+
+
+typedef fapi::ReturnCode (*mss_eff_config_cke_map_FP_t)(const fapi::Target i_target_mba);
+
+extern "C" {
+
+//******************************************************************************
+//* name=mss_eff_config_cke_map, param=i_target_mba, return=ReturnCode
+//******************************************************************************
+fapi::ReturnCode mss_eff_config_cke_map(const fapi::Target i_target_mba);
+
+} // extern "C"
+
+#endif // MSS_EFF_CONFIG_CKE_MAP_H_
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 6865f0fb0..946da5294 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.2 2012/09/05 23:01:02 asaetow Exp $
+// $Id: mss_eff_config_termination.C,v 1.8 2012/12/06 13:45:57 bellows 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,7 +42,15 @@
//------------------------------------------------------------------------------
// Version:| Author: | Date: | Comment:
//---------|----------|---------|-----------------------------------------------
-// 1.3 | | |
+// 1.9 | | |
+// 1.8 | bellows |06-DEC-12| Added sim leg for rotator values
+// 1.7 | asaetow |18-NOV-12| Changed ATTR_MSS_CAL_STEP_ENABLE from 0x7F back to 0xFF.
+// 1.6 | asaetow |17-NOV-12| Fixed ATTR_EFF_ODT_WR for 4R RDIMMs.
+// 1.5 | asaetow |17-NOV-12| Added PR settings.
+// | | | Fixed RCD settings for RDIMM.
+// 1.4 | asaetow |17-NOV-12| Changed ATTR_MSS_CAL_STEP_ENABLE from 0xFF to 0x7F.
+// 1.3 | asaetow |05-NOV-12| Added Paul's SI value for pre-machine parsable workbook.
+// | | | NOTE: DO NOT pick-up without memory_attributes.xml v1.45 or newer.
// 1.2 | asaetow |05-SEP-12| Added ATTR_MSS_CAL_STEP_ENABLE.
// 1.1 | asaetow |30-APR-12| First Draft.
@@ -62,9 +70,113 @@
//----------------------------------------------------------------------
-// ENUMs
+// ENUMs and CONSTs
//----------------------------------------------------------------------
+// Define attribute array size
+const uint8_t PORT_SIZE = 2;
+const uint8_t PR_TYPE_SIZE = 48;
+const uint8_t TOPO_SIZE = 25;
+
+const uint8_t PR_VALUE_U8ARRAY[PORT_SIZE][PR_TYPE_SIZE][TOPO_SIZE] = {
+ {{0,95,100,63,67,66,63,63,63,90,95,69,71,73,77,69,71,69,73,76,77,81,73,78,74},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,103,109,0,0,0,0,0,0,98,104,0,0,0,0,0,0,0,69,71,72,77,69,71,68},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,6,9,2,1,2,2,2,2,11,14,12,15,12,15,12,14,10,18,21,17,21,16,20,15},
+ {0,7,9,3,2,3,2,3,3,11,14,11,13,11,13,10,13,9,17,20,16,19,14,18,14},
+ {0,7,9,2,2,2,2,2,2,10,13,12,15,12,15,12,15,10,18,22,18,21,16,20,15},
+ {0,3,3,5,4,5,4,5,4,5,6,11,14,11,14,11,14,9,17,20,17,20,15,19,14},
+ {0,0,0,0,0,0,0,0,1,4,5,8,10,8,10,8,10,7,14,17,14,16,12,15,12},
+ {0,0,0,1,1,1,1,1,1,5,6,12,15,12,15,11,14,10,18,21,17,21,16,20,15},
+ {0,3,3,4,3,4,3,4,4,6,8,13,16,13,16,13,16,11,19,23,18,22,17,21,16},
+ {0,2,2,3,2,3,2,3,3,6,8,13,17,13,17,13,17,11,19,23,19,23,17,22,16},
+ {0,4,4,6,5,6,5,6,5,9,11,16,21,16,21,16,21,14,22,27,22,27,21,26,19},
+ {0,6,8,2,2,2,2,2,2,10,13,12,15,12,15,12,15,10,18,22,18,22,16,21,15},
+ {0,11,14,8,6,8,6,8,7,8,11,9,11,9,11,9,11,7,15,18,15,17,12,16,12},
+ {0,8,10,3,3,3,3,3,3,11,14,12,15,12,15,12,15,10,18,22,18,21,16,21,15},
+ {0,8,10,4,3,4,3,4,4,10,12,11,13,11,13,10,13,9,17,20,16,19,14,18,14},
+ {0,7,10,3,3,3,3,3,3,13,16,14,18,14,18,14,17,12,20,24,19,23,18,23,17},
+ {0,7,9,3,2,3,2,3,3,11,14,12,15,12,15,12,15,10,18,21,17,21,16,20,15},
+ {0,11,14,8,7,8,6,8,7,8,10,7,9,7,9,7,9,6,13,15,13,15,10,14,11},
+ {0,6,7,8,7,8,7,8,7,3,3,9,11,9,11,9,11,7,15,18,14,17,12,16,12},
+ {0,6,6,8,7,8,7,8,7,4,5,10,13,10,13,10,13,8,16,20,16,19,14,18,14},
+ {0,11,14,8,6,8,6,8,7,7,9,7,8,7,8,7,8,5,13,15,12,14,10,13,10},
+ {0,12,15,9,8,9,8,9,8,7,9,8,10,8,10,8,10,7,14,17,14,16,12,15,12},
+ {0,11,14,8,6,8,6,8,7,11,13,11,14,11,14,11,14,9,17,20,17,20,15,19,14},
+ {0,12,15,9,7,9,7,9,8,7,9,6,7,6,7,6,7,5,12,14,11,13,9,12,9},
+ {0,0,0,8,7,8,7,8,7,0,0,9,11,9,11,9,11,7,15,18,14,17,12,16,12},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,31,37,3,2,3,2,3,3,38,44,8,10,8,9,8,10,7,11,14,12,13,12,16,12},
+ {0,0,0,12,10,12,10,12,11,0,0,1,2,1,1,1,1,1,5,6,5,5,6,8,7},
+ {0,24,29,0,0,0,0,0,0,34,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,12,14,0,0,0,0,0,1,21,25,10,13,10,13,10,13,9,14,17,14,16,15,20,15},
+ {0,0,0,12,10,12,10,12,11,0,0,1,2,1,2,1,2,1,5,6,5,5,6,8,7},
+ {0,0,0,2,2,2,2,2,3,0,0,10,12,10,12,10,12,8,13,17,14,15,14,19,14},
+ {0,0,0,12,10,12,10,12,11,0,0,4,5,4,5,4,5,3,7,10,8,8,8,12,9},
+ {0,14,16,3,2,3,2,3,3,14,16,3,4,3,4,3,4,3,7,9,7,7,8,11,9},
+ {0,0,0,11,9,11,9,11,10,0,0,1,2,1,1,1,1,1,5,6,5,5,6,8,7},
+ {0,31,37,0,0,0,0,0,0,41,47,0,0,0,0,0,0,0,11,13,11,13,11,14,9},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,1},
+ {0,34,40,0,0,0,0,0,0,34,41,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,19,23,0,0,0,0,0,0,13,15,0,0,0,0,0,0,0,3,4,3,4,3,4,3},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,3,3,3,3,3,2},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,6,4},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,3,3,3,3,3,3},
+ {0,15,17,0,0,0,0,0,0,21,24,0,0,0,0,0,0,0,8,10,8,10,8,10,7},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,2,2,2,3,2}},
+
+ {{0,90,95,70,71,75,68,70,71,91,96,69,71,73,77,69,71,69,73,76,77,81,73,78,74},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,99,105,0,0,0,0,0,0,99,104,0,0,0,0,0,0,0,69,71,72,77,69,71,68},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,11,13,8,7,8,7,8,7,7,9,10,12,10,12,10,12,8,16,19,16,19,14,17,13},
+ {0,9,11,6,5,6,5,6,5,8,10,10,13,10,13,10,13,8,16,20,16,19,14,18,14},
+ {0,12,14,9,7,9,7,9,7,10,12,13,16,13,16,13,16,11,19,23,19,23,17,22,16},
+ {0,2,3,4,3,4,3,4,3,2,2,10,13,11,13,10,13,8,16,20,16,19,14,18,14},
+ {0,0,0,2,2,2,2,2,2,2,3,11,13,11,13,10,13,9,17,20,16,19,14,18,14},
+ {0,0,0,0,0,0,0,0,0,4,4,13,16,13,16,13,16,10,19,23,18,22,17,21,16},
+ {0,1,2,3,2,3,2,3,2,4,5,13,16,13,16,13,16,11,19,23,19,23,17,22,16},
+ {0,0,0,2,1,2,1,2,1,3,4,12,15,12,15,12,15,10,18,22,18,21,16,20,15},
+ {0,7,8,10,8,10,8,10,8,5,5,13,16,13,16,13,16,11,19,23,19,23,17,22,16},
+ {0,5,7,1,1,1,1,1,1,10,12,13,17,13,17,13,16,11,19,23,19,23,17,22,16},
+ {0,12,15,9,8,9,8,9,8,5,7,9,11,9,11,8,10,7,15,17,14,17,12,15,12},
+ {0,6,8,3,2,3,2,3,2,10,12,13,16,13,16,13,16,11,19,23,18,22,17,21,16},
+ {0,10,13,7,6,7,6,7,6,7,8,10,12,10,13,10,12,8,16,19,16,19,14,17,13},
+ {0,9,11,6,5,6,5,6,5,9,11,12,15,12,15,12,15,10,18,22,18,21,16,20,15},
+ {0,7,9,3,3,3,3,3,3,10,12,13,17,13,17,13,17,11,19,23,19,23,17,22,16},
+ {0,10,13,6,5,6,5,6,5,7,9,10,12,10,12,10,12,8,16,19,16,19,13,17,13},
+ {0,4,5,6,5,6,5,6,5,1,1,10,12,10,12,9,12,8,16,19,15,18,13,17,13},
+ {0,4,4,5,4,5,4,5,4,2,2,10,13,10,13,10,12,8,16,19,16,19,14,17,13},
+ {0,11,14,7,6,8,6,8,6,6,8,9,11,9,11,9,11,7,15,18,15,18,13,16,12},
+ {0,12,15,9,7,9,7,9,7,7,9,10,12,10,12,10,12,8,16,19,16,19,14,17,13},
+ {0,15,18,11,9,11,9,11,9,5,7,8,9,8,9,8,9,6,14,16,13,16,11,14,11},
+ {0,13,16,10,9,11,9,11,9,5,7,8,10,8,10,8,9,6,14,16,13,16,11,14,11},
+ {0,0,0,4,3,4,3,4,3,0,0,12,15,12,15,12,15,10,18,22,18,22,16,21,15},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,32,38,3,1,3,2,3,2,31,37,4,4,4,4,4,4,3,7,9,8,7,8,11,9},
+ {0,0,0,5,3,5,4,5,4,0,0,11,14,11,14,11,14,10,15,19,15,17,16,21,15},
+ {0,27,32,0,0,0,0,0,0,36,42,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,14,16,4,3,4,4,5,4,14,15,4,4,4,4,4,4,3,7,9,8,8,8,11,9},
+ {0,0,0,10,7,10,8,10,8,0,0,12,15,12,15,12,15,10,15,20,16,18,17,22,16},
+ {0,0,0,3,2,3,3,3,3,0,0,4,4,4,4,4,4,3,7,9,8,8,8,11,9},
+ {0,0,0,12,9,12,10,12,10,0,0,11,13,11,13,11,13,9,14,18,15,16,15,20,15},
+ {0,14,16,3,1,3,2,3,3,13,15,3,4,3,3,3,4,2,6,8,7,7,7,10,8},
+ {0,0,0,12,10,12,10,13,11,0,0,9,12,9,11,9,12,8,13,16,13,15,14,18,14},
+ {0,33,39,0,0,0,0,0,0,31,36,0,0,0,0,0,0,0,4,4,4,4,4,4,3},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,15,12,15,12,15,10},
+ {0,33,40,0,0,0,0,0,0,32,38,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,15,18,0,0,0,0,0,0,19,21,0,0,0,0,0,0,0,9,11,9,11,9,11,8},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,14,17,14,17,14,17,12},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,10,9,10,9,11,7},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,13,11,13,11,13,9},
+ {0,12,14,0,0,0,0,0,0,13,15,0,0,0,0,0,0,0,4,5,4,5,4,5,3},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,11,13,11,13,10,13,9}}};
+
extern "C" {
@@ -79,112 +191,839 @@ fapi::ReturnCode mss_eff_config_termination(const fapi::Target i_target_mba) {
const char * const PROCEDURE_NAME = "mss_eff_config_termination";
FAPI_INF("*** Running %s on %s ... ***", PROCEDURE_NAME, i_target_mba.toEcmdString());
+
// Define attribute array size
- const uint8_t PORT_SIZE = 2;
const uint8_t DIMM_SIZE = 2;
const uint8_t RANK_SIZE = 4;
+
+ // Fetch dependent attributes
+ uint8_t l_target_mba_pos = 0;
+ uint32_t l_mss_freq = 0;
+ uint32_t l_mss_volt = 0;
+ uint8_t l_num_ranks_per_dimm_u8array[PORT_SIZE][DIMM_SIZE];
+ // ATTR_EFF_DRAM_GEN: EMPTY = 0, DDR3 = 1, DDR4 = 2,
+ uint8_t l_dram_gen_u8;
+ // ATTR_EFF_DIMM_TYPE: CDIMM = 0, RDIMM = 1, UDIMM = 2, LRDIMM = 3,
+ uint8_t l_dimm_type_u8;
+ uint8_t l_num_drops_per_port;
+ rc = FAPI_ATTR_GET(ATTR_CHIP_UNIT_POS, &i_target_mba, l_target_mba_pos);
+ 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;
+ if (l_mss_freq <= 0) {
+ FAPI_ERR("Invalid 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;
+ }
+ 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_GEN, &i_target_mba, l_dram_gen_u8); if(rc) return rc;
+ rc = FAPI_ATTR_GET(ATTR_EFF_DIMM_TYPE, &i_target_mba, l_dimm_type_u8); if(rc) return rc;
+ rc = FAPI_ATTR_GET(ATTR_EFF_NUM_DROPS_PER_PORT, &i_target_mba, l_num_drops_per_port); if(rc) return rc;
+
+
+ // 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;
+
+ // find out if we are in simulation mode
+ uint8_t l_attr_is_simulation;
+ rc = FAPI_ATTR_GET(ATTR_IS_SIMULATION, NULL, l_attr_is_simulation);
+
+
// Define local attribute variables
- uint8_t my_attr_mss_cal_step_enable = 0xFF;
- uint8_t my_attr_eff_cen_drv_imp_cmd = 15;
- uint8_t my_attr_eff_cen_drv_imp_cntl = 15;
- uint8_t my_attr_eff_cen_drv_imp_dq_dqs = 24;
- uint8_t my_attr_eff_cen_rcv_imp_dq_dqs = 15;
- uint32_t my_attr_eff_cen_rd_vref = 50000;
- uint8_t my_attr_eff_cen_slew_rate_cmd = 0x0;
- uint8_t my_attr_eff_cen_slew_rate_cntl = 0x0;
- uint8_t my_attr_eff_cen_slew_rate_dq_dqs = 0x0;
- uint8_t my_attr_eff_dram_ron[PORT_SIZE][DIMM_SIZE];
- my_attr_eff_dram_ron[0][0] = 34;
- my_attr_eff_dram_ron[0][1] = 34;
- my_attr_eff_dram_ron[1][0] = 34;
- my_attr_eff_dram_ron[1][1] = 34;
- uint8_t my_attr_eff_dram_rtt_nom[PORT_SIZE][DIMM_SIZE][RANK_SIZE];
- my_attr_eff_dram_rtt_nom[0][0][0] = 20;
- my_attr_eff_dram_rtt_nom[0][0][1] = 0;
- my_attr_eff_dram_rtt_nom[0][0][2] = 0;
- my_attr_eff_dram_rtt_nom[0][0][3] = 0;
- my_attr_eff_dram_rtt_nom[0][1][0] = 20;
- my_attr_eff_dram_rtt_nom[0][1][1] = 0;
- my_attr_eff_dram_rtt_nom[0][1][2] = 0;
- my_attr_eff_dram_rtt_nom[0][1][3] = 0;
- my_attr_eff_dram_rtt_nom[1][0][0] = 20;
- my_attr_eff_dram_rtt_nom[1][0][1] = 0;
- my_attr_eff_dram_rtt_nom[1][0][2] = 0;
- my_attr_eff_dram_rtt_nom[1][0][3] = 0;
- my_attr_eff_dram_rtt_nom[1][1][0] = 20;
- my_attr_eff_dram_rtt_nom[1][1][1] = 0;
- my_attr_eff_dram_rtt_nom[1][1][2] = 0;
- my_attr_eff_dram_rtt_nom[1][1][3] = 0;
- uint8_t my_attr_eff_dram_rtt_wr[PORT_SIZE][DIMM_SIZE][RANK_SIZE];
- my_attr_eff_dram_rtt_wr[0][0][0] = 60;
- my_attr_eff_dram_rtt_wr[0][0][1] = 60;
- my_attr_eff_dram_rtt_wr[0][0][2] = 0;
- my_attr_eff_dram_rtt_wr[0][0][3] = 0;
- my_attr_eff_dram_rtt_wr[0][1][0] = 60;
- my_attr_eff_dram_rtt_wr[0][1][1] = 60;
- my_attr_eff_dram_rtt_wr[0][1][2] = 0;
- my_attr_eff_dram_rtt_wr[0][1][3] = 0;
- my_attr_eff_dram_rtt_wr[1][0][0] = 60;
- my_attr_eff_dram_rtt_wr[1][0][1] = 60;
- my_attr_eff_dram_rtt_wr[1][0][2] = 0;
- my_attr_eff_dram_rtt_wr[1][0][3] = 0;
- my_attr_eff_dram_rtt_wr[1][1][0] = 60;
- my_attr_eff_dram_rtt_wr[1][1][1] = 60;
- my_attr_eff_dram_rtt_wr[1][1][2] = 0;
- my_attr_eff_dram_rtt_wr[1][1][3] = 0;
- uint32_t my_attr_eff_dram_wr_vref = 500;
- uint8_t my_attr_eff_odt_rd[PORT_SIZE][DIMM_SIZE][RANK_SIZE];
- my_attr_eff_odt_rd[0][0][0] = 0x0;
- my_attr_eff_odt_rd[0][0][1] = 0x0;
- my_attr_eff_odt_rd[0][0][2] = 0x0;
- my_attr_eff_odt_rd[0][0][3] = 0x0;
- my_attr_eff_odt_rd[0][1][0] = 0x0;
- my_attr_eff_odt_rd[0][1][1] = 0x0;
- my_attr_eff_odt_rd[0][1][2] = 0x0;
- my_attr_eff_odt_rd[0][1][3] = 0x0;
- my_attr_eff_odt_rd[1][0][0] = 0x0;
- my_attr_eff_odt_rd[1][0][1] = 0x0;
- my_attr_eff_odt_rd[1][0][2] = 0x0;
- my_attr_eff_odt_rd[1][0][3] = 0x0;
- my_attr_eff_odt_rd[1][1][0] = 0x0;
- my_attr_eff_odt_rd[1][1][1] = 0x0;
- my_attr_eff_odt_rd[1][1][2] = 0x0;
- my_attr_eff_odt_rd[1][1][3] = 0x0;
- uint8_t my_attr_eff_odt_wr[PORT_SIZE][DIMM_SIZE][RANK_SIZE];
- my_attr_eff_odt_wr[0][0][0] = 0x0;
- my_attr_eff_odt_wr[0][0][1] = 0x0;
- my_attr_eff_odt_wr[0][0][2] = 0x0;
- my_attr_eff_odt_wr[0][0][3] = 0x0;
- my_attr_eff_odt_wr[0][1][0] = 0x0;
- my_attr_eff_odt_wr[0][1][1] = 0x0;
- my_attr_eff_odt_wr[0][1][2] = 0x0;
- my_attr_eff_odt_wr[0][1][3] = 0x0;
- my_attr_eff_odt_wr[1][0][0] = 0x0;
- my_attr_eff_odt_wr[1][0][1] = 0x0;
- my_attr_eff_odt_wr[1][0][2] = 0x0;
- my_attr_eff_odt_wr[1][0][3] = 0x0;
- my_attr_eff_odt_wr[1][1][0] = 0x0;
- my_attr_eff_odt_wr[1][1][1] = 0x0;
- my_attr_eff_odt_wr[1][1][2] = 0x0;
- my_attr_eff_odt_wr[1][1][3] = 0x0;
+ uint8_t l_attr_mss_cal_step_enable = 0xFF;
+
+ uint32_t l_attr_eff_dimm_rcd_ibt[PORT_SIZE][DIMM_SIZE];
+ l_attr_eff_dimm_rcd_ibt[0][0] = fapi::ENUM_ATTR_EFF_DIMM_RCD_IBT_IBT_OFF;
+ l_attr_eff_dimm_rcd_ibt[0][1] = fapi::ENUM_ATTR_EFF_DIMM_RCD_IBT_IBT_OFF;
+ l_attr_eff_dimm_rcd_ibt[1][0] = fapi::ENUM_ATTR_EFF_DIMM_RCD_IBT_IBT_OFF;
+ l_attr_eff_dimm_rcd_ibt[1][1] = fapi::ENUM_ATTR_EFF_DIMM_RCD_IBT_IBT_OFF;
+ uint8_t l_attr_eff_dimm_rcd_mirror_mode[PORT_SIZE][DIMM_SIZE];
+ l_attr_eff_dimm_rcd_mirror_mode[0][0] = fapi::ENUM_ATTR_EFF_DIMM_RCD_MIRROR_MODE_IBT_BACK_OFF;
+ l_attr_eff_dimm_rcd_mirror_mode[0][1] = fapi::ENUM_ATTR_EFF_DIMM_RCD_MIRROR_MODE_IBT_BACK_OFF;
+ l_attr_eff_dimm_rcd_mirror_mode[1][0] = fapi::ENUM_ATTR_EFF_DIMM_RCD_MIRROR_MODE_IBT_BACK_OFF;
+ l_attr_eff_dimm_rcd_mirror_mode[1][1] = fapi::ENUM_ATTR_EFF_DIMM_RCD_MIRROR_MODE_IBT_BACK_OFF;
+
+ uint32_t l_attr_eff_cen_rd_vref[PORT_SIZE];
+ l_attr_eff_cen_rd_vref[0] = fapi::ENUM_ATTR_EFF_CEN_RD_VREF_VDD50000;
+ l_attr_eff_cen_rd_vref[1] = fapi::ENUM_ATTR_EFF_CEN_RD_VREF_VDD50000;
+ uint32_t l_attr_eff_dram_wr_vref[PORT_SIZE];
+ l_attr_eff_dram_wr_vref[0] = fapi::ENUM_ATTR_EFF_DRAM_WR_VREF_VDD500;
+ l_attr_eff_dram_wr_vref[1] = fapi::ENUM_ATTR_EFF_DRAM_WR_VREF_VDD500;
+
+ uint8_t l_attr_eff_cen_rcv_imp_dq_dqs[PORT_SIZE];
+ l_attr_eff_cen_rcv_imp_dq_dqs[0] = fapi::ENUM_ATTR_EFF_CEN_RCV_IMP_DQ_DQS_OHM60;
+ l_attr_eff_cen_rcv_imp_dq_dqs[1] = fapi::ENUM_ATTR_EFF_CEN_RCV_IMP_DQ_DQS_OHM60;
+ uint8_t l_attr_eff_cen_drv_imp_dq_dqs[PORT_SIZE];
+ l_attr_eff_cen_drv_imp_dq_dqs[0] = fapi::ENUM_ATTR_EFF_CEN_DRV_IMP_DQ_DQS_OHM34_FFE0;
+ l_attr_eff_cen_drv_imp_dq_dqs[1] = fapi::ENUM_ATTR_EFF_CEN_DRV_IMP_DQ_DQS_OHM34_FFE0;
+ uint8_t l_attr_eff_cen_drv_imp_cntl[PORT_SIZE];
+ l_attr_eff_cen_drv_imp_cntl[0] = fapi::ENUM_ATTR_EFF_CEN_DRV_IMP_CNTL_OHM30;
+ l_attr_eff_cen_drv_imp_cntl[1] = fapi::ENUM_ATTR_EFF_CEN_DRV_IMP_CNTL_OHM30;
+ uint8_t l_attr_eff_cen_drv_imp_addr[PORT_SIZE];
+ l_attr_eff_cen_drv_imp_addr[0] = fapi::ENUM_ATTR_EFF_CEN_DRV_IMP_ADDR_OHM30;
+ l_attr_eff_cen_drv_imp_addr[1] = fapi::ENUM_ATTR_EFF_CEN_DRV_IMP_ADDR_OHM30;
+ uint8_t l_attr_eff_cen_drv_imp_clk[PORT_SIZE];
+ l_attr_eff_cen_drv_imp_clk[0] = fapi::ENUM_ATTR_EFF_CEN_DRV_IMP_CLK_OHM30;
+ l_attr_eff_cen_drv_imp_clk[1] = fapi::ENUM_ATTR_EFF_CEN_DRV_IMP_CLK_OHM30;
+ uint8_t l_attr_eff_cen_drv_imp_spcke[PORT_SIZE];
+ l_attr_eff_cen_drv_imp_spcke[0] = fapi::ENUM_ATTR_EFF_CEN_DRV_IMP_SPCKE_OHM40;
+ l_attr_eff_cen_drv_imp_spcke[1] = fapi::ENUM_ATTR_EFF_CEN_DRV_IMP_SPCKE_OHM40;
+
+ uint8_t l_attr_eff_cen_slew_rate_dq_dqs[PORT_SIZE];
+ l_attr_eff_cen_slew_rate_dq_dqs[0] = fapi::ENUM_ATTR_EFF_CEN_SLEW_RATE_DQ_DQS_SLEW_4V_NS;
+ l_attr_eff_cen_slew_rate_dq_dqs[1] = fapi::ENUM_ATTR_EFF_CEN_SLEW_RATE_DQ_DQS_SLEW_4V_NS;
+ uint8_t l_attr_eff_cen_slew_rate_cntl[PORT_SIZE];
+ l_attr_eff_cen_slew_rate_cntl[0] = fapi::ENUM_ATTR_EFF_CEN_SLEW_RATE_CNTL_SLEW_4V_NS;
+ l_attr_eff_cen_slew_rate_cntl[1] = fapi::ENUM_ATTR_EFF_CEN_SLEW_RATE_CNTL_SLEW_4V_NS;
+ uint8_t l_attr_eff_cen_slew_rate_addr[PORT_SIZE];
+ l_attr_eff_cen_slew_rate_addr[0] = fapi::ENUM_ATTR_EFF_CEN_SLEW_RATE_ADDR_SLEW_4V_NS;
+ l_attr_eff_cen_slew_rate_addr[1] = fapi::ENUM_ATTR_EFF_CEN_SLEW_RATE_ADDR_SLEW_4V_NS;
+ uint8_t l_attr_eff_cen_slew_rate_clk[PORT_SIZE];
+ l_attr_eff_cen_slew_rate_clk[0] = fapi::ENUM_ATTR_EFF_CEN_SLEW_RATE_CLK_SLEW_4V_NS;
+ l_attr_eff_cen_slew_rate_clk[1] = fapi::ENUM_ATTR_EFF_CEN_SLEW_RATE_CLK_SLEW_4V_NS;
+ uint8_t l_attr_eff_cen_slew_rate_spcke[PORT_SIZE];
+ l_attr_eff_cen_slew_rate_spcke[0] = fapi::ENUM_ATTR_EFF_CEN_SLEW_RATE_SPCKE_SLEW_3V_NS;
+ l_attr_eff_cen_slew_rate_spcke[1] = fapi::ENUM_ATTR_EFF_CEN_SLEW_RATE_SPCKE_SLEW_3V_NS;
+
+ uint8_t l_attr_eff_dram_ron[PORT_SIZE][DIMM_SIZE];
+ l_attr_eff_dram_ron[0][0] = fapi::ENUM_ATTR_EFF_DRAM_RON_OHM34;
+ l_attr_eff_dram_ron[0][1] = fapi::ENUM_ATTR_EFF_DRAM_RON_OHM34;
+ l_attr_eff_dram_ron[1][0] = fapi::ENUM_ATTR_EFF_DRAM_RON_OHM34;
+ l_attr_eff_dram_ron[1][1] = fapi::ENUM_ATTR_EFF_DRAM_RON_OHM34;
+ uint8_t l_attr_eff_dram_rtt_nom[PORT_SIZE][DIMM_SIZE][RANK_SIZE];
+ l_attr_eff_dram_rtt_nom[0][0][0] = fapi::ENUM_ATTR_EFF_DRAM_RTT_NOM_DISABLE;
+ l_attr_eff_dram_rtt_nom[0][0][1] = fapi::ENUM_ATTR_EFF_DRAM_RTT_NOM_DISABLE;
+ l_attr_eff_dram_rtt_nom[0][0][2] = fapi::ENUM_ATTR_EFF_DRAM_RTT_NOM_DISABLE;
+ l_attr_eff_dram_rtt_nom[0][0][3] = fapi::ENUM_ATTR_EFF_DRAM_RTT_NOM_DISABLE;
+ l_attr_eff_dram_rtt_nom[0][1][0] = fapi::ENUM_ATTR_EFF_DRAM_RTT_NOM_DISABLE;
+ l_attr_eff_dram_rtt_nom[0][1][1] = fapi::ENUM_ATTR_EFF_DRAM_RTT_NOM_DISABLE;
+ l_attr_eff_dram_rtt_nom[0][1][2] = fapi::ENUM_ATTR_EFF_DRAM_RTT_NOM_DISABLE;
+ l_attr_eff_dram_rtt_nom[0][1][3] = fapi::ENUM_ATTR_EFF_DRAM_RTT_NOM_DISABLE;
+ l_attr_eff_dram_rtt_nom[1][0][0] = fapi::ENUM_ATTR_EFF_DRAM_RTT_NOM_DISABLE;
+ l_attr_eff_dram_rtt_nom[1][0][1] = fapi::ENUM_ATTR_EFF_DRAM_RTT_NOM_DISABLE;
+ l_attr_eff_dram_rtt_nom[1][0][2] = fapi::ENUM_ATTR_EFF_DRAM_RTT_NOM_DISABLE;
+ l_attr_eff_dram_rtt_nom[1][0][3] = fapi::ENUM_ATTR_EFF_DRAM_RTT_NOM_DISABLE;
+ l_attr_eff_dram_rtt_nom[1][1][0] = fapi::ENUM_ATTR_EFF_DRAM_RTT_NOM_DISABLE;
+ l_attr_eff_dram_rtt_nom[1][1][1] = fapi::ENUM_ATTR_EFF_DRAM_RTT_NOM_DISABLE;
+ l_attr_eff_dram_rtt_nom[1][1][2] = fapi::ENUM_ATTR_EFF_DRAM_RTT_NOM_DISABLE;
+ l_attr_eff_dram_rtt_nom[1][1][3] = fapi::ENUM_ATTR_EFF_DRAM_RTT_NOM_DISABLE;
+ uint8_t l_attr_eff_dram_rtt_wr[PORT_SIZE][DIMM_SIZE][RANK_SIZE];
+ l_attr_eff_dram_rtt_wr[0][0][0] = fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_DISABLE;
+ l_attr_eff_dram_rtt_wr[0][0][1] = fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_DISABLE;
+ l_attr_eff_dram_rtt_wr[0][0][2] = fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_DISABLE;
+ l_attr_eff_dram_rtt_wr[0][0][3] = fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_DISABLE;
+ l_attr_eff_dram_rtt_wr[0][1][0] = fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_DISABLE;
+ l_attr_eff_dram_rtt_wr[0][1][1] = fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_DISABLE;
+ l_attr_eff_dram_rtt_wr[0][1][2] = fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_DISABLE;
+ l_attr_eff_dram_rtt_wr[0][1][3] = fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_DISABLE;
+ l_attr_eff_dram_rtt_wr[1][0][0] = fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_DISABLE;
+ l_attr_eff_dram_rtt_wr[1][0][1] = fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_DISABLE;
+ l_attr_eff_dram_rtt_wr[1][0][2] = fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_DISABLE;
+ l_attr_eff_dram_rtt_wr[1][0][3] = fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_DISABLE;
+ l_attr_eff_dram_rtt_wr[1][1][0] = fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_DISABLE;
+ l_attr_eff_dram_rtt_wr[1][1][1] = fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_DISABLE;
+ l_attr_eff_dram_rtt_wr[1][1][2] = fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_DISABLE;
+ l_attr_eff_dram_rtt_wr[1][1][3] = fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_DISABLE;
+
+ uint8_t l_attr_eff_odt_rd[PORT_SIZE][DIMM_SIZE][RANK_SIZE];
+ l_attr_eff_odt_rd[0][0][0] = 0x0;
+ l_attr_eff_odt_rd[0][0][1] = 0x0;
+ l_attr_eff_odt_rd[0][0][2] = 0x0;
+ l_attr_eff_odt_rd[0][0][3] = 0x0;
+ l_attr_eff_odt_rd[0][1][0] = 0x0;
+ l_attr_eff_odt_rd[0][1][1] = 0x0;
+ l_attr_eff_odt_rd[0][1][2] = 0x0;
+ l_attr_eff_odt_rd[0][1][3] = 0x0;
+ l_attr_eff_odt_rd[1][0][0] = 0x0;
+ l_attr_eff_odt_rd[1][0][1] = 0x0;
+ l_attr_eff_odt_rd[1][0][2] = 0x0;
+ l_attr_eff_odt_rd[1][0][3] = 0x0;
+ l_attr_eff_odt_rd[1][1][0] = 0x0;
+ l_attr_eff_odt_rd[1][1][1] = 0x0;
+ l_attr_eff_odt_rd[1][1][2] = 0x0;
+ l_attr_eff_odt_rd[1][1][3] = 0x0;
+ uint8_t l_attr_eff_odt_wr[PORT_SIZE][DIMM_SIZE][RANK_SIZE];
+ l_attr_eff_odt_wr[0][0][0] = 0x0;
+ l_attr_eff_odt_wr[0][0][1] = 0x0;
+ l_attr_eff_odt_wr[0][0][2] = 0x0;
+ l_attr_eff_odt_wr[0][0][3] = 0x0;
+ l_attr_eff_odt_wr[0][1][0] = 0x0;
+ l_attr_eff_odt_wr[0][1][1] = 0x0;
+ l_attr_eff_odt_wr[0][1][2] = 0x0;
+ l_attr_eff_odt_wr[0][1][3] = 0x0;
+ l_attr_eff_odt_wr[1][0][0] = 0x0;
+ l_attr_eff_odt_wr[1][0][1] = 0x0;
+ l_attr_eff_odt_wr[1][0][2] = 0x0;
+ l_attr_eff_odt_wr[1][0][3] = 0x0;
+ l_attr_eff_odt_wr[1][1][0] = 0x0;
+ l_attr_eff_odt_wr[1][1][1] = 0x0;
+ l_attr_eff_odt_wr[1][1][2] = 0x0;
+ l_attr_eff_odt_wr[1][1][3] = 0x0;
+
+
+ if ( l_dimm_type_u8 == fapi::ENUM_ATTR_EFF_DIMM_TYPE_CDIMM ) {
+ // IMP
+ l_attr_eff_cen_drv_imp_dq_dqs[0] = fapi::ENUM_ATTR_EFF_CEN_DRV_IMP_DQ_DQS_OHM34_FFE0;
+ l_attr_eff_cen_drv_imp_dq_dqs[1] = fapi::ENUM_ATTR_EFF_CEN_DRV_IMP_DQ_DQS_OHM34_FFE0;
+ l_attr_eff_cen_drv_imp_cntl[0] = fapi::ENUM_ATTR_EFF_CEN_DRV_IMP_CNTL_OHM30;
+ l_attr_eff_cen_drv_imp_cntl[1] = fapi::ENUM_ATTR_EFF_CEN_DRV_IMP_CNTL_OHM30;
+ l_attr_eff_cen_drv_imp_addr[0] = fapi::ENUM_ATTR_EFF_CEN_DRV_IMP_ADDR_OHM30;
+ l_attr_eff_cen_drv_imp_addr[1] = fapi::ENUM_ATTR_EFF_CEN_DRV_IMP_ADDR_OHM30;
+ l_attr_eff_cen_drv_imp_clk[0] = fapi::ENUM_ATTR_EFF_CEN_DRV_IMP_CLK_OHM30;
+ l_attr_eff_cen_drv_imp_clk[1] = fapi::ENUM_ATTR_EFF_CEN_DRV_IMP_CLK_OHM30;
+ // SLEW
+ l_attr_eff_cen_slew_rate_cntl[0] = fapi::ENUM_ATTR_EFF_CEN_SLEW_RATE_CNTL_SLEW_4V_NS;
+ l_attr_eff_cen_slew_rate_cntl[1] = fapi::ENUM_ATTR_EFF_CEN_SLEW_RATE_CNTL_SLEW_4V_NS;
+ l_attr_eff_cen_slew_rate_addr[0] = fapi::ENUM_ATTR_EFF_CEN_SLEW_RATE_ADDR_SLEW_4V_NS;
+ l_attr_eff_cen_slew_rate_addr[1] = fapi::ENUM_ATTR_EFF_CEN_SLEW_RATE_ADDR_SLEW_4V_NS;
+ l_attr_eff_cen_slew_rate_clk[0] = fapi::ENUM_ATTR_EFF_CEN_SLEW_RATE_CLK_SLEW_4V_NS;
+ l_attr_eff_cen_slew_rate_clk[1] = fapi::ENUM_ATTR_EFF_CEN_SLEW_RATE_CLK_SLEW_4V_NS;
+ // RTT and ODT
+ l_attr_eff_dram_rtt_nom[0][0][0] = fapi::ENUM_ATTR_EFF_DRAM_RTT_NOM_OHM40;
+ l_attr_eff_dram_rtt_nom[0][1][0] = fapi::ENUM_ATTR_EFF_DRAM_RTT_NOM_OHM40;
+ l_attr_eff_dram_rtt_nom[1][0][0] = fapi::ENUM_ATTR_EFF_DRAM_RTT_NOM_OHM40;
+ l_attr_eff_dram_rtt_nom[1][1][0] = fapi::ENUM_ATTR_EFF_DRAM_RTT_NOM_OHM40;
+ l_attr_eff_dram_rtt_wr[0][0][0] = fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_OHM120;
+ l_attr_eff_dram_rtt_wr[0][1][0] = fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_OHM120;
+ l_attr_eff_dram_rtt_wr[1][0][0] = fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_OHM120;
+ l_attr_eff_dram_rtt_wr[1][1][0] = fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_OHM120;
+ l_attr_eff_odt_wr[0][0][0] = 0x80;
+ l_attr_eff_odt_wr[1][0][0] = 0x80;
+ } else if ( l_dimm_type_u8 == fapi::ENUM_ATTR_EFF_DIMM_TYPE_RDIMM ) {
+ // IMP
+ l_attr_eff_cen_drv_imp_dq_dqs[0] = fapi::ENUM_ATTR_EFF_CEN_DRV_IMP_DQ_DQS_OHM40_FFE0;
+ l_attr_eff_cen_drv_imp_dq_dqs[1] = fapi::ENUM_ATTR_EFF_CEN_DRV_IMP_DQ_DQS_OHM40_FFE0;
+ l_attr_eff_cen_drv_imp_cntl[0] = fapi::ENUM_ATTR_EFF_CEN_DRV_IMP_CNTL_OHM40;
+ l_attr_eff_cen_drv_imp_cntl[1] = fapi::ENUM_ATTR_EFF_CEN_DRV_IMP_CNTL_OHM40;
+ l_attr_eff_cen_drv_imp_addr[0] = fapi::ENUM_ATTR_EFF_CEN_DRV_IMP_ADDR_OHM40;
+ l_attr_eff_cen_drv_imp_addr[1] = fapi::ENUM_ATTR_EFF_CEN_DRV_IMP_ADDR_OHM40;
+ l_attr_eff_cen_drv_imp_clk[0] = fapi::ENUM_ATTR_EFF_CEN_DRV_IMP_CLK_OHM40;
+ l_attr_eff_cen_drv_imp_clk[1] = fapi::ENUM_ATTR_EFF_CEN_DRV_IMP_CLK_OHM40;
+ // SLEW
+ l_attr_eff_cen_slew_rate_cntl[0] = fapi::ENUM_ATTR_EFF_CEN_SLEW_RATE_CNTL_SLEW_3V_NS;
+ l_attr_eff_cen_slew_rate_cntl[1] = fapi::ENUM_ATTR_EFF_CEN_SLEW_RATE_CNTL_SLEW_3V_NS;
+ l_attr_eff_cen_slew_rate_addr[0] = fapi::ENUM_ATTR_EFF_CEN_SLEW_RATE_ADDR_SLEW_3V_NS;
+ l_attr_eff_cen_slew_rate_addr[1] = fapi::ENUM_ATTR_EFF_CEN_SLEW_RATE_ADDR_SLEW_3V_NS;
+ l_attr_eff_cen_slew_rate_clk[0] = fapi::ENUM_ATTR_EFF_CEN_SLEW_RATE_CLK_SLEW_3V_NS;
+ l_attr_eff_cen_slew_rate_clk[1] = fapi::ENUM_ATTR_EFF_CEN_SLEW_RATE_CLK_SLEW_3V_NS;
+ // Check DPHY01 or DHPY23
+ if ( l_target_mba_pos == 0 ) {
+ if ( l_num_ranks_per_dimm_u8array[0][0] == 4 ) {
+ // RCD TERM
+ l_attr_eff_dimm_rcd_ibt[0][0] = fapi::ENUM_ATTR_EFF_DIMM_RCD_IBT_IBT_100;
+ l_attr_eff_dimm_rcd_ibt[1][0] = fapi::ENUM_ATTR_EFF_DIMM_RCD_IBT_IBT_100;
+ l_attr_eff_dimm_rcd_mirror_mode[0][1] = fapi::ENUM_ATTR_EFF_DIMM_RCD_MIRROR_MODE_IBT_BACK_ON;
+ l_attr_eff_dimm_rcd_mirror_mode[1][1] = fapi::ENUM_ATTR_EFF_DIMM_RCD_MIRROR_MODE_IBT_BACK_ON;
+ // RTT and ODT
+ l_attr_eff_dram_rtt_nom[0][0][0] = fapi::ENUM_ATTR_EFF_DRAM_RTT_NOM_OHM30;
+ l_attr_eff_dram_rtt_nom[0][0][2] = fapi::ENUM_ATTR_EFF_DRAM_RTT_NOM_OHM30;
+ l_attr_eff_dram_rtt_nom[1][0][0] = fapi::ENUM_ATTR_EFF_DRAM_RTT_NOM_OHM30;
+ l_attr_eff_dram_rtt_nom[1][0][2] = fapi::ENUM_ATTR_EFF_DRAM_RTT_NOM_OHM30;
+ l_attr_eff_dram_rtt_wr[0][0][0] = fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_OHM120;
+ l_attr_eff_dram_rtt_wr[0][0][1] = fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_OHM120;
+ l_attr_eff_dram_rtt_wr[0][0][2] = fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_OHM120;
+ l_attr_eff_dram_rtt_wr[0][0][3] = fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_OHM120;
+ l_attr_eff_dram_rtt_wr[1][0][0] = fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_OHM120;
+ l_attr_eff_dram_rtt_wr[1][0][1] = fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_OHM120;
+ l_attr_eff_dram_rtt_wr[1][0][2] = fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_OHM120;
+ l_attr_eff_dram_rtt_wr[1][0][3] = fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_OHM120;
+ l_attr_eff_odt_rd[0][0][0] = 0x40;
+ l_attr_eff_odt_rd[0][0][1] = 0x40;
+ l_attr_eff_odt_rd[0][0][2] = 0x80;
+ l_attr_eff_odt_rd[0][0][3] = 0x80;
+ l_attr_eff_odt_rd[1][0][0] = 0x40;
+ l_attr_eff_odt_rd[1][0][1] = 0x40;
+ l_attr_eff_odt_rd[1][0][2] = 0x80;
+ l_attr_eff_odt_rd[1][0][3] = 0x80;
+ l_attr_eff_odt_wr[0][0][0] = 0xC0;
+ l_attr_eff_odt_wr[0][0][1] = 0x40;
+ l_attr_eff_odt_wr[0][0][2] = 0xC0;
+ l_attr_eff_odt_wr[0][0][3] = 0x40;
+ l_attr_eff_odt_wr[1][0][0] = 0xC0;
+ l_attr_eff_odt_wr[1][0][1] = 0x40;
+ l_attr_eff_odt_wr[1][0][2] = 0xC0;
+ l_attr_eff_odt_wr[1][0][3] = 0x40;
+ } else if ( l_num_ranks_per_dimm_u8array[0][0] == 2 ) {
+ // RCD TERM
+ l_attr_eff_dimm_rcd_ibt[0][0] = fapi::ENUM_ATTR_EFF_DIMM_RCD_IBT_IBT_100;
+ l_attr_eff_dimm_rcd_ibt[1][0] = fapi::ENUM_ATTR_EFF_DIMM_RCD_IBT_IBT_100;
+ l_attr_eff_dimm_rcd_mirror_mode[0][0] = fapi::ENUM_ATTR_EFF_DIMM_RCD_MIRROR_MODE_IBT_BACK_ON;
+ l_attr_eff_dimm_rcd_mirror_mode[0][1] = fapi::ENUM_ATTR_EFF_DIMM_RCD_MIRROR_MODE_IBT_BACK_ON;
+ l_attr_eff_dimm_rcd_mirror_mode[1][0] = fapi::ENUM_ATTR_EFF_DIMM_RCD_MIRROR_MODE_IBT_BACK_ON;
+ l_attr_eff_dimm_rcd_mirror_mode[1][1] = fapi::ENUM_ATTR_EFF_DIMM_RCD_MIRROR_MODE_IBT_BACK_ON;
+ // RTT and ODT
+ l_attr_eff_dram_rtt_wr[0][0][0] = fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_OHM60;
+ l_attr_eff_dram_rtt_wr[0][0][1] = fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_OHM60;
+ l_attr_eff_dram_rtt_wr[1][0][0] = fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_OHM60;
+ l_attr_eff_dram_rtt_wr[1][0][1] = fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_OHM60;
+ l_attr_eff_odt_wr[0][0][0] = 0x80;
+ l_attr_eff_odt_wr[0][0][1] = 0x40;
+ l_attr_eff_odt_wr[1][0][0] = 0x80;
+ l_attr_eff_odt_wr[1][0][1] = 0x40;
+ } else if ( l_num_ranks_per_dimm_u8array[0][0] == 1 ) {
+ // RCD TERM
+ l_attr_eff_dimm_rcd_ibt[0][0] = fapi::ENUM_ATTR_EFF_DIMM_RCD_IBT_IBT_100;
+ l_attr_eff_dimm_rcd_ibt[1][0] = fapi::ENUM_ATTR_EFF_DIMM_RCD_IBT_IBT_100;
+ l_attr_eff_dimm_rcd_mirror_mode[0][0] = fapi::ENUM_ATTR_EFF_DIMM_RCD_MIRROR_MODE_IBT_BACK_ON;
+ l_attr_eff_dimm_rcd_mirror_mode[0][1] = fapi::ENUM_ATTR_EFF_DIMM_RCD_MIRROR_MODE_IBT_BACK_ON;
+ l_attr_eff_dimm_rcd_mirror_mode[1][0] = fapi::ENUM_ATTR_EFF_DIMM_RCD_MIRROR_MODE_IBT_BACK_ON;
+ l_attr_eff_dimm_rcd_mirror_mode[1][1] = fapi::ENUM_ATTR_EFF_DIMM_RCD_MIRROR_MODE_IBT_BACK_ON;
+ // RTT and ODT
+ l_attr_eff_dram_rtt_wr[0][0][0] = fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_OHM60;
+ l_attr_eff_dram_rtt_wr[1][0][0] = fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_OHM60;
+ l_attr_eff_odt_wr[0][0][0] = 0x80;
+ l_attr_eff_odt_wr[1][0][0] = 0x80;
+ }
+ } else if ( l_target_mba_pos == 1 ) {
+ // Check SINGLE or DUAL Drop
+ if ( l_num_drops_per_port == fapi::ENUM_ATTR_EFF_NUM_DROPS_PER_PORT_SINGLE ) {
+ if ( l_num_ranks_per_dimm_u8array[0][0] == 4 ) {
+ // RCD TERM
+ l_attr_eff_dimm_rcd_ibt[0][0] = fapi::ENUM_ATTR_EFF_DIMM_RCD_IBT_IBT_100;
+ l_attr_eff_dimm_rcd_ibt[1][0] = fapi::ENUM_ATTR_EFF_DIMM_RCD_IBT_IBT_100;
+ l_attr_eff_dimm_rcd_mirror_mode[0][1] = fapi::ENUM_ATTR_EFF_DIMM_RCD_MIRROR_MODE_IBT_BACK_ON;
+ l_attr_eff_dimm_rcd_mirror_mode[1][1] = fapi::ENUM_ATTR_EFF_DIMM_RCD_MIRROR_MODE_IBT_BACK_ON;
+ // RTT and ODT
+ l_attr_eff_dram_rtt_nom[0][0][0] = fapi::ENUM_ATTR_EFF_DRAM_RTT_NOM_OHM30;
+ l_attr_eff_dram_rtt_nom[0][0][2] = fapi::ENUM_ATTR_EFF_DRAM_RTT_NOM_OHM30;
+ l_attr_eff_dram_rtt_nom[1][0][0] = fapi::ENUM_ATTR_EFF_DRAM_RTT_NOM_OHM30;
+ l_attr_eff_dram_rtt_nom[1][0][2] = fapi::ENUM_ATTR_EFF_DRAM_RTT_NOM_OHM30;
+ l_attr_eff_dram_rtt_wr[0][0][0] = fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_OHM120;
+ l_attr_eff_dram_rtt_wr[0][0][1] = fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_OHM120;
+ l_attr_eff_dram_rtt_wr[0][0][2] = fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_OHM120;
+ l_attr_eff_dram_rtt_wr[0][0][3] = fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_OHM120;
+ l_attr_eff_dram_rtt_wr[1][0][0] = fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_OHM120;
+ l_attr_eff_dram_rtt_wr[1][0][1] = fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_OHM120;
+ l_attr_eff_dram_rtt_wr[1][0][2] = fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_OHM120;
+ l_attr_eff_dram_rtt_wr[1][0][3] = fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_OHM120;
+ l_attr_eff_odt_rd[0][0][0] = 0x40;
+ l_attr_eff_odt_rd[0][0][1] = 0x40;
+ l_attr_eff_odt_rd[0][0][2] = 0x80;
+ l_attr_eff_odt_rd[0][0][3] = 0x80;
+ l_attr_eff_odt_rd[1][0][0] = 0x40;
+ l_attr_eff_odt_rd[1][0][1] = 0x40;
+ l_attr_eff_odt_rd[1][0][2] = 0x80;
+ l_attr_eff_odt_rd[1][0][3] = 0x80;
+ l_attr_eff_odt_wr[0][0][0] = 0xC0;
+ l_attr_eff_odt_wr[0][0][1] = 0x40;
+ l_attr_eff_odt_wr[0][0][2] = 0xC0;
+ l_attr_eff_odt_wr[0][0][3] = 0x40;
+ l_attr_eff_odt_wr[1][0][0] = 0xC0;
+ l_attr_eff_odt_wr[1][0][1] = 0x40;
+ l_attr_eff_odt_wr[1][0][2] = 0xC0;
+ l_attr_eff_odt_wr[1][0][3] = 0x40;
+ } else if ( l_num_ranks_per_dimm_u8array[0][0] == 2 ) {
+ // RCD TERM
+ l_attr_eff_dimm_rcd_ibt[0][0] = fapi::ENUM_ATTR_EFF_DIMM_RCD_IBT_IBT_100;
+ l_attr_eff_dimm_rcd_ibt[1][0] = fapi::ENUM_ATTR_EFF_DIMM_RCD_IBT_IBT_100;
+ l_attr_eff_dimm_rcd_mirror_mode[0][0] = fapi::ENUM_ATTR_EFF_DIMM_RCD_MIRROR_MODE_IBT_BACK_ON;
+ l_attr_eff_dimm_rcd_mirror_mode[0][1] = fapi::ENUM_ATTR_EFF_DIMM_RCD_MIRROR_MODE_IBT_BACK_ON;
+ l_attr_eff_dimm_rcd_mirror_mode[1][0] = fapi::ENUM_ATTR_EFF_DIMM_RCD_MIRROR_MODE_IBT_BACK_ON;
+ l_attr_eff_dimm_rcd_mirror_mode[1][1] = fapi::ENUM_ATTR_EFF_DIMM_RCD_MIRROR_MODE_IBT_BACK_ON;
+ // RTT and ODT
+ l_attr_eff_dram_rtt_wr[0][0][0] = fapi::ENUM_ATTR_EFF_DRAM_RTT_NOM_OHM40;
+ l_attr_eff_dram_rtt_wr[0][0][1] = fapi::ENUM_ATTR_EFF_DRAM_RTT_NOM_OHM40;
+ l_attr_eff_dram_rtt_wr[1][0][0] = fapi::ENUM_ATTR_EFF_DRAM_RTT_NOM_OHM40;
+ l_attr_eff_dram_rtt_wr[1][0][1] = fapi::ENUM_ATTR_EFF_DRAM_RTT_NOM_OHM40;
+ l_attr_eff_odt_wr[0][0][0] = 0x40;
+ l_attr_eff_odt_wr[0][0][1] = 0x80;
+ l_attr_eff_odt_wr[1][0][0] = 0x40;
+ l_attr_eff_odt_wr[1][0][1] = 0x80;
+ } else if ( l_num_ranks_per_dimm_u8array[0][0] == 1 ) {
+ // RCD TERM
+ l_attr_eff_dimm_rcd_ibt[0][0] = fapi::ENUM_ATTR_EFF_DIMM_RCD_IBT_IBT_100;
+ l_attr_eff_dimm_rcd_ibt[1][0] = fapi::ENUM_ATTR_EFF_DIMM_RCD_IBT_IBT_100;
+ l_attr_eff_dimm_rcd_mirror_mode[0][0] = fapi::ENUM_ATTR_EFF_DIMM_RCD_MIRROR_MODE_IBT_BACK_ON;
+ l_attr_eff_dimm_rcd_mirror_mode[0][1] = fapi::ENUM_ATTR_EFF_DIMM_RCD_MIRROR_MODE_IBT_BACK_ON;
+ l_attr_eff_dimm_rcd_mirror_mode[1][0] = fapi::ENUM_ATTR_EFF_DIMM_RCD_MIRROR_MODE_IBT_BACK_ON;
+ l_attr_eff_dimm_rcd_mirror_mode[1][1] = fapi::ENUM_ATTR_EFF_DIMM_RCD_MIRROR_MODE_IBT_BACK_ON;
+ // RTT and ODT
+ l_attr_eff_dram_rtt_wr[0][0][0] = fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_OHM60;
+ l_attr_eff_dram_rtt_wr[1][0][0] = fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_OHM60;
+ l_attr_eff_odt_wr[0][0][0] = 0x80;
+ l_attr_eff_odt_wr[1][0][0] = 0x80;
+ }
+ } else if ( l_num_drops_per_port == fapi::ENUM_ATTR_EFF_NUM_DROPS_PER_PORT_DUAL ) {
+ if ( l_num_ranks_per_dimm_u8array[0][0] == 4 ) {
+ // RCD TERM
+ l_attr_eff_dimm_rcd_ibt[0][0] = fapi::ENUM_ATTR_EFF_DIMM_RCD_IBT_IBT_200;
+ l_attr_eff_dimm_rcd_ibt[0][1] = fapi::ENUM_ATTR_EFF_DIMM_RCD_IBT_IBT_200;
+ l_attr_eff_dimm_rcd_ibt[1][0] = fapi::ENUM_ATTR_EFF_DIMM_RCD_IBT_IBT_200;
+ l_attr_eff_dimm_rcd_ibt[1][1] = fapi::ENUM_ATTR_EFF_DIMM_RCD_IBT_IBT_200;
+ l_attr_eff_dimm_rcd_mirror_mode[0][0] = fapi::ENUM_ATTR_EFF_DIMM_RCD_MIRROR_MODE_IBT_BACK_OFF;
+ l_attr_eff_dimm_rcd_mirror_mode[0][1] = fapi::ENUM_ATTR_EFF_DIMM_RCD_MIRROR_MODE_IBT_BACK_OFF;
+ l_attr_eff_dimm_rcd_mirror_mode[1][0] = fapi::ENUM_ATTR_EFF_DIMM_RCD_MIRROR_MODE_IBT_BACK_OFF;
+ l_attr_eff_dimm_rcd_mirror_mode[1][1] = fapi::ENUM_ATTR_EFF_DIMM_RCD_MIRROR_MODE_IBT_BACK_OFF;
+ // RTT and ODT
+ l_attr_eff_dram_rtt_nom[0][0][0] = fapi::ENUM_ATTR_EFF_DRAM_RTT_NOM_OHM20;
+ l_attr_eff_dram_rtt_nom[0][0][2] = fapi::ENUM_ATTR_EFF_DRAM_RTT_NOM_OHM20;
+ l_attr_eff_dram_rtt_nom[0][1][0] = fapi::ENUM_ATTR_EFF_DRAM_RTT_NOM_OHM20;
+ l_attr_eff_dram_rtt_nom[0][1][2] = fapi::ENUM_ATTR_EFF_DRAM_RTT_NOM_OHM20;
+ l_attr_eff_dram_rtt_nom[1][0][0] = fapi::ENUM_ATTR_EFF_DRAM_RTT_NOM_OHM20;
+ l_attr_eff_dram_rtt_nom[1][0][2] = fapi::ENUM_ATTR_EFF_DRAM_RTT_NOM_OHM20;
+ l_attr_eff_dram_rtt_nom[1][1][0] = fapi::ENUM_ATTR_EFF_DRAM_RTT_NOM_OHM20;
+ l_attr_eff_dram_rtt_nom[1][1][2] = fapi::ENUM_ATTR_EFF_DRAM_RTT_NOM_OHM20;
+ l_attr_eff_dram_rtt_wr[0][0][0] = fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_OHM120;
+ l_attr_eff_dram_rtt_wr[0][0][1] = fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_OHM120;
+ l_attr_eff_dram_rtt_wr[0][0][2] = fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_OHM120;
+ l_attr_eff_dram_rtt_wr[0][0][3] = fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_OHM120;
+ l_attr_eff_dram_rtt_wr[0][1][0] = fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_OHM120;
+ l_attr_eff_dram_rtt_wr[0][1][1] = fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_OHM120;
+ l_attr_eff_dram_rtt_wr[0][1][2] = fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_OHM120;
+ l_attr_eff_dram_rtt_wr[0][1][3] = fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_OHM120;
+ l_attr_eff_dram_rtt_wr[1][0][0] = fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_OHM120;
+ l_attr_eff_dram_rtt_wr[1][0][1] = fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_OHM120;
+ l_attr_eff_dram_rtt_wr[1][0][2] = fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_OHM120;
+ l_attr_eff_dram_rtt_wr[1][0][3] = fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_OHM120;
+ l_attr_eff_dram_rtt_wr[1][1][0] = fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_OHM120;
+ l_attr_eff_dram_rtt_wr[1][1][1] = fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_OHM120;
+ l_attr_eff_dram_rtt_wr[1][1][2] = fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_OHM120;
+ l_attr_eff_dram_rtt_wr[1][1][3] = fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_OHM120;
+ l_attr_eff_odt_rd[0][0][0] = 0x20;
+ l_attr_eff_odt_rd[0][0][1] = 0x20;
+ l_attr_eff_odt_rd[0][0][2] = 0x20;
+ l_attr_eff_odt_rd[0][0][3] = 0x20;
+ l_attr_eff_odt_rd[0][1][0] = 0x80;
+ l_attr_eff_odt_rd[0][1][1] = 0x80;
+ l_attr_eff_odt_rd[0][1][2] = 0x80;
+ l_attr_eff_odt_rd[0][1][3] = 0x80;
+ l_attr_eff_odt_rd[1][0][0] = 0x20;
+ l_attr_eff_odt_rd[1][0][1] = 0x20;
+ l_attr_eff_odt_rd[1][0][2] = 0x20;
+ l_attr_eff_odt_rd[1][0][3] = 0x20;
+ l_attr_eff_odt_rd[1][1][0] = 0x80;
+ l_attr_eff_odt_rd[1][1][1] = 0x80;
+ l_attr_eff_odt_rd[1][1][2] = 0x80;
+ l_attr_eff_odt_rd[1][1][3] = 0x80;
+ l_attr_eff_odt_wr[0][0][0] = 0xA0;
+ l_attr_eff_odt_wr[0][0][1] = 0x20;
+ l_attr_eff_odt_wr[0][0][2] = 0x60;
+ l_attr_eff_odt_wr[0][0][3] = 0x20;
+ l_attr_eff_odt_wr[0][1][0] = 0xA0;
+ l_attr_eff_odt_wr[0][1][1] = 0x80;
+ l_attr_eff_odt_wr[0][1][2] = 0x90;
+ l_attr_eff_odt_wr[0][1][3] = 0x80;
+ l_attr_eff_odt_wr[1][0][0] = 0xA0;
+ l_attr_eff_odt_wr[1][0][1] = 0x20;
+ l_attr_eff_odt_wr[1][0][2] = 0x60;
+ l_attr_eff_odt_wr[1][0][3] = 0x20;
+ l_attr_eff_odt_wr[1][1][0] = 0xA0;
+ l_attr_eff_odt_wr[1][1][1] = 0x80;
+ l_attr_eff_odt_wr[1][1][2] = 0x90;
+ l_attr_eff_odt_wr[1][1][3] = 0x80;
+ } else if ( l_num_ranks_per_dimm_u8array[0][0] == 2 ) {
+ // RCD TERM
+ l_attr_eff_dimm_rcd_ibt[0][0] = fapi::ENUM_ATTR_EFF_DIMM_RCD_IBT_IBT_200;
+ l_attr_eff_dimm_rcd_ibt[0][1] = fapi::ENUM_ATTR_EFF_DIMM_RCD_IBT_IBT_200;
+ l_attr_eff_dimm_rcd_ibt[1][0] = fapi::ENUM_ATTR_EFF_DIMM_RCD_IBT_IBT_200;
+ l_attr_eff_dimm_rcd_ibt[1][1] = fapi::ENUM_ATTR_EFF_DIMM_RCD_IBT_IBT_200;
+ l_attr_eff_dimm_rcd_mirror_mode[0][0] = fapi::ENUM_ATTR_EFF_DIMM_RCD_MIRROR_MODE_IBT_BACK_ON;
+ l_attr_eff_dimm_rcd_mirror_mode[0][1] = fapi::ENUM_ATTR_EFF_DIMM_RCD_MIRROR_MODE_IBT_BACK_ON;
+ l_attr_eff_dimm_rcd_mirror_mode[1][0] = fapi::ENUM_ATTR_EFF_DIMM_RCD_MIRROR_MODE_IBT_BACK_ON;
+ l_attr_eff_dimm_rcd_mirror_mode[1][1] = fapi::ENUM_ATTR_EFF_DIMM_RCD_MIRROR_MODE_IBT_BACK_ON;
+ // RTT and ODT
+ l_attr_eff_dram_rtt_wr[0][0][0] = fapi::ENUM_ATTR_EFF_DRAM_RTT_NOM_OHM40;
+ l_attr_eff_dram_rtt_wr[0][0][1] = fapi::ENUM_ATTR_EFF_DRAM_RTT_NOM_OHM40;
+ l_attr_eff_dram_rtt_wr[0][1][0] = fapi::ENUM_ATTR_EFF_DRAM_RTT_NOM_OHM40;
+ l_attr_eff_dram_rtt_wr[0][1][1] = fapi::ENUM_ATTR_EFF_DRAM_RTT_NOM_OHM40;
+ l_attr_eff_dram_rtt_wr[1][0][0] = fapi::ENUM_ATTR_EFF_DRAM_RTT_NOM_OHM40;
+ l_attr_eff_dram_rtt_wr[1][0][1] = fapi::ENUM_ATTR_EFF_DRAM_RTT_NOM_OHM40;
+ l_attr_eff_dram_rtt_wr[1][1][0] = fapi::ENUM_ATTR_EFF_DRAM_RTT_NOM_OHM40;
+ l_attr_eff_dram_rtt_wr[1][1][1] = fapi::ENUM_ATTR_EFF_DRAM_RTT_NOM_OHM40;
+ l_attr_eff_dram_rtt_wr[0][0][0] = fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_OHM120;
+ l_attr_eff_dram_rtt_wr[0][0][1] = fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_OHM120;
+ l_attr_eff_dram_rtt_wr[0][1][0] = fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_OHM120;
+ l_attr_eff_dram_rtt_wr[0][1][1] = fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_OHM120;
+ l_attr_eff_dram_rtt_wr[1][0][0] = fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_OHM120;
+ l_attr_eff_dram_rtt_wr[1][0][1] = fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_OHM120;
+ l_attr_eff_dram_rtt_wr[1][1][0] = fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_OHM120;
+ l_attr_eff_dram_rtt_wr[1][1][1] = fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_OHM120;
+ l_attr_eff_odt_rd[0][0][0] = 0x20;
+ l_attr_eff_odt_rd[0][0][1] = 0x20;
+ l_attr_eff_odt_rd[0][1][0] = 0x80;
+ l_attr_eff_odt_rd[0][1][1] = 0x80;
+ l_attr_eff_odt_rd[1][0][0] = 0x20;
+ l_attr_eff_odt_rd[1][0][1] = 0x20;
+ l_attr_eff_odt_rd[1][1][0] = 0x80;
+ l_attr_eff_odt_rd[1][1][1] = 0x80;
+ l_attr_eff_odt_wr[0][0][0] = 0xA0;
+ l_attr_eff_odt_wr[0][0][1] = 0x60;
+ l_attr_eff_odt_wr[0][1][0] = 0xA0;
+ l_attr_eff_odt_wr[0][1][1] = 0x60;
+ l_attr_eff_odt_wr[1][0][0] = 0xA0;
+ l_attr_eff_odt_wr[1][0][1] = 0x60;
+ l_attr_eff_odt_wr[1][1][0] = 0xA0;
+ l_attr_eff_odt_wr[1][1][1] = 0x60;
+ } else if ( l_num_ranks_per_dimm_u8array[0][0] == 1 ) {
+ // RCD TERM
+ l_attr_eff_dimm_rcd_ibt[0][0] = fapi::ENUM_ATTR_EFF_DIMM_RCD_IBT_IBT_200;
+ l_attr_eff_dimm_rcd_ibt[0][1] = fapi::ENUM_ATTR_EFF_DIMM_RCD_IBT_IBT_200;
+ l_attr_eff_dimm_rcd_ibt[1][0] = fapi::ENUM_ATTR_EFF_DIMM_RCD_IBT_IBT_200;
+ l_attr_eff_dimm_rcd_ibt[1][1] = fapi::ENUM_ATTR_EFF_DIMM_RCD_IBT_IBT_200;
+ l_attr_eff_dimm_rcd_mirror_mode[0][0] = fapi::ENUM_ATTR_EFF_DIMM_RCD_MIRROR_MODE_IBT_BACK_ON;
+ l_attr_eff_dimm_rcd_mirror_mode[0][1] = fapi::ENUM_ATTR_EFF_DIMM_RCD_MIRROR_MODE_IBT_BACK_ON;
+ l_attr_eff_dimm_rcd_mirror_mode[1][0] = fapi::ENUM_ATTR_EFF_DIMM_RCD_MIRROR_MODE_IBT_BACK_ON;
+ l_attr_eff_dimm_rcd_mirror_mode[1][1] = fapi::ENUM_ATTR_EFF_DIMM_RCD_MIRROR_MODE_IBT_BACK_ON;
+ // RTT and ODT
+ l_attr_eff_dram_rtt_wr[0][0][0] = fapi::ENUM_ATTR_EFF_DRAM_RTT_NOM_OHM30;
+ l_attr_eff_dram_rtt_wr[0][1][0] = fapi::ENUM_ATTR_EFF_DRAM_RTT_NOM_OHM30;
+ l_attr_eff_dram_rtt_wr[1][0][0] = fapi::ENUM_ATTR_EFF_DRAM_RTT_NOM_OHM30;
+ l_attr_eff_dram_rtt_wr[1][1][0] = fapi::ENUM_ATTR_EFF_DRAM_RTT_NOM_OHM30;
+ l_attr_eff_dram_rtt_wr[0][0][0] = fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_OHM120;
+ l_attr_eff_dram_rtt_wr[0][1][0] = fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_OHM120;
+ l_attr_eff_dram_rtt_wr[1][0][0] = fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_OHM120;
+ l_attr_eff_dram_rtt_wr[1][1][0] = fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_OHM120;
+ l_attr_eff_odt_rd[0][0][0] = 0x20;
+ l_attr_eff_odt_rd[0][1][0] = 0x80;
+ l_attr_eff_odt_rd[1][0][0] = 0x20;
+ l_attr_eff_odt_rd[1][1][0] = 0x80;
+ l_attr_eff_odt_wr[0][0][0] = 0xA0;
+ l_attr_eff_odt_wr[0][1][0] = 0xA0;
+ l_attr_eff_odt_wr[1][0][0] = 0xA0;
+ l_attr_eff_odt_wr[1][1][0] = 0xA0;
+ }
+ }
+ } else {
+ FAPI_ERR("Invalid MBA on %s!", i_target_mba.toEcmdString());
+ FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR); return rc;
+ }
+ } else {
+ FAPI_ERR("Currently unsupported DIMM_TYPE on %s!", i_target_mba.toEcmdString());
+ FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR); return rc;
+ }
+
+
+ // Modify impacted attributes
+ if ( l_dimm_type_u8 == fapi::ENUM_ATTR_EFF_DIMM_TYPE_RDIMM ) {
+ for( int l_port = 0; l_port < PORT_SIZE; l_port += 1 ) {
+ for( int l_dimm = 0; l_dimm < DIMM_SIZE; l_dimm += 1 ) {
+ uint64_t l_mss_freq_mask = 0xFFFFFFFFFFCFFFFFLL;
+ uint64_t l_mss_volt_mask = 0xFFFFFFFFFFFEFFFFLL;
+ uint64_t l_rcd_ibt_mask = 0xFFBFFFFF8FFFFFFFLL;
+ uint64_t l_rcd_mirror_mode_mask = 0xFFFFFFFF7FFFFFFFLL;
+ if ( l_num_ranks_per_dimm_u8array[l_port][l_dimm] == 4 ) {
+ l_attr_eff_dimm_rcd_cntl_word_0_15[l_port][l_dimm] = 0x0005050080210000LL;
+ } else if ( l_num_ranks_per_dimm_u8array[l_port][l_dimm] == 2 ) {
+ l_attr_eff_dimm_rcd_cntl_word_0_15[l_port][l_dimm] = 0x0005550000210000LL;
+ } else if ( l_num_ranks_per_dimm_u8array[l_port][l_dimm] == 1 ) {
+ l_attr_eff_dimm_rcd_cntl_word_0_15[l_port][l_dimm] = 0x0C00000001210000LL;
+ } else {
+ l_attr_eff_dimm_rcd_cntl_word_0_15[l_port][l_dimm] = 0x0000000000000000LL;
+ }
+ 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_mss_freq_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_mss_volt_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_ibt_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_mirror_mode_mask;
+ if ( l_mss_freq <= 933 ) { // 800Mbps
+ l_mss_freq_mask = 0x0000000000000000LL;
+ } else if ( l_mss_freq <= 1200 ) { // 1066Mbps
+ l_mss_freq_mask = 0x0000000000100000LL;
+ } else if ( l_mss_freq <= 1466 ) { // 1333Mbps
+ l_mss_freq_mask = 0x0000000000200000LL;
+ } else if ( l_mss_freq <= 1733 ) { // 1600Mbps
+ l_mss_freq_mask = 0x0000000000300000LL;
+ } else { // 1866Mbps
+ FAPI_ERR("Invalid RDIMM 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;
+ }
+ if ( l_mss_volt >= 1420 ) { // 1.5V
+ l_mss_volt_mask = 0x0000000000000000LL;
+ } else if ( l_mss_volt >= 1270 ) { // 1.35V
+ l_mss_volt_mask = 0x0000000000010000LL;
+ } else { // 1.2V
+ FAPI_ERR("Invalid RDIMM 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;
+ }
+ if ( l_attr_eff_dimm_rcd_ibt[l_port][l_dimm] == fapi::ENUM_ATTR_EFF_DIMM_RCD_IBT_IBT_OFF ) {
+ l_rcd_ibt_mask = 0x0000000070000000LL;
+ } else if ( l_attr_eff_dimm_rcd_ibt[l_port][l_dimm] == fapi::ENUM_ATTR_EFF_DIMM_RCD_IBT_IBT_100 ) {
+ l_rcd_ibt_mask = 0x0000000000000000LL;
+ } else if ( l_attr_eff_dimm_rcd_ibt[l_port][l_dimm] == fapi::ENUM_ATTR_EFF_DIMM_RCD_IBT_IBT_150 ) {
+ l_rcd_ibt_mask = 0x0040000000000000LL;
+ } else if ( l_attr_eff_dimm_rcd_ibt[l_port][l_dimm] == fapi::ENUM_ATTR_EFF_DIMM_RCD_IBT_IBT_200 ) {
+ l_rcd_ibt_mask = 0x0000000020000000LL;
+ } else if ( l_attr_eff_dimm_rcd_ibt[l_port][l_dimm] == fapi::ENUM_ATTR_EFF_DIMM_RCD_IBT_IBT_300 ) {
+ l_rcd_ibt_mask = 0x0000000040000000LL;
+ } else {
+ FAPI_ERR("Invalid DIMM_RCD_IBT on %s!", i_target_mba.toEcmdString());
+ FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR); return rc;
+ }
+ if ( l_attr_eff_dimm_rcd_mirror_mode[l_port][l_dimm] == fapi::ENUM_ATTR_EFF_DIMM_RCD_MIRROR_MODE_IBT_BACK_OFF ) {
+ l_rcd_mirror_mode_mask = 0x0000000000000000LL;
+ } else if ( l_attr_eff_dimm_rcd_mirror_mode[l_port][l_dimm] == fapi::ENUM_ATTR_EFF_DIMM_RCD_MIRROR_MODE_IBT_BACK_ON ) {
+ l_rcd_mirror_mode_mask = 0x0000000080000000LL;
+ } else {
+ FAPI_ERR("Invalid DIMM_RCD_MIRROR_MODE on %s!", i_target_mba.toEcmdString());
+ FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR); return rc;
+ }
+ 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_mss_freq_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_mss_volt_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_ibt_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_mirror_mode_mask;
+ }
+ }
+ }
+
+
+ // PR_VALUE_U8ARRAY[PORT_SIZE][PR_TYPE_SIZE][TOPO_SIZE]
+ uint8_t l_attr_eff_cen_phase_rot[PR_TYPE_SIZE][PORT_SIZE];
+ uint8_t l_topo_index = 0;
+ if ( l_dimm_type_u8 == fapi::ENUM_ATTR_EFF_DIMM_TYPE_CDIMM ) {
+ if ( l_target_mba_pos == 0 ) {
+ if ( l_mss_freq <= 933 ) { // 800Mbps
+ l_topo_index = 0;
+ } else if ( l_mss_freq <= 1200 ) { // 1066Mbps
+ l_topo_index = 1;
+ } else if ( l_mss_freq <= 1466 ) { // 1333Mbps
+ l_topo_index = 1;
+ } else if ( l_mss_freq <= 1733 ) { // 1600Mbps
+ l_topo_index = 2;
+ } else { // 1866Mbps
+ l_topo_index = 2;
+ }
+ } else if ( l_target_mba_pos == 1 ) {
+ if ( l_mss_freq <= 933 ) { // 800Mbps
+ l_topo_index = 0;
+ } else if ( l_mss_freq <= 1200 ) { // 1066Mbps
+ l_topo_index = 9;
+ } else if ( l_mss_freq <= 1466 ) { // 1333Mbps
+ l_topo_index = 9;
+ } else if ( l_mss_freq <= 1733 ) { // 1600Mbps
+ l_topo_index = 10;
+ } else { // 1866Mbps
+ l_topo_index = 10;
+ }
+ } else {
+ FAPI_ERR("Invalid MBA on %s!", i_target_mba.toEcmdString());
+ FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR); return rc;
+ }
+ } else {
+ if ( l_target_mba_pos == 0 ) {
+ if ( l_num_ranks_per_dimm_u8array[0][0] == 4 ) {
+ l_topo_index = 8;
+ } else if ( l_num_ranks_per_dimm_u8array[0][0] == 2 ) {
+ if ( l_mss_freq <= 933 ) { // 800Mbps
+ l_topo_index = 0;
+ } else if ( l_mss_freq <= 1200 ) { // 1066Mbps
+ l_topo_index = 4;
+ } else if ( l_mss_freq <= 1466 ) { // 1333Mbps
+ l_topo_index = 4;
+ } else if ( l_mss_freq <= 1733 ) { // 1600Mbps
+ l_topo_index = 5;
+ } else { // 1866Mbps
+ l_topo_index = 5;
+ }
+ } else if ( l_num_ranks_per_dimm_u8array[0][0] == 1 ) {
+ l_topo_index = 3;
+ } else {
+ l_topo_index = 0;
+ }
+ } else if ( l_target_mba_pos == 1 ) {
+ if ( l_num_drops_per_port == fapi::ENUM_ATTR_EFF_NUM_DROPS_PER_PORT_SINGLE ) {
+ if ( l_num_ranks_per_dimm_u8array[0][0] == 4 ) {
+ l_topo_index = 17;
+ } else if ( l_num_ranks_per_dimm_u8array[0][0] == 2 ) {
+ if ( l_mss_freq <= 933 ) { // 800Mbps
+ l_topo_index = 0;
+ } else if ( l_mss_freq <= 1200 ) { // 1066Mbps
+ l_topo_index = 13;
+ } else if ( l_mss_freq <= 1466 ) { // 1333Mbps
+ l_topo_index = 13;
+ } else if ( l_mss_freq <= 1733 ) { // 1600Mbps
+ l_topo_index = 14;
+ } else { // 1866Mbps
+ l_topo_index = 14;
+ }
+ } else if ( l_num_ranks_per_dimm_u8array[0][0] == 1 ) {
+ if ( l_mss_freq <= 933 ) { // 800Mbps
+ l_topo_index = 0;
+ } else if ( l_mss_freq <= 1200 ) { // 1066Mbps
+ l_topo_index = 11;
+ } else if ( l_mss_freq <= 1466 ) { // 1333Mbps
+ l_topo_index = 11;
+ } else if ( l_mss_freq <= 1733 ) { // 1600Mbps
+ l_topo_index = 12;
+ } else { // 1866Mbps
+ l_topo_index = 12;
+ }
+ } else {
+ l_topo_index = 0;
+ }
+ } else if ( l_num_drops_per_port == fapi::ENUM_ATTR_EFF_NUM_DROPS_PER_PORT_DUAL ) {
+ if ( l_num_ranks_per_dimm_u8array[0][0] == 4 ) {
+ l_topo_index = 24;
+ } else if ( l_num_ranks_per_dimm_u8array[0][0] == 2 ) {
+ if ( l_mss_freq <= 933 ) { // 800Mbps
+ l_topo_index = 0;
+ } else if ( l_mss_freq <= 1200 ) { // 1066Mbps
+ l_topo_index = 20;
+ } else if ( l_mss_freq <= 1466 ) { // 1333Mbps
+ l_topo_index = 20;
+ } else if ( l_mss_freq <= 1733 ) { // 1600Mbps
+ l_topo_index = 21;
+ } else { // 1866Mbps
+ l_topo_index = 21;
+ }
+ } else if ( l_num_ranks_per_dimm_u8array[0][0] == 1 ) {
+ if ( l_mss_freq <= 933 ) { // 800Mbps
+ l_topo_index = 0;
+ } else if ( l_mss_freq <= 1200 ) { // 1066Mbps
+ l_topo_index = 18;
+ } else if ( l_mss_freq <= 1466 ) { // 1333Mbps
+ l_topo_index = 18;
+ } else if ( l_mss_freq <= 1733 ) { // 1600Mbps
+ l_topo_index = 19;
+ } else { // 1866Mbps
+ l_topo_index = 19;
+ }
+ } else {
+ l_topo_index = 0;
+ }
+ } else {
+ l_topo_index = 0;
+ }
+ } else {
+ FAPI_ERR("Invalid MBA on %s!", i_target_mba.toEcmdString());
+ FAPI_SET_HWP_ERROR(rc, RC_MSS_PLACE_HOLDER_ERROR); return rc;
+ }
+ }
+ for( int l_port = 0; l_port < PORT_SIZE; l_port += 1 ) {
+ for( int l_pr_type_index = 0; l_pr_type_index < PR_TYPE_SIZE; l_pr_type_index += 1 ) {
+ l_attr_eff_cen_phase_rot[l_pr_type_index][l_port] = PR_VALUE_U8ARRAY[l_port][l_pr_type_index][l_topo_index];
+ }
+ }
+
// Set attributes
- rc = FAPI_ATTR_SET(ATTR_MSS_CAL_STEP_ENABLE, &i_target_mba, my_attr_mss_cal_step_enable); if(rc) return rc;
- rc = FAPI_ATTR_SET(ATTR_EFF_CEN_DRV_IMP_CMD, &i_target_mba, my_attr_eff_cen_drv_imp_cmd); if(rc) return rc;
- rc = FAPI_ATTR_SET(ATTR_EFF_CEN_DRV_IMP_CNTL, &i_target_mba, my_attr_eff_cen_drv_imp_cntl); if(rc) return rc;
- rc = FAPI_ATTR_SET(ATTR_EFF_CEN_DRV_IMP_DQ_DQS, &i_target_mba, my_attr_eff_cen_drv_imp_dq_dqs); if(rc) return rc;
- rc = FAPI_ATTR_SET(ATTR_EFF_CEN_RCV_IMP_DQ_DQS, &i_target_mba, my_attr_eff_cen_rcv_imp_dq_dqs); if(rc) return rc;
- rc = FAPI_ATTR_SET(ATTR_EFF_CEN_RD_VREF, &i_target_mba, my_attr_eff_cen_rd_vref); if(rc) return rc;
- rc = FAPI_ATTR_SET(ATTR_EFF_CEN_SLEW_RATE_CMD, &i_target_mba, my_attr_eff_cen_slew_rate_cmd); if(rc) return rc;
- rc = FAPI_ATTR_SET(ATTR_EFF_CEN_SLEW_RATE_CNTL, &i_target_mba, my_attr_eff_cen_slew_rate_cntl); if(rc) return rc;
- rc = FAPI_ATTR_SET(ATTR_EFF_CEN_SLEW_RATE_DQ_DQS, &i_target_mba, my_attr_eff_cen_slew_rate_dq_dqs); if(rc) return rc;
- rc = FAPI_ATTR_SET(ATTR_EFF_DRAM_RON, &i_target_mba, my_attr_eff_dram_ron); if(rc) return rc;
- rc = FAPI_ATTR_SET(ATTR_EFF_DRAM_RTT_NOM, &i_target_mba, my_attr_eff_dram_rtt_nom); if(rc) return rc;
- rc = FAPI_ATTR_SET(ATTR_EFF_DRAM_RTT_WR, &i_target_mba, my_attr_eff_dram_rtt_wr); if(rc) return rc;
- rc = FAPI_ATTR_SET(ATTR_EFF_DRAM_WR_VREF, &i_target_mba, my_attr_eff_dram_wr_vref); if(rc) return rc;
- rc = FAPI_ATTR_SET(ATTR_EFF_ODT_RD, &i_target_mba, my_attr_eff_odt_rd); if(rc) return rc;
- rc = FAPI_ATTR_SET(ATTR_EFF_ODT_WR, &i_target_mba, my_attr_eff_odt_wr); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_MSS_CAL_STEP_ENABLE, &i_target_mba, l_attr_mss_cal_step_enable); 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;
+ rc = FAPI_ATTR_SET(ATTR_EFF_DIMM_RCD_IBT, &i_target_mba, l_attr_eff_dimm_rcd_ibt); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_DIMM_RCD_MIRROR_MODE, &i_target_mba, l_attr_eff_dimm_rcd_mirror_mode); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_CEN_RD_VREF, &i_target_mba, l_attr_eff_cen_rd_vref); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_DRAM_WR_VREF, &i_target_mba, l_attr_eff_dram_wr_vref); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_CEN_RCV_IMP_DQ_DQS, &i_target_mba, l_attr_eff_cen_rcv_imp_dq_dqs); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_CEN_DRV_IMP_DQ_DQS, &i_target_mba, l_attr_eff_cen_drv_imp_dq_dqs); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_CEN_DRV_IMP_CNTL, &i_target_mba, l_attr_eff_cen_drv_imp_cntl); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_CEN_DRV_IMP_ADDR, &i_target_mba, l_attr_eff_cen_drv_imp_addr); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_CEN_DRV_IMP_CLK, &i_target_mba, l_attr_eff_cen_drv_imp_clk); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_CEN_DRV_IMP_SPCKE, &i_target_mba, l_attr_eff_cen_drv_imp_spcke); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_CEN_SLEW_RATE_DQ_DQS, &i_target_mba, l_attr_eff_cen_slew_rate_dq_dqs); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_CEN_SLEW_RATE_CNTL, &i_target_mba, l_attr_eff_cen_slew_rate_cntl); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_CEN_SLEW_RATE_ADDR, &i_target_mba, l_attr_eff_cen_slew_rate_addr); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_CEN_SLEW_RATE_CLK, &i_target_mba, l_attr_eff_cen_slew_rate_clk); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_CEN_SLEW_RATE_SPCKE, &i_target_mba, l_attr_eff_cen_slew_rate_spcke); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_DRAM_RON, &i_target_mba, l_attr_eff_dram_ron); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_DRAM_RTT_NOM, &i_target_mba, l_attr_eff_dram_rtt_nom); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_DRAM_RTT_WR, &i_target_mba, l_attr_eff_dram_rtt_wr); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_ODT_RD, &i_target_mba, l_attr_eff_odt_rd); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_ODT_WR, &i_target_mba, l_attr_eff_odt_wr); if(rc) return rc;
+
+ if(l_attr_is_simulation || 1) {
+ FAPI_INF("In Sim Detected %s on %s value is %d", PROCEDURE_NAME, i_target_mba.toEcmdString(), l_attr_is_simulation);
+
+ for(int i=0;i<2;i++) {
+ l_attr_eff_cen_phase_rot[0][i]=0;
+ l_attr_eff_cen_phase_rot[1][i]=0;
+ l_attr_eff_cen_phase_rot[2][i]=0;
+ l_attr_eff_cen_phase_rot[3][i]=0;
+ l_attr_eff_cen_phase_rot[4][i]=0;
+ l_attr_eff_cen_phase_rot[5][i]=0;
+ l_attr_eff_cen_phase_rot[6][i]=0;
+ l_attr_eff_cen_phase_rot[7][i]=0;
+ l_attr_eff_cen_phase_rot[8][i]=0;
+ l_attr_eff_cen_phase_rot[9][i]=0;
+ l_attr_eff_cen_phase_rot[10][i]=0;
+ l_attr_eff_cen_phase_rot[11][i]=0;
+ l_attr_eff_cen_phase_rot[12][i]=0;
+ l_attr_eff_cen_phase_rot[13][i]=0;
+ l_attr_eff_cen_phase_rot[14][i]=0;
+ l_attr_eff_cen_phase_rot[15][i]=0;
+ l_attr_eff_cen_phase_rot[16][i]=0;
+ l_attr_eff_cen_phase_rot[17][i]=0;
+ l_attr_eff_cen_phase_rot[18][i]=0;
+ l_attr_eff_cen_phase_rot[19][i]=0;
+ l_attr_eff_cen_phase_rot[20][i]=0;
+ l_attr_eff_cen_phase_rot[21][i]=0;
+ l_attr_eff_cen_phase_rot[22][i]=0;
+ l_attr_eff_cen_phase_rot[23][i]=0;
+ l_attr_eff_cen_phase_rot[24][i]=0;
+ l_attr_eff_cen_phase_rot[25][i]=0;
+ l_attr_eff_cen_phase_rot[26][i]=0;
+ l_attr_eff_cen_phase_rot[27][i]=0;
+ l_attr_eff_cen_phase_rot[28][i]=0;
+ l_attr_eff_cen_phase_rot[29][i]=0;
+ l_attr_eff_cen_phase_rot[30][i]=0;
+ l_attr_eff_cen_phase_rot[31][i]=0;
+ l_attr_eff_cen_phase_rot[32][i]=0;
+ l_attr_eff_cen_phase_rot[33][i]=0;
+ l_attr_eff_cen_phase_rot[34][i]=0;
+ l_attr_eff_cen_phase_rot[35][i]=0;
+ l_attr_eff_cen_phase_rot[36][i]=0;
+ l_attr_eff_cen_phase_rot[37][i]=0;
+ l_attr_eff_cen_phase_rot[38][i]=0;
+ l_attr_eff_cen_phase_rot[39][i]=0;
+ l_attr_eff_cen_phase_rot[40][i]=0;
+ l_attr_eff_cen_phase_rot[41][i]=0;
+ l_attr_eff_cen_phase_rot[42][i]=0;
+ l_attr_eff_cen_phase_rot[43][i]=0;
+ l_attr_eff_cen_phase_rot[44][i]=0;
+ l_attr_eff_cen_phase_rot[45][i]=0;
+ l_attr_eff_cen_phase_rot[46][i]=0;
+ l_attr_eff_cen_phase_rot[47][i]=0;
+ }
+ }
+
+
+ rc = FAPI_ATTR_SET(ATTR_EFF_CEN_PHASE_ROT_M0_CLK_P0, &i_target_mba, l_attr_eff_cen_phase_rot[0]); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_CEN_PHASE_ROT_M0_CLK_P1, &i_target_mba, l_attr_eff_cen_phase_rot[1]); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_CEN_PHASE_ROT_M1_CLK_P0, &i_target_mba, l_attr_eff_cen_phase_rot[2]); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_CEN_PHASE_ROT_M1_CLK_P1, &i_target_mba, l_attr_eff_cen_phase_rot[3]); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_CEN_PHASE_ROT_M_CMD_A0, &i_target_mba, l_attr_eff_cen_phase_rot[4]); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_CEN_PHASE_ROT_M_CMD_A1, &i_target_mba, l_attr_eff_cen_phase_rot[5]); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_CEN_PHASE_ROT_M_CMD_A2, &i_target_mba, l_attr_eff_cen_phase_rot[6]); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_CEN_PHASE_ROT_M_CMD_A3, &i_target_mba, l_attr_eff_cen_phase_rot[7]); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_CEN_PHASE_ROT_M_CMD_A4, &i_target_mba, l_attr_eff_cen_phase_rot[8]); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_CEN_PHASE_ROT_M_CMD_A5, &i_target_mba, l_attr_eff_cen_phase_rot[9]); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_CEN_PHASE_ROT_M_CMD_A6, &i_target_mba, l_attr_eff_cen_phase_rot[10]); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_CEN_PHASE_ROT_M_CMD_A7, &i_target_mba, l_attr_eff_cen_phase_rot[11]); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_CEN_PHASE_ROT_M_CMD_A8, &i_target_mba, l_attr_eff_cen_phase_rot[12]); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_CEN_PHASE_ROT_M_CMD_A9, &i_target_mba, l_attr_eff_cen_phase_rot[13]); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_CEN_PHASE_ROT_M_CMD_A10, &i_target_mba, l_attr_eff_cen_phase_rot[14]); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_CEN_PHASE_ROT_M_CMD_A11, &i_target_mba, l_attr_eff_cen_phase_rot[15]); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_CEN_PHASE_ROT_M_CMD_A12, &i_target_mba, l_attr_eff_cen_phase_rot[16]); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_CEN_PHASE_ROT_M_CMD_A13, &i_target_mba, l_attr_eff_cen_phase_rot[17]); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_CEN_PHASE_ROT_M_CMD_A14, &i_target_mba, l_attr_eff_cen_phase_rot[18]); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_CEN_PHASE_ROT_M_CMD_A15, &i_target_mba, l_attr_eff_cen_phase_rot[19]); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_CEN_PHASE_ROT_M_CMD_BA0, &i_target_mba, l_attr_eff_cen_phase_rot[20]); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_CEN_PHASE_ROT_M_CMD_BA1, &i_target_mba, l_attr_eff_cen_phase_rot[21]); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_CEN_PHASE_ROT_M_CMD_BA2, &i_target_mba, l_attr_eff_cen_phase_rot[22]); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_CEN_PHASE_ROT_M_CMD_CASN, &i_target_mba, l_attr_eff_cen_phase_rot[23]); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_CEN_PHASE_ROT_M_CMD_RASN, &i_target_mba, l_attr_eff_cen_phase_rot[24]); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_CEN_PHASE_ROT_M_CMD_WEN, &i_target_mba, l_attr_eff_cen_phase_rot[25]); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_CEN_PHASE_ROT_M_PAR, &i_target_mba, l_attr_eff_cen_phase_rot[26]); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_CEN_PHASE_ROT_M_ACTN, &i_target_mba, l_attr_eff_cen_phase_rot[27]); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_CEN_PHASE_ROT_M0_CNTL_CKE0, &i_target_mba, l_attr_eff_cen_phase_rot[28]); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_CEN_PHASE_ROT_M0_CNTL_CKE1, &i_target_mba, l_attr_eff_cen_phase_rot[29]); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_CEN_PHASE_ROT_M0_CNTL_CKE2, &i_target_mba, l_attr_eff_cen_phase_rot[30]); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_CEN_PHASE_ROT_M0_CNTL_CKE3, &i_target_mba, l_attr_eff_cen_phase_rot[31]); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_CEN_PHASE_ROT_M0_CNTL_CSN0, &i_target_mba, l_attr_eff_cen_phase_rot[32]); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_CEN_PHASE_ROT_M0_CNTL_CSN1, &i_target_mba, l_attr_eff_cen_phase_rot[33]); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_CEN_PHASE_ROT_M0_CNTL_CSN2, &i_target_mba, l_attr_eff_cen_phase_rot[34]); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_CEN_PHASE_ROT_M0_CNTL_CSN3, &i_target_mba, l_attr_eff_cen_phase_rot[35]); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_CEN_PHASE_ROT_M0_CNTL_ODT0, &i_target_mba, l_attr_eff_cen_phase_rot[36]); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_CEN_PHASE_ROT_M0_CNTL_ODT1, &i_target_mba, l_attr_eff_cen_phase_rot[37]); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_CEN_PHASE_ROT_M1_CNTL_CKE0, &i_target_mba, l_attr_eff_cen_phase_rot[38]); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_CEN_PHASE_ROT_M1_CNTL_CKE1, &i_target_mba, l_attr_eff_cen_phase_rot[39]); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_CEN_PHASE_ROT_M1_CNTL_CKE2, &i_target_mba, l_attr_eff_cen_phase_rot[40]); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_CEN_PHASE_ROT_M1_CNTL_CKE3, &i_target_mba, l_attr_eff_cen_phase_rot[41]); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_CEN_PHASE_ROT_M1_CNTL_CSN0, &i_target_mba, l_attr_eff_cen_phase_rot[42]); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_CEN_PHASE_ROT_M1_CNTL_CSN1, &i_target_mba, l_attr_eff_cen_phase_rot[43]); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_CEN_PHASE_ROT_M1_CNTL_CSN2, &i_target_mba, l_attr_eff_cen_phase_rot[44]); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_CEN_PHASE_ROT_M1_CNTL_CSN3, &i_target_mba, l_attr_eff_cen_phase_rot[45]); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_CEN_PHASE_ROT_M1_CNTL_ODT0, &i_target_mba, l_attr_eff_cen_phase_rot[46]); if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_EFF_CEN_PHASE_ROT_M1_CNTL_ODT1, &i_target_mba, l_attr_eff_cen_phase_rot[47]); if(rc) 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_config/mss_eff_config_thermal.C b/src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_eff_config_thermal.C
index e8c23eda6..30a69e334 100644
--- a/src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_eff_config_thermal.C
+++ b/src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_eff_config_thermal.C
@@ -20,7 +20,7 @@
/* Origin: 30 */
/* */
/* IBM_PROLOG_END_TAG */
-// $Id: mss_eff_config_thermal.C,v 1.8 2012/06/13 20:53:57 pardeik Exp $
+// $Id: mss_eff_config_thermal.C,v 1.13 2012/11/28 21:33:11 pardeik Exp $
// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/centaur/working/procedures/ipl/fapi/mss_eff_config_thermal.C,v $
//------------------------------------------------------------------------------
// *! (C) Copyright International Business Machines Corp. 2011
@@ -33,15 +33,15 @@
// *! BACKUP NAME : Michael Pardeik Email: pardeik@us.ibm.com
// *! ADDITIONAL COMMENTS :
//
+// applicable CQ component memory_screen
+//
// DESCRIPTION:
// The purpose of this procedure is to set the default throttle and power attributes for dimms in a given system
-// -- The throttles here are intended to be the thermal runtime throttles for dimm/channel N/M
// -- The power attributes are the slope/intercept values. Note that these values are in cW.
// -- The power values are determined by DRAM Generation and Width (with various uplifts/adders applied)
-// and will be derived from the model and then verified with hardware measurements
// -- Power will be per rank for a given dram generation and width
// -- Uplifts will be applied for dimm type, number of ranks
-// -- Thermal values are system dependent and will need to come from the machine readable workbook
+// -- The throttle attributes will setup values for safemode and runtime
//
//
//------------------------------------------------------------------------------
@@ -51,6 +51,11 @@
//------------------------------------------------------------------------------
// Version:| Author: | Date: | Comment:
//---------|----------|---------|-----------------------------------------------
+// 1.13 | pardeik |28-NOV-12| fixed hostboot compile errors
+// 1.12 | pardeik |07-NOV-12| updated to use new SI attributes and their enums
+// 1.11 | pardeik |22-OCT-12| Use the schmoo attributes to find wc termination, updated hwp errors, removed unneeded variables, added CQ component comment line, updated safemode throttle default values
+// 1.10 | pardeik |19-OCT-12| Enable TYPE_1D for ODT mapping. Set ISDIMM supplier power curve to master power curve
+// 1.9 | pardeik |11-OCT-12| updated to use new attributes, termination power calculation added in
// 1.8 | pardeik |13-JUN-12| Major rewrite to have dimm power determined by dram generation and width, with uplifts applied (not based on dimm size lookup table any longer)
// 1.7 | pardeik |04-MAY-12| removed typedef from structures, use fapi to define dimm type enums
// 1.6 | pardeik |10-APR-12| update cdimm power/int default, change power_thermal_values_t to use int32_t instead of uint32_t in order to identify a negative value correctly, added dimm config to the messages printed out
@@ -61,28 +66,99 @@
// 1.2 | asaetow |03-NOV-11| Changed format of file and made function lower case.
// 1.1 | pardeik |01-NOV-11| First Draft.
+/*
+TODO ITEMS:
+
+Waiting for platinit attributes to enable sections in this procedure:
+1. Power Curves to originate from CDIMM VPD (platinit)
+2. Thermal memory power limit from MRW (platinit)
+3. Safemode throttles from MRW (platinit)
+4. ATTR_EFF_CEN_DRV_IMP_DQ_DQS_SCHMOO and ATTR_EFF_CEN_RCV_IMP_DQ_DQS_SCHMOO enable sections of this procedure when they are used
+5. Need runtime throttles non-volatile and initialized to zero by firmware on the first IPL
+6. Error callouts
+
+*/
-//----------------------------------------------------------------------
+//------------------------------------------------------------------------------
+// My Includes
+//------------------------------------------------------------------------------
+#include <mss_eff_config_thermal.H>
+#include <mss_bulk_pwr_throttles.H>
+
+//------------------------------------------------------------------------------
// Includes
-//----------------------------------------------------------------------
+//------------------------------------------------------------------------------
#include <fapi.H>
-#include <mss_eff_config_thermal.H>
+
+//------------------------------------------------------------------------------
+// Constants
+//------------------------------------------------------------------------------
+const uint8_t NUM_PORTS = 2; // number of ports per MBA
+const uint8_t NUM_DIMMS = 2; // number of dimms per MBA port
+const uint8_t NUM_RANKS = 4; // number of ranks per dimm
+const uint32_t ISDIMM_POWER_SLOPE_DEFAULT = 940; // default power slope (cW/utilization)
+const uint32_t ISDIMM_POWER_INT_DEFAULT = 900; // default power intercept (cW)
+const uint32_t CDIMM_POWER_SLOPE_DEFAULT = 0x8240; // default power slope (cW/utilization)
+const uint32_t CDIMM_POWER_INT_DEFAULT = 0x80CE; // default power intercept (cW)
+const uint8_t IDLE_DIMM_UTILIZATION = 0; // DRAM data bus utilization percent for the idle power defined in table below - needs to be 0
+const uint8_t ACTIVE_DIMM_UTILIZATION = 70; // DRAM data bus utilization percent for the active power defined in table below (reads+writes)
+const uint8_t DATA_BUS_READ_PERCENT = 66; // read percentage of data bus
+const uint8_t DATA_BUS_WRITE_PERCENT = 34; // write percentage of data bus
+
extern "C" {
using namespace fapi;
-// Procedures in this file
- fapi::ReturnCode mss_eff_config_thermal(const fapi::Target & i_target);
+//------------------------------------------------------------------------------
+// Funtions in this file
+//------------------------------------------------------------------------------
+ fapi::ReturnCode mss_eff_config_thermal(const fapi::Target & i_target_mba);
+
+ fapi::ReturnCode mss_eff_config_thermal_term(
+ const char nom_or_wc_term[4],
+ uint8_t i_port,
+ uint8_t i_dimm,
+ uint8_t i_rank,
+ uint32_t i_dimm_voltage,
+ uint8_t i_dram_width,
+ uint8_t i_dram_tdqs,
+ uint8_t i_ibm_type[NUM_PORTS][NUM_DIMMS],
+ uint8_t i_dimm_ranks_configed_array[NUM_PORTS][NUM_DIMMS],
+ uint8_t i_dimm_dram_ron[NUM_PORTS][NUM_DIMMS],
+ uint8_t i_dimm_rank_odt_rd[NUM_PORTS][NUM_DIMMS][NUM_RANKS],
+ uint8_t i_dimm_rank_odt_wr[NUM_PORTS][NUM_DIMMS][NUM_RANKS],
+ uint8_t i_dram_rtt_nom[NUM_PORTS][NUM_DIMMS][NUM_RANKS],
+ uint8_t i_dram_rtt_wr[NUM_PORTS][NUM_DIMMS][NUM_RANKS],
+ uint8_t i_cen_dq_dqs_rcv_imp[NUM_PORTS],
+ uint8_t i_cen_dq_dqs_drv_imp[NUM_PORTS],
+ float &o_dimm_power_adder_termination
+ );
-//******************************************************************************
-//
-//******************************************************************************
+ fapi::ReturnCode mss_eff_config_thermal_get_wc_term(
+ const fapi::Target &i_target_mba,
+ uint8_t i_port,
+ uint8_t &o_cen_dq_dqs_rcv_imp_wc,
+ uint8_t &o_cen_dq_dqs_drv_imp_wc
+ );
- fapi::ReturnCode mss_eff_config_thermal(const fapi::Target & i_target)
+ fapi::ReturnCode mss_eff_config_thermal_get_cen_drv_value(
+ uint8_t i_cen_dq_dqs_drv_imp,
+ uint8_t &o_cen_dq_dqs_drv_imp
+ );
+
+//------------------------------------------------------------------------------
+// @brief mss_eff_config_thermal(): This function determines the power and throttle attribute values to use
+//
+// @param const fapi::Target & i_target_mba: MBA Target passed in
+//
+// @return fapi::ReturnCode
+//------------------------------------------------------------------------------
+
+ fapi::ReturnCode mss_eff_config_thermal(const fapi::Target & i_target_mba)
{
- fapi::ReturnCode l_rc;
+ fapi::ReturnCode rc = fapi::FAPI_RC_SUCCESS;
char procedure_name[32];
sprintf(procedure_name, "mss_eff_config_thermal");
@@ -105,281 +181,1214 @@ extern "C" {
struct dimm_power_t
{
uint32_t idle;
- uint32_t max;
+ uint32_t active;
};
struct dimm_type_t
{
int32_t udimm;
int32_t lrdimm;
int32_t rdimm;
- int32_t cdimm;
- };
- struct dimm_voltage_t
- {
- int8_t volt1500;
- int8_t volt1350;
- int8_t volt1200;
- };
- struct dimm_frequency_t
- {
- int8_t freq1066;
- int8_t freq1333;
- int8_t freq1600;
};
struct power_data_t
{
uint8_t dram_generation;
uint8_t dram_width;
uint8_t dimm_ranks;
- dimm_power_t rank_master_power;
+ dimm_power_t rank_power;
dimm_type_t dimm_type_adder;
- dimm_power_t rank_slave_adder;
- dimm_voltage_t dimm_voltage_adder;
- dimm_frequency_t dimm_frequency_adder;
+ int32_t dimm_voltage_base;
+ int32_t dimm_frequency_base;
};
-power_data_t l_power_table[] =
-{
-// Master Ranks column uses the values in the same table entry for the number of master ranks specified. Default is to have it use same power for each master rank, so that is why master ranks = 1. If we need to separate power based on number of master ranks, then have the table setup for descending master rank values. We always need an entry for master ranks of 1. Table lookup will stop after first matching entry is found (DRAM Generation, DRAM Width, and Master Ranks = l_dimm_master_ranks_array OR 1)
-//
-// Note: Slave rank full bw is set to idle, since the active power for full bw will be acounted for the master rank (ie. only one rank active at a time). Set slave rank full bw to the slave rank idle bw power value.
+// Master Ranks column uses the values in the same table entry for the number of master ranks specified. Default is to have it use same power for each master rank, so that is why master ranks = 1. If we need to separate power based on number of master ranks, then have the table setup for descending master rank values. We always need an entry for master ranks of 1. Table lookup will stop after first matching entry is found (DRAM Generation, DRAM Width, and Master Ranks = dimm_master_ranks_array OR 1)
//
-// DRAM DRAM Master MasterRankPower DIMMTypeAdder SlaveRankAdder VoltageAdder FrequencyAdder
-// Generation Width Ranks (cW) (cW) (cW) (%) (%)
-// DDR3 X4 1 idle,full UDIMM,LRDIMM, idle,full 1.5,1.35,1.2 1066,1333,1600
-// or or RDIMM,CDIMM
-// DDR4 X8
+// DRAM DRAM Master RankPower DIMMTypeAdder BaseVoltage BaseFrequency
+// GenerationWidth Ranks (cW) (cW) (mV) (MHz)
+// DDR3 X4 1 idle,full UDIMM,LRDIMM, 1500,1350,1200 1066,1333,1600
+// or or RDIMM for values in for values in
+// DDR4 X8 this table this table
//
+ power_data_t power_table[] =
+ {
+ { DDR3, X4, 1, { 70,373}, {0,93,104}, 1350, 1066 },
+ { DDR3, X8, 1, { 52,300}, {0,93,104}, 1350, 1066 },
+ { DDR4, X4, 1, { 70,373}, {0,93,104}, 1350, 1066 },
+ { DDR4, X8, 1, { 52,300}, {0,93,104}, 1350, 1066 },
+ };
+
-// TODO: Finalize these values against model. These are just place holders for now and will work for the time being.
- { DDR3, X4, 1, { 65,650}, {0,50,100,0}, { 65,65}, {10,0,-10}, {0,10,20} },
- { DDR3, X8, 1, { 50,500}, {0,50,100,0}, { 50,50}, {10,0,-10}, {0,10,20} },
- { DDR4, X4, 1, { 65,650}, {0,50,100,0}, { 65,65}, {10,0,-10}, {0,10,20} },
- { DDR4, X8, 1, { 50,500}, {0,50,100,0}, { 50,50}, {10,0,-10}, {0,10,20} },
-};
-
-// Default values defined here
- const uint8_t l_num_ports = 2; // number of ports per MBA
- const uint8_t l_num_dimms = 2; // number of dimms per MBA port
- const uint32_t l_dimm_power_slope_default = 940; // default power slope (cW/utilization)
- const uint32_t l_dimm_power_int_default = 900; // default power intercept (cW)
- const uint32_t l_dimm_throttle_n_default = 100; // default dimm throttle numerator
- const uint32_t l_dimm_throttle_d_default = 100; // default dimm throttle denominator
- const uint32_t l_channel_throttle_n_default = 100; // default channel throttle numerator
- const uint32_t l_channel_throttle_d_default = 100; // default channel throttle denominator
- const uint8_t l_idle_dimm_utilization = 0; // DRAM data bus utilization for the idle power defined in table below
- const uint8_t l_max_dimm_utilization = 100; // DRAM data bus utilization for the active power defined in table below
-
-// other variables used in this procedure
- fapi::Target l_targetCentaur;
- std::vector<fapi::Target> l_targetDimm;
+// other variables used in this function
+ fapi::Target target_chip;
+ std::vector<fapi::Target> target_mba_array;
+ std::vector<fapi::Target> target_dimm_array;
uint8_t port;
uint8_t dimm;
+ uint8_t rank;
uint8_t entry;
- uint8_t l_dimm_type;
- uint8_t l_dimm_ranks_array[l_num_ports][l_num_dimms];
- uint32_t l_list_sz;
- uint32_t l_power_slope_array[l_num_ports][l_num_dimms];
- uint32_t l_power_int_array[l_num_ports][l_num_dimms];
- uint32_t l_dimm_throttle_n_array[l_num_ports][l_num_dimms];
- uint32_t l_dimm_throttle_d_array[l_num_ports][l_num_dimms];
- uint32_t l_channel_throttle_n_array[l_num_ports];
- uint32_t l_channel_throttle_d_array[l_num_ports];
- uint8_t l_found_entry_in_table;
- uint8_t l_dram_width;
- uint8_t l_dram_gen;
- uint32_t l_dimm_voltage;
- uint32_t l_dimm_frequency;
- uint8_t l_dimm_ranks_configed_array[l_num_ports][l_num_dimms];
- uint8_t l_dimm_master_ranks_array[l_num_ports][l_num_dimms];
- int32_t l_dimm_power_adder_type;
- int8_t l_dimm_power_adder_volt;
- int8_t l_dimm_power_adder_freq;
- uint32_t l_dimm_idle_power_adder_slave;
- uint32_t l_dimm_max_power_adder_slave;
- int32_t l_dimm_idle_power;
- int32_t l_dimm_max_power;
- uint8_t l_dimm_num_slave_ranks;
-
- l_list_sz = (sizeof(l_power_table))/(sizeof(power_data_t));
+ uint8_t dimm_type;
+ uint8_t dimm_ranks_array[NUM_PORTS][NUM_DIMMS];
+ uint32_t power_table_size;
+ uint32_t power_slope_array[NUM_PORTS][NUM_DIMMS];
+ uint32_t power_int_array[NUM_PORTS][NUM_DIMMS];
+ uint32_t power_slope2_array[NUM_PORTS][NUM_DIMMS];
+ uint32_t power_int2_array[NUM_PORTS][NUM_DIMMS];
+ uint8_t found_entry_in_table;
+ uint8_t dram_width;
+ uint8_t dram_tdqs;
+ uint8_t dram_gen;
+ uint32_t dimm_voltage;
+ uint32_t dimm_frequency;
+ uint8_t dimm_ranks_configed_array[NUM_PORTS][NUM_DIMMS];
+ uint8_t dimm_master_ranks_array[NUM_PORTS][NUM_DIMMS];
+ int32_t dimm_power_adder_type;
+ float dimm_power_multiplier_volt;
+ float dimm_power_mulitiplier_freq;
+ float dimm_idle_power;
+ float dimm_active_power;
+ float dimm_power_adder_termination;
+ float dimm_power_adder_termination_largest = 0;
+ uint8_t dimm_rank_odt_rd[NUM_PORTS][NUM_DIMMS][NUM_RANKS];
+ uint8_t dimm_rank_odt_wr[NUM_PORTS][NUM_DIMMS][NUM_RANKS];
+ uint8_t dimm_dram_ron[NUM_PORTS][NUM_DIMMS];
+ uint8_t cen_dq_dqs_rcv_imp[NUM_PORTS];
+ uint8_t cen_dq_dqs_drv_imp[NUM_PORTS];
+ float dimm_power_adder_termination_wc;
+ float dimm_power_adder_termination_largest_wc = 0;
+ uint8_t cen_dq_dqs_rcv_imp_wc[NUM_PORTS];
+ uint8_t cen_dq_dqs_drv_imp_wc[NUM_PORTS];
+ uint8_t num_dimms_on_port;
+ uint32_t throttle_n_per_mba;
+ uint32_t throttle_n_per_chip;
+ uint32_t throttle_d;
+ uint32_t runtime_throttle_n_per_mba;
+ uint32_t runtime_throttle_n_per_chip;
+ uint32_t runtime_throttle_d;
+ uint8_t dram_rtt_nom[NUM_PORTS][NUM_DIMMS][NUM_RANKS];
+ uint8_t dram_rtt_wr[NUM_PORTS][NUM_DIMMS][NUM_RANKS];
+ uint8_t ibm_type[NUM_PORTS][NUM_DIMMS];
+ char dram_gen_str[4];
+ uint32_t dimm_thermal_power_limit;
+ uint32_t channel_pair_thermal_power_limit;
+ uint8_t num_mba_with_dimms = 0;
+ uint8_t mba_index;
+ uint8_t dimm_number_registers[NUM_PORTS][NUM_DIMMS];
+ uint8_t dimm_index;
+ uint32_t cdimm_master_power_slope;
+ uint32_t cdimm_master_power_intercept;
+ uint32_t cdimm_supplier_power_slope;
+ uint32_t cdimm_supplier_power_intercept;
+ uint32_t safemode_throttle_n_per_mba;
+ uint32_t safemode_throttle_n_per_chip;
+ uint32_t safemode_throttle_d;
+
+ power_table_size = (sizeof(power_table))/(sizeof(power_data_t));
// Get input attributes
- l_rc = FAPI_ATTR_GET(ATTR_EFF_DRAM_GEN, &i_target, l_dram_gen);
- if(l_rc) return l_rc;
- l_rc = FAPI_ATTR_GET(ATTR_EFF_DIMM_TYPE, &i_target, l_dimm_type);
- if(l_rc) return l_rc;
- l_rc = FAPI_ATTR_GET(ATTR_EFF_DRAM_WIDTH, &i_target, l_dram_width);
- if(l_rc) return l_rc;
- l_rc = FAPI_ATTR_GET(ATTR_EFF_NUM_RANKS_PER_DIMM, &i_target, l_dimm_ranks_array);
- if(l_rc) return l_rc;
- l_rc = FAPI_ATTR_GET(ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM, &i_target, l_dimm_master_ranks_array);
- if(l_rc) return l_rc;
- l_rc = FAPI_ATTR_GET(ATTR_EFF_DIMM_RANKS_CONFIGED, &i_target, l_dimm_ranks_configed_array);
- if(l_rc) return l_rc;
-// TODO: Get Attributes for number of registers on ISDIMM and Termination settings being used
+ rc = FAPI_ATTR_GET(ATTR_EFF_DRAM_GEN, &i_target_mba, dram_gen);
+ if(rc) return rc;
+ rc = FAPI_ATTR_GET(ATTR_EFF_DIMM_TYPE, &i_target_mba, dimm_type);
+ if(rc) return rc;
+ rc = FAPI_ATTR_GET(ATTR_EFF_DRAM_WIDTH, &i_target_mba, dram_width);
+ if(rc) return rc;
+ rc = FAPI_ATTR_GET(ATTR_EFF_DRAM_TDQS, &i_target_mba, dram_tdqs);
+ if(rc) return rc;
+ rc = FAPI_ATTR_GET(ATTR_EFF_NUM_RANKS_PER_DIMM, &i_target_mba, dimm_ranks_array);
+ if(rc) return rc;
+ rc = FAPI_ATTR_GET(ATTR_EFF_NUM_MASTER_RANKS_PER_DIMM, &i_target_mba, dimm_master_ranks_array);
+ if(rc) return rc;
+ rc = FAPI_ATTR_GET(ATTR_EFF_DIMM_RANKS_CONFIGED, &i_target_mba, dimm_ranks_configed_array);
+ if(rc) return rc;
+ rc = FAPI_ATTR_GET(ATTR_EFF_DRAM_RON, &i_target_mba, dimm_dram_ron);
+ if(rc) return rc;
+ rc = FAPI_ATTR_GET(ATTR_EFF_ODT_RD, &i_target_mba, dimm_rank_odt_rd);
+ if(rc) return rc;
+ rc = FAPI_ATTR_GET(ATTR_EFF_ODT_WR, &i_target_mba, dimm_rank_odt_wr);
+ if(rc) return rc;
+ rc = FAPI_ATTR_GET(ATTR_EFF_CEN_RCV_IMP_DQ_DQS, &i_target_mba, cen_dq_dqs_rcv_imp);
+ if(rc) return rc;
+ rc = FAPI_ATTR_GET(ATTR_EFF_CEN_DRV_IMP_DQ_DQS, &i_target_mba, cen_dq_dqs_drv_imp);
+ if(rc) return rc;
+ rc = FAPI_ATTR_GET(ATTR_EFF_DRAM_RTT_NOM, &i_target_mba, dram_rtt_nom);
+ if(rc) return rc;
+ rc = FAPI_ATTR_GET(ATTR_EFF_DRAM_RTT_WR, &i_target_mba, dram_rtt_wr);
+ if(rc) return rc;
+ rc = FAPI_ATTR_GET(ATTR_EFF_IBM_TYPE, &i_target_mba, ibm_type);
+ if(rc) return rc;
+ rc = FAPI_ATTR_GET(ATTR_EFF_NUM_DROPS_PER_PORT, &i_target_mba, num_dimms_on_port);
+ if(rc) return rc;
+// TODO: use vpd values when power curve data is available from CDIMM VPD (platinit), remove hardcoding
+ cdimm_master_power_slope = CDIMM_POWER_SLOPE_DEFAULT;
+ cdimm_master_power_intercept = CDIMM_POWER_INT_DEFAULT;
+ cdimm_supplier_power_slope = CDIMM_POWER_SLOPE_DEFAULT;
+ cdimm_supplier_power_intercept = CDIMM_POWER_INT_DEFAULT;
+// rc = FAPI_ATTR_GET(ATTR_SPD_CDIMM_MASTER_POWER_SLOPE, &i_target_mba, cdimm_master_power_slope);
+// if(rc) return rc;
+// rc = FAPI_ATTR_GET(ATTR_SPD_CDIMM_MASTER_POWER_INTERCEPT, &i_target_mba, cdimm_master_power_intercept);
+// if(rc) return rc;
+// rc = FAPI_ATTR_GET(ATTR_SPD_CDIMM_SUPPLIER_POWER_SLOPE, &i_target_mba, cdimm_supplier_power_slope);
+// if(rc) return rc;
+// rc = FAPI_ATTR_GET(ATTR_SPD_CDIMM_SUPPLIER_POWER_INTERCEPT, &i_target_mba, cdimm_supplier_power_intercept);
+// if(rc) return rc;
+// TODO: Get Safemode throttles from MRW (platinit), hardcode until available - Keep here until cronus is able to set runtime memory throttles at the end of istep
+ safemode_throttle_n_per_mba = 96;
+// safemode_throttle_n_per_chip = 32;
+ safemode_throttle_n_per_chip = 96;
+ safemode_throttle_d = 512;
+// rc = FAPI_ATTR_GET(ATTR_MRW_SAFEMODE_MEM_THROTTLE_NUMERATOR_PER_MBA, &i_target_mba, safemode_throttle_n_per_mba);
+// if(rc) return rc;
+// rc = FAPI_ATTR_GET(ATTR_MRW_SAFEMODE_MEM_THROTTLE_NUMERATOR_PER_CHIP, &i_target_mba, safemode_throttle_n_per_chip);
+// if(rc) return rc;
+// rc = FAPI_ATTR_GET(ATTR_MRW_SAFEMODE_MEM_THROTTLE_DENOMINATOR, &i_target_mba, safemode_throttle_d);
+// if(rc) return rc;
+// TODO: Get Thermal power Limit from MRW (platinit), hardcode until available
+ if (dimm_type == CDIMM)
+ {
+ dimm_thermal_power_limit = 5000; // in cW, per CDIMM, high limit
+// dimm_thermal_power_limit = 2500; // in cW, per CDIMM
+ }
+ else
+ {
+ dimm_thermal_power_limit = 2000; // in cW, per ISDIMM, high limit
+// dimm_thermal_power_limit = 600; // in cW, per ISDIMM
+ }
+// rc = FAPI_ATTR_GET(ATTR_MRW_THERMAL_MEMORY_POWER_LIMIT, &i_target_mba, dimm_thermal_power_limit);
+// if(rc) return rc;
+
// Get Centaur target for the given MBA
+ rc = fapiGetParentChip(i_target_mba, target_chip);
+ if(rc) return rc;
// Get voltage and frequency attributes
- l_rc = fapiGetParentChip(i_target, l_targetCentaur);
- if(l_rc)
+ rc = FAPI_ATTR_GET(ATTR_MSS_VOLT, &target_chip, dimm_voltage);
+ if(rc) return rc;
+ rc = FAPI_ATTR_GET(ATTR_MSS_FREQ, &target_chip, dimm_frequency);
+ if(rc) return rc;
+
+// get any attributes from DIMM SPD
+ if (dimm_type != CDIMM)
{
- FAPI_ERR("Error getting Centaur parent target for the given MBA");
- return l_rc;
+ rc = fapiGetAssociatedDimms(i_target_mba, target_dimm_array, fapi::TARGET_STATE_PRESENT);
+ if(rc) return rc;
+ for (dimm_index=0; dimm_index < target_dimm_array.size(); dimm_index++)
+ {
+ rc = FAPI_ATTR_GET(ATTR_MBA_PORT, &target_dimm_array[dimm_index], port);
+ if(rc) return rc;
+ rc = FAPI_ATTR_GET(ATTR_MBA_DIMM, &target_dimm_array[dimm_index], dimm);
+ if(rc) return rc;
+ rc = FAPI_ATTR_GET(ATTR_SPD_NUM_OF_REGISTERS_USED_ON_RDIMM, &target_dimm_array[dimm_index], dimm_number_registers[port][dimm]);
+ if(rc) return rc;
+ }
}
- l_rc = FAPI_ATTR_GET(ATTR_MSS_VOLT, &l_targetCentaur, l_dimm_voltage);
- if(l_rc) return l_rc;
- l_rc = FAPI_ATTR_GET(ATTR_MSS_FREQ, &l_targetCentaur, l_dimm_frequency);
- if(l_rc) return l_rc;
+// Get number of Centaur MBAs that have dimms present
+ if (dimm_type == CDIMM)
+ {
+ rc = fapiGetChildChiplets(target_chip, fapi::TARGET_TYPE_MBA_CHIPLET, target_mba_array, fapi::TARGET_STATE_PRESENT);
+ if(rc) return rc;
+ num_mba_with_dimms = 0;
+ for (mba_index=0; mba_index < target_mba_array.size(); mba_index++)
+ {
+ rc = fapiGetAssociatedDimms(target_mba_array[mba_index], target_dimm_array, fapi::TARGET_STATE_PRESENT);
+ if(rc) return rc;
+ if (target_dimm_array.size() > 0)
+ {
+ num_mba_with_dimms++;
+ }
+ }
+ }
-// iterate through the MBA ports to define power and thermal attributes
- for (port=0; port < l_num_ports; port++)
+// determine worst case termination settings here for ISDIMMs (to be used later)
+ if (dimm_type != CDIMM)
{
-// initialize channel entries to zero
- l_channel_throttle_n_array[port] = 0;
- l_channel_throttle_d_array[port] = 0;
-// iterate through the dimms on each port
- for (dimm=0; dimm < l_num_dimms; dimm++)
+// get worst case termination values that will be used
+// Only look at Centaur DQ/DQS Driver and Receiver termination settings
+// Note that the DRAM rtt_nom, rtt_wr, and ron will not be allowed to change, all these will stay at the nominal settings
+ for (port=0; port < NUM_PORTS; port++)
+ {
+ rc = mss_eff_config_thermal_get_wc_term(
+ i_target_mba,
+ port,
+ cen_dq_dqs_rcv_imp_wc[port],
+ cen_dq_dqs_drv_imp_wc[port]
+ );
+ if(rc)
+ {
+ FAPI_ERR("Error (0x%x) calling mss_eff_config_thermal_get_wc_term", static_cast<uint32_t>(rc));
+ return rc;
+ }
+ }
+ }
+
+////////////////////////////////////////////////////////////////////////
+// Power Curve Determination
+////////////////////////////////////////////////////////////////////////
+// Iterate through the MBA ports to get power slope/intercept values
+ for (port=0; port < NUM_PORTS; port++)
+ {
+// Get termination power for ISDIMM
+ if (dimm_type != CDIMM)
+ {
+ dimm_power_adder_termination_largest=0;
+ dimm_power_adder_termination_largest_wc=0;
+
+// iterate through the dimms on each port to determine termination power to use
+ for (dimm=0; dimm < NUM_DIMMS; dimm++)
+ {
+// calculate the effective net termination for each rank
+ for (rank=0; rank < NUM_RANKS; rank++)
+ {
+// nominal termination
+ rc = mss_eff_config_thermal_term(
+ "NOM",
+ port,
+ dimm,
+ rank,
+ dimm_voltage,
+ dram_width,
+ dram_tdqs,
+ ibm_type,
+ dimm_ranks_configed_array,
+ dimm_dram_ron,
+ dimm_rank_odt_rd,
+ dimm_rank_odt_wr,
+ dram_rtt_nom,
+ dram_rtt_wr,
+ cen_dq_dqs_rcv_imp,
+ cen_dq_dqs_drv_imp,
+ dimm_power_adder_termination
+ );
+ if(rc)
+ {
+ FAPI_ERR("Error (0x%x) calling mss_eff_config_thermal_term", static_cast<uint32_t>(rc));
+ return rc;
+ }
+ if (dimm_power_adder_termination > dimm_power_adder_termination_largest)
+ {
+ dimm_power_adder_termination_largest = dimm_power_adder_termination;
+ }
+
+// worst case termination
+ rc = mss_eff_config_thermal_term(
+ "WC",
+ port,
+ dimm,
+ rank,
+ dimm_voltage,
+ dram_width,
+ dram_tdqs,
+ ibm_type,
+ dimm_ranks_configed_array,
+ dimm_dram_ron,
+ dimm_rank_odt_rd,
+ dimm_rank_odt_wr,
+ dram_rtt_nom,
+ dram_rtt_wr,
+ cen_dq_dqs_rcv_imp_wc,
+ cen_dq_dqs_drv_imp_wc,
+ dimm_power_adder_termination_wc
+ );
+ if(rc)
+ {
+ FAPI_ERR("Error (0x%x) calling mss_eff_config_thermal_term", static_cast<uint32_t>(rc));
+ return rc;
+ }
+ if (dimm_power_adder_termination_wc > dimm_power_adder_termination_largest_wc)
+ {
+ dimm_power_adder_termination_largest_wc = dimm_power_adder_termination_wc;
+ }
+ }
+ }
+ }
+
+// iterate through the dimms on each port again to determine power slope and intercept
+ for (dimm=0; dimm < NUM_DIMMS; dimm++)
{
// initialize dimm entries to zero
- l_dimm_throttle_n_array[port][dimm] = 0;
- l_dimm_throttle_d_array[port][dimm] = 0;
- l_power_slope_array[port][dimm] = 0;
- l_power_int_array[port][dimm] = 0;
+ power_slope_array[port][dimm] = 0;
+ power_int_array[port][dimm] = 0;
+ power_slope2_array[port][dimm] = 0;
+ power_int2_array[port][dimm] = 0;
// only update values for dimms that are physically present
- if (l_dimm_ranks_array[port][dimm] > 0)
+ if (dimm_ranks_array[port][dimm] > 0)
{
-// TODO: Placeholder for thermal attributes that will come from machine readable workbook (runtime throttles) - Hardcode these to the default values for now.
-// TODO: IPL throttles will need to be added into an initfile once available.
- l_dimm_throttle_n_array[port][dimm] = l_dimm_throttle_n_default;
- l_dimm_throttle_d_array[port][dimm] = l_dimm_throttle_d_default;
- l_channel_throttle_n_array[port] = l_channel_throttle_n_default;
- l_channel_throttle_d_array[port] = l_channel_throttle_d_default;
-
-// Get the dimm power from table and add on any adjustments (if not found in table - should never happen, then default values will be used)
- l_power_slope_array[port][dimm] = l_dimm_power_slope_default;
- l_power_int_array[port][dimm] = l_dimm_power_int_default;
- l_found_entry_in_table = 0;
- for (entry = 0; entry < l_list_sz; entry++) {
- if ((l_power_table[entry].dram_generation == l_dram_gen) && (l_power_table[entry].dram_width == l_dram_width) && ((l_power_table[entry].dimm_ranks == l_dimm_master_ranks_array[port][dimm]) || (l_power_table[entry].dimm_ranks == 1)))
+
+// CDIMM power slope/intercept will come from VPD
+// Data in VPD needs to be the power per virtual dimm on the CDIMM
+ if (dimm_type == CDIMM)
+ {
+ power_slope_array[port][dimm] = cdimm_master_power_slope;
+ power_int_array[port][dimm] = cdimm_master_power_intercept;
+ power_slope2_array[port][dimm] = cdimm_supplier_power_slope;
+ power_int2_array[port][dimm] = cdimm_supplier_power_intercept;
+
+// check to see if data is valid
+ if ((((cdimm_master_power_slope & 0x8000) != 0) && ((cdimm_master_power_intercept & 0x8000) != 0)) && (((cdimm_supplier_power_slope & 0x8000) != 0) && ((cdimm_supplier_power_intercept & 0x8000) != 0)))
{
-// get adder for dimm type
- if (l_dimm_type == UDIMM) {
- l_dimm_power_adder_type = l_power_table[entry].dimm_type_adder.udimm;
- }
- else if (l_dimm_type == LRDIMM)
+ power_slope_array[port][dimm] = cdimm_master_power_slope & 0x1FFF;
+ power_int_array[port][dimm] = cdimm_master_power_intercept & 0x1FFF;
+ power_slope2_array[port][dimm] = cdimm_supplier_power_slope & 0x1FFF;
+ power_int2_array[port][dimm] = cdimm_supplier_power_intercept & 0x1FFF;
+// check to see if data is lab data
+ if ((((cdimm_master_power_slope & 0x4000) == 0) || ((cdimm_master_power_intercept & 0x4000) == 0)) || (((cdimm_supplier_power_slope & 0x4000) == 0) || ((cdimm_supplier_power_intercept & 0x4000) == 0)))
{
- l_dimm_power_adder_type = l_power_table[entry].dimm_type_adder.lrdimm;
+//TODO: enable error reporting for this when it makes sense to do (after ship level power curve data is known), remove warning message. Log error and allow IPL to continue and use the lab data if it is there.
+ FAPI_INF("WARNING: power curve data is lab data, not ship level data");
+// FAPI_ERR("power curve data is lab data, not ship level data");
+// FAPI_SET_HWP_ERROR(rc, RC_MSS_DIMM_POWER_CURVE_DATA_LAB);
+// if (rc) fapiLogError(rc);
}
- else if (l_dimm_type == CDIMM)
- {
- l_dimm_power_adder_type = l_power_table[entry].dimm_type_adder.cdimm;
- }
- else if ( l_dimm_type == RDIMM )
- {
- l_dimm_power_adder_type = l_power_table[entry].dimm_type_adder.rdimm;
- }
- else
- {
- FAPI_ERR("UNKNOWN DIMM TYPE FOUND: ldimm_type");
- l_dimm_power_adder_type = 0;
- }
-// TODO: Use attribute for number of registers for RDIMM when available - via SPD byte 63 bits 1:0
-// TODO: Remove the double uplift below when SPD byte 63 is used
- // double the uplift for additional register if dimm has more than 2 ranks
- if ((l_dimm_master_ranks_array[port][dimm] > 2) && (l_dram_width == X4) && ((l_dimm_type == LRDIMM) || (l_dimm_type == RDIMM)))
+ }
+ else
+ {
+ power_slope_array[port][dimm] = CDIMM_POWER_SLOPE_DEFAULT;
+ power_int_array[port][dimm] = CDIMM_POWER_INT_DEFAULT;
+ power_slope2_array[port][dimm] = CDIMM_POWER_SLOPE_DEFAULT;
+ power_int2_array[port][dimm] = CDIMM_POWER_INT_DEFAULT;
+ FAPI_ERR("power curve data not valid, use default values");
+ FAPI_SET_HWP_ERROR(rc, RC_MSS_DIMM_POWER_CURVE_DATA_INVALID);
+ if (rc) fapiLogError(rc);
+ }
+
+ FAPI_INF("CDIMM Power [P%d:D%d][SLOPE=%d:INT=%d cW][SLOPE2=%d:INT2=%d cW]", port, dimm, power_slope_array[port][dimm], power_int_array[port][dimm], power_slope2_array[port][dimm], power_int2_array[port][dimm]);
+ }
+// ISDIMM power slope/intercept will come from equation
+ else
+ {
+// Get the dimm power from table and add on any adjustments (if not found in table - should never happen - then default values will be used)
+ power_slope_array[port][dimm] = ISDIMM_POWER_SLOPE_DEFAULT;
+ power_int_array[port][dimm] = ISDIMM_POWER_INT_DEFAULT;
+
+ found_entry_in_table = 0;
+ for (entry = 0; entry < power_table_size; entry++)
+ {
+ if ((power_table[entry].dram_generation == dram_gen) && (power_table[entry].dram_width == dram_width) && ((power_table[entry].dimm_ranks == dimm_master_ranks_array[port][dimm]) || (power_table[entry].dimm_ranks == 1)))
{
- l_dimm_power_adder_type = l_dimm_power_adder_type * 2;
- }
+// get adder for dimm type
+ if (dimm_type == UDIMM)
+ {
+ dimm_power_adder_type = power_table[entry].dimm_type_adder.udimm;
+ }
+ else if (dimm_type == LRDIMM)
+ {
+ dimm_power_adder_type = power_table[entry].dimm_type_adder.lrdimm;
+ }
+ else // RDIMM
+ {
+ dimm_power_adder_type = power_table[entry].dimm_type_adder.rdimm;
+ }
+
+
+ if (dimm_type == RDIMM) {
+ dimm_power_adder_type = dimm_power_adder_type * dimm_number_registers[port][dimm];
+ }
+
// get adder for dimm voltage
- if (l_dimm_voltage == 1200)
- {
- l_dimm_power_adder_volt = l_power_table[entry].dimm_voltage_adder.volt1200;
- }
- else if (l_dimm_voltage == 1350)
- {
- l_dimm_power_adder_volt = l_power_table[entry].dimm_voltage_adder.volt1350;
- }
- else if (l_dimm_voltage == 1500)
- {
- l_dimm_power_adder_volt = l_power_table[entry].dimm_voltage_adder.volt1500;
- }
- else
- {
- FAPI_ERR("UNKNOWN DIMM VOLTAGE FOUND: l_dimm_voltage");
- l_dimm_power_adder_volt = 0;
- }
+ dimm_power_multiplier_volt = ((float(dimm_voltage) / power_table[entry].dimm_voltage_base) * (float(dimm_voltage) / power_table[entry].dimm_voltage_base));
// get adder for dimm frequency
- if (l_dimm_frequency == 1066)
- {
- l_dimm_power_adder_freq = l_power_table[entry].dimm_frequency_adder.freq1066;
- }
- else if (l_dimm_frequency == 1333)
- {
- l_dimm_power_adder_freq = l_power_table[entry].dimm_frequency_adder.freq1333;
- }
- else if (l_dimm_frequency == 1600)
- {
- l_dimm_power_adder_freq = l_power_table[entry].dimm_frequency_adder.freq1600;
- }
- else
- {
- FAPI_ERR("UNKNOWN DIMM FREQ FOUND: l_dimm_frequency");
- l_dimm_power_adder_freq = 0;
- }
-// get adder for slave ranks
- l_dimm_num_slave_ranks=l_dimm_ranks_array[port][dimm] - l_dimm_master_ranks_array[port][dimm];
- if (l_dimm_num_slave_ranks > 0)
- {
- l_dimm_idle_power_adder_slave = l_power_table[entry].rank_slave_adder.idle * l_dimm_num_slave_ranks;
- l_dimm_max_power_adder_slave = l_dimm_idle_power_adder_slave + (l_power_table[entry].rank_slave_adder.max - l_power_table[entry].rank_slave_adder.idle);
- }
- else
- {
- l_dimm_idle_power_adder_slave = 0;
- l_dimm_max_power_adder_slave = 0;
+ dimm_power_mulitiplier_freq = (float(dimm_frequency) / power_table[entry].dimm_frequency_base);
+// get adder for termination using equation (in cW)
+ dimm_power_adder_termination = dimm_power_adder_termination_largest * 100;
+ dimm_power_adder_termination_wc = dimm_power_adder_termination_largest_wc * 100;
+// add up power for each dimm on channel and divide by number of dimms to get an average power for each dimm
+// calculate idle and active dimm power (active power includes worst case termination power)
+ dimm_idle_power = ((float(((power_table[entry].rank_power.idle * (dimm_master_ranks_array[port][dimm] + (dimm_ranks_array[port][dimm] - dimm_master_ranks_array[port][dimm])) + dimm_power_adder_type) * (dimm_power_multiplier_volt) * (dimm_power_mulitiplier_freq)) * num_dimms_on_port) / (num_dimms_on_port)));
+ dimm_active_power = ((float((((power_table[entry].rank_power.idle * (dimm_master_ranks_array[port][dimm] + (dimm_ranks_array[port][dimm] - dimm_master_ranks_array[port][dimm])) + (power_table[entry].rank_power.active - power_table[entry].rank_power.idle)) + dimm_power_adder_type) * (dimm_power_multiplier_volt) * (dimm_power_mulitiplier_freq)) * num_dimms_on_port - (power_table[entry].rank_power.active - power_table[entry].rank_power.idle) * (num_dimms_on_port - 1) + dimm_power_adder_termination + (dimm_power_adder_termination_wc - dimm_power_adder_termination)) / (num_dimms_on_port)));
+// calculate dimm power slope and intercept (add on 0.5 so value is effectively rounded to nearest integer)
+ power_slope_array[port][dimm] = int((dimm_active_power - dimm_idle_power) / (float(ACTIVE_DIMM_UTILIZATION - IDLE_DIMM_UTILIZATION) / 100) + 0.5);
+ power_int_array[port][dimm] = int(dimm_idle_power + 0.5);
+ power_slope2_array[port][dimm] = power_slope_array[port][dimm];
+ power_int2_array[port][dimm] = power_int_array[port][dimm];
+ if (power_table[entry].dram_generation == DDR3)
+ {
+ sprintf(dram_gen_str, "DDR3");
+ }
+ if (power_table[entry].dram_generation == DDR4)
+ {
+ sprintf(dram_gen_str, "DDR4");
+ }
+
+ found_entry_in_table = 1;
+ FAPI_DBG("FOUND ENTRY: GEN=%s WIDTH=X%d RANK=%d IDLE(%d%%)=%d ACTIVE(%d%%)=%d ADDER[TYPE=%d WCTERM=%4.2f] Multiplier[VOLT=%4.2f FREQ=%4.2f]", dram_gen_str, power_table[entry].dram_width, power_table[entry].dimm_ranks, IDLE_DIMM_UTILIZATION, power_table[entry].rank_power.idle, ACTIVE_DIMM_UTILIZATION, power_table[entry].rank_power.active, dimm_power_adder_type, dimm_power_adder_termination_wc, dimm_power_multiplier_volt, dimm_power_mulitiplier_freq);
+ FAPI_DBG("ISDIMM Power [P%d:D%d][%s:X%d:R%d/%d:%d:%d][IDLE(%d%%)=%4.2f:ACTIVE(%d%%)=%4.2f cW][SLOPE=%d:INT=%d cW]", port, dimm, dram_gen_str, power_table[entry].dram_width, dimm_master_ranks_array[port][dimm], (dimm_ranks_array[port][dimm] - dimm_master_ranks_array[port][dimm]), dimm_voltage, dimm_frequency, IDLE_DIMM_UTILIZATION, dimm_idle_power, ACTIVE_DIMM_UTILIZATION, dimm_active_power, power_slope_array[port][dimm], power_int_array[port][dimm]);
+ FAPI_INF("ISDIMM Power [P%d:D%d][SLOPE=%d:INT=%d cW][SLOPE2=%d:INT2=%d cW]", port, dimm, power_slope_array[port][dimm], power_int_array[port][dimm], power_slope2_array[port][dimm], power_int2_array[port][dimm]);
+ break;
}
-// get adder for termination using equation
-// TODO: Need to add this in once equations are available for termination adder
-
-// calculate idle and max dimm power
- l_dimm_idle_power = int((l_power_table[entry].rank_master_power.idle * l_dimm_master_ranks_array[port][dimm] + l_dimm_power_adder_type + l_dimm_idle_power_adder_slave) * (1 + float(l_dimm_power_adder_volt + l_dimm_power_adder_freq) / 100));
- l_dimm_max_power = int(((l_power_table[entry].rank_master_power.idle * l_dimm_master_ranks_array[port][dimm] + l_power_table[entry].rank_master_power.max - l_power_table[entry].rank_master_power.idle) + l_dimm_power_adder_type + l_dimm_max_power_adder_slave) * (1 + float(l_dimm_power_adder_volt + l_dimm_power_adder_freq) / 100));
-// caculcate dimm power slope and intercept
- l_power_slope_array[port][dimm] = int((l_dimm_max_power - l_dimm_idle_power) / (float(l_max_dimm_utilization - l_idle_dimm_utilization) / 100));
- l_power_int_array[port][dimm] = l_dimm_idle_power;
-
- l_found_entry_in_table = 1;
- FAPI_INF("FOUND ENTRY: GEN=%d WIDTH=%d RANK=%d IDLE=%d MAX=%d ADDER[SLAVE_IDLE=%d SLAVE_MAX=%d TYPE=%d VOLT=%d FREQ=%d]", l_power_table[entry].dram_generation, l_power_table[entry].dram_width, l_power_table[entry].dimm_ranks, l_power_table[entry].rank_master_power.idle, l_power_table[entry].rank_master_power.max, l_power_table[entry].rank_slave_adder.idle, l_power_table[entry].rank_slave_adder.max, l_dimm_power_adder_type, l_dimm_power_adder_volt, l_dimm_power_adder_freq);
- FAPI_INF("DIMM Power Calculated [P%d:D%d:R%d/%d][IDLE=%d:MAX=%d cW][SLOPE=%d:INT=%d cW]", port, dimm, l_dimm_master_ranks_array[port][dimm], l_dimm_num_slave_ranks, l_dimm_idle_power, l_dimm_max_power, l_power_slope_array[port][dimm], l_power_int_array[port][dimm]);
- break;
+
+ }
+ if (found_entry_in_table == 0)
+ {
+ FAPI_ERR( "Failed to Find DIMM Power Values on %s. Default values will be used [P%d:D%d][Slope=%d:INT=%d cW]", i_target_mba.toEcmdString(), port, dimm, power_slope_array[port][dimm], power_int_array[port][dimm] );
+ FAPI_SET_HWP_ERROR(rc, RC_MSS_DIMM_NOT_FOUND_IN_POWER_TABLE);
+ if (rc) fapiLogError(rc);
}
+ }
+ }
+ }
+ }
+
+// write output attributes
+ rc = FAPI_ATTR_SET(ATTR_MSS_POWER_SLOPE, &i_target_mba, power_slope_array);
+ if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_MSS_POWER_INT, &i_target_mba, power_int_array);
+ if(rc) return rc;
+
+ rc = FAPI_ATTR_SET(ATTR_MSS_POWER_SLOPE2, &i_target_mba, power_slope2_array);
+ if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_MSS_POWER_INT2, &i_target_mba, power_int2_array);
+ if(rc) return rc;
+
+
+////////////////////////////////////////////////////////////////////////
+// Memory Throttle Determination
+////////////////////////////////////////////////////////////////////////
+
+// Runtime throttles will be non-volatile, so don't recalculate them if they have already been set
+// TODO: remove this section when firmware initializes attributes to zero AND runtime throttles are non-volatile
+ runtime_throttle_n_per_mba = 0;
+ runtime_throttle_n_per_chip = 0;
+ runtime_throttle_d = 0;
+ rc = FAPI_ATTR_SET(ATTR_MSS_RUNTIME_MEM_THROTTLE_NUMERATOR_PER_MBA, &i_target_mba, runtime_throttle_n_per_mba);
+ if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_MSS_RUNTIME_MEM_THROTTLE_NUMERATOR_PER_CHIP, &i_target_mba, runtime_throttle_n_per_chip);
+ if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_MSS_RUNTIME_MEM_THROTTLE_DENOMINATOR, &i_target_mba, runtime_throttle_d);
+ if(rc) return rc;
+
+// Get the runtime throttle attributes here
+ rc = FAPI_ATTR_GET(ATTR_MSS_RUNTIME_MEM_THROTTLE_NUMERATOR_PER_MBA, &i_target_mba, runtime_throttle_n_per_mba);
+ if(rc) return rc;
+ rc = FAPI_ATTR_GET(ATTR_MSS_RUNTIME_MEM_THROTTLE_NUMERATOR_PER_CHIP, &i_target_mba, runtime_throttle_n_per_chip);
+ if(rc) return rc;
+ rc = FAPI_ATTR_GET(ATTR_MSS_RUNTIME_MEM_THROTTLE_DENOMINATOR, &i_target_mba, runtime_throttle_d);
+ if(rc) return rc;
+// check to see if runtime throttles are all zero here
+ if ((runtime_throttle_n_per_mba == 0) && (runtime_throttle_n_per_chip == 0) && (runtime_throttle_d == 0))
+ {
+// Values have not been initialized, so get them initialized
+
+// Determine the thermal power limit to use, which represents a single channel pair power limit for the dimms on that channel pair (ie. power for all dimms attached to one MBA). The procedure mss_bulk_power_throttles takes the input of channel pair power to determine throttles.
+// CDIMM thermal power limit from MRW is per CDIMM, so divide by number of mbas that have dimms to get channel pair power
+// CDIMM: Allow all commands to be directed toward one MBA to achieve the power limit
+// This means that the power limit for a MBA channel pair must be the total CDIMM power limit minus the idle power of the other MBAs logical dimms
+ if (dimm_type == CDIMM)
+ {
+ channel_pair_thermal_power_limit = dimm_thermal_power_limit / num_mba_with_dimms;
+ }
+// ISDIMMs thermal power limit from MRW is per DIMM, so multiply by number of dimms on channel to get channel power and multiply by 2 to get channel pair power
+ else
+ {
+ // ISDIMMs
+ channel_pair_thermal_power_limit = dimm_thermal_power_limit * num_dimms_on_port * 2;
+ }
+
+// Update the channel pair power limit attribute
+ rc = FAPI_ATTR_SET(ATTR_MSS_MEM_WATT_TARGET, &i_target_mba, channel_pair_thermal_power_limit);
+ if(rc) return rc;
+
+// Call the procedure function that takes a channel pair power limit and converts it to throttle values
+
+ FAPI_EXEC_HWP(rc, mss_bulk_pwr_throttles, i_target_mba);
+ if (rc)
+ {
+ FAPI_ERR("Error (0x%x) calling mss_bulk_pwr_throttles", static_cast<uint32_t>(rc));
+ return rc;
+ }
+
+// Read back in the updated throttle attribute values (these are now set to values that will give dimm/channel power underneath the thermal power limit)
+ rc = FAPI_ATTR_GET(ATTR_MSS_MEM_THROTTLE_NUMERATOR_PER_MBA, &i_target_mba, runtime_throttle_n_per_mba);
+ if(rc) return rc;
+ rc = FAPI_ATTR_GET(ATTR_MSS_MEM_THROTTLE_NUMERATOR_PER_CHIP, &i_target_mba, runtime_throttle_n_per_chip);
+ if(rc) return rc;
+ rc = FAPI_ATTR_GET(ATTR_MSS_MEM_THROTTLE_DENOMINATOR, &i_target_mba, runtime_throttle_d);
+ if(rc) return rc;
+
+// update output attributes
+ rc = FAPI_ATTR_SET(ATTR_MSS_RUNTIME_MEM_THROTTLE_NUMERATOR_PER_MBA, &i_target_mba, runtime_throttle_n_per_mba);
+ if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_MSS_RUNTIME_MEM_THROTTLE_NUMERATOR_PER_CHIP, &i_target_mba, runtime_throttle_n_per_chip);
+ if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_MSS_RUNTIME_MEM_THROTTLE_DENOMINATOR, &i_target_mba, runtime_throttle_d);
+ if(rc) return rc;
+
+ }
+
+// Initialize the generic throttle attributes to safemode throttles (since the IPL will be done at the safemode throttles)
+ throttle_n_per_mba = safemode_throttle_n_per_mba;
+ throttle_n_per_chip = safemode_throttle_n_per_chip;
+ throttle_d = safemode_throttle_d;
+
+// write output attributes
+ rc = FAPI_ATTR_SET(ATTR_MSS_MEM_THROTTLE_NUMERATOR_PER_MBA, &i_target_mba, throttle_n_per_mba);
+ if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_MSS_MEM_THROTTLE_NUMERATOR_PER_CHIP, &i_target_mba, throttle_n_per_chip);
+ if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_MSS_MEM_THROTTLE_DENOMINATOR, &i_target_mba, throttle_d);
+ if(rc) return rc;
+
+ FAPI_INF("*** %s COMPLETE ***", procedure_name);
+ return rc;
+ }
+
+//------------------------------------------------------------------------------
+// @brief mss_eff_config_thermal_term(): This function calculates the data bus termination power
+//
+// @param const char i_nom_or_wc_term[4]: description of what is being calculated (ie. NOM or WC)
+// @param uint8_t i_port: MBA port being worked on
+// @param uint8_t i_dimm: DIMM being worked on
+// @param uint8_t i_rank: Rank being worked on
+// @param uint32_t i_dimm_voltage: DIMM Voltage
+// @param uint8_t i_dram_width: DRAM Width
+// @param uint8_t i_dram_tdqs: DRAM TDQS enable/disable
+// @param uint8_t i_ibm_type[NUM_PORTS][NUM_DIMMS]: IBM bus topology type
+// @param uint8_t i_dimm_ranks_configed_array[NUM_PORTS][NUM_DIMMS]: Master Ranks configured
+// @param uint8_t i_dimm_dram_ron[NUM_PORTS][NUM_DIMMS]: DRAM RON driver impedance
+// @param uint8_t i_dimm_rank_odt_rd[NUM_PORTS][NUM_DIMMS][NUM_RANKS]: Read ODT
+// @param uint8_t i_dimm_rank_odt_wr[NUM_PORTS][NUM_DIMMS][NUM_RANKS]: Write ODT
+// @param uint8_t i_dram_rtt_nom[NUM_PORTS][NUM_DIMMS][NUM_RANKS]: DRAM RTT NOM
+// @param uint8_t i_dram_rtt_wr[NUM_PORTS][NUM_DIMMS][NUM_RANKS]: DRAM RTT WR
+// @param uint8_t i_cen_dq_dqs_rcv_imp[NUM_PORTS]: Centaur DQ/DQS receiver impedance
+// @param uint8_t i_cen_dq_dqs_drv_imp[NUM_PORTS]: Centaur DQ/DQS driver impedance
+// @param float &o_dimm_power_adder_termination: Termination Power Calculated in Watts
+
+// @return fapi::ReturnCode
+//------------------------------------------------------------------------------
+
+ fapi::ReturnCode mss_eff_config_thermal_term(
+ const char i_nom_or_wc_term[4],
+ uint8_t i_port,
+ uint8_t i_dimm,
+ uint8_t i_rank,
+ uint32_t i_dimm_voltage,
+ uint8_t i_dram_width,
+ uint8_t i_dram_tdqs,
+ uint8_t i_ibm_type[NUM_PORTS][NUM_DIMMS],
+ uint8_t i_dimm_ranks_configed_array[NUM_PORTS][NUM_DIMMS],
+ uint8_t i_dimm_dram_ron[NUM_PORTS][NUM_DIMMS],
+ uint8_t i_dimm_rank_odt_rd[NUM_PORTS][NUM_DIMMS][NUM_RANKS],
+ uint8_t i_dimm_rank_odt_wr[NUM_PORTS][NUM_DIMMS][NUM_RANKS],
+ uint8_t i_dram_rtt_nom[NUM_PORTS][NUM_DIMMS][NUM_RANKS],
+ uint8_t i_dram_rtt_wr[NUM_PORTS][NUM_DIMMS][NUM_RANKS],
+ uint8_t i_cen_dq_dqs_rcv_imp[NUM_PORTS],
+ uint8_t i_cen_dq_dqs_drv_imp[NUM_PORTS],
+ float &o_dimm_power_adder_termination
+ )
+ {
+
+ fapi::ReturnCode rc = fapi::FAPI_RC_SUCCESS;
+ uint8_t number_nets_term_rd;
+ uint8_t number_nets_term_wr;
+ uint8_t ma0odt01_dimm;
+ uint8_t ma1odt01_dimm;
+ uint8_t ma0odt0_rank;
+ uint8_t ma0odt1_rank;
+ uint8_t ma1odt0_rank;
+ uint8_t ma1odt1_rank;
+ uint8_t rank_mask;
+ float eff_term_rd;
+ float eff_net_term_rd;
+ float term_odt_mult_rd;
+ float eff_term_wr;
+ float eff_net_term_wr;
+ float term_odt_mult_wr;
+ uint8_t cen_dq_dqs_drv_imp_value;
+
+// Get number of nets that will have termination applied from ODT (DQ,DQS,DM,TDQS)
+// number of nets for DQ (9 DRAMs x 8 bits each, or 18 DRAMs x 4 bits each = 72)
+ number_nets_term_rd = 72;
+ number_nets_term_wr = 72;
+// add in number of nets for DQS + DM + TDQS (TDQS only supported for X8, DM only used for writes)
+ if (i_dram_width == fapi::ENUM_ATTR_EFF_DRAM_WIDTH_X4)
+ {
+ number_nets_term_rd = number_nets_term_rd + 36 + 0 + 0;
+ number_nets_term_wr = number_nets_term_wr + 36 + 0 + 0;
+ }
+ else if ((i_dram_width == fapi::ENUM_ATTR_EFF_DRAM_WIDTH_X8) && (i_dram_tdqs == fapi::ENUM_ATTR_EFF_DRAM_TDQS_DISABLE))
+ {
+ number_nets_term_rd = number_nets_term_rd + 18 + 0 + 0;
+ number_nets_term_wr = number_nets_term_wr + 18 + 9 + 0;
+ }
+ else if ((i_dram_width == fapi::ENUM_ATTR_EFF_DRAM_WIDTH_X8) && (i_dram_tdqs == fapi::ENUM_ATTR_EFF_DRAM_TDQS_ENABLE))
+ {
+ number_nets_term_rd = number_nets_term_rd + 18 + 0 + 18;
+ number_nets_term_wr = number_nets_term_wr + 18 + 0 + 18;
+ }
+
+// which rank is mapped to the [01]ODT[01] nets, from centaur spec, every type uses Ranks 0,1,4,5, with the following exceptions
+// Type 1D used Ranks 0,2,4,6 in that order (0_ODT0,0_ODT1,1_ODT0,1_ODT1)
+// expect that EFF_ODT_RD and EFF_ODT_WR will be setup correctly so we just need to add up any termination in parallel for the bits set in these attributes
+// Also need to consider if ODT is tied high for writes (if rtt_wr is set for the rank being written to, then it will be assumed that ODT is tied high)
+
+ if (i_ibm_type[i_port][i_dimm] == fapi::ENUM_ATTR_EFF_IBM_TYPE_TYPE_1D)
+ {
+ ma0odt01_dimm = 0;
+ ma1odt01_dimm = 1;
+ ma0odt0_rank = 0;
+ ma0odt1_rank = 2;
+ ma1odt0_rank = 0;
+ ma1odt1_rank = 2;
+ }
+ else
+ {
+ ma0odt01_dimm = 0;
+ ma1odt01_dimm = 1;
+ ma0odt0_rank = 0;
+ ma0odt1_rank = 1;
+ ma1odt0_rank = 0;
+ ma1odt1_rank = 1;
+ }
+
+// check to see if rank is configured, only get termination power for these ranks
+ rank_mask = 0x00;
+ if (i_rank == 0)
+ {
+ rank_mask = 0x80;
+ }
+ else if (i_rank == 1)
+ {
+ rank_mask = 0x40;
+ }
+ else if (i_rank == 2)
+ {
+ rank_mask = 0x20;
+ }
+ else if (i_rank == 3)
+ {
+ rank_mask = 0x10;
+ }
+ if ((i_dimm_ranks_configed_array[i_port][i_dimm] & rank_mask) != 0)
+ {
+// effective net termination = [(active termination in parallel || driver impedance) + active termination in parallel]
+
+
+
+////////////////////////////////////////////////
+// calculate out effective termination for reads
+////////////////////////////////////////////////
+ eff_term_rd = 0;
+
+// 0ODT0
+ if (((i_dimm_rank_odt_rd[i_port][i_dimm][i_rank] & 0x80) != 0) && (i_dram_rtt_nom[i_port][ma0odt01_dimm][ma0odt0_rank] != fapi::ENUM_ATTR_EFF_DRAM_RTT_NOM_DISABLE))
+ {
+ if (eff_term_rd == 0)
+ {
+ eff_term_rd = i_dram_rtt_nom[i_port][ma0odt01_dimm][ma0odt0_rank];
+ }
+ else
+ {
+ eff_term_rd = (eff_term_rd * i_dram_rtt_nom[i_port][ma0odt01_dimm][ma0odt0_rank]) / (eff_term_rd + i_dram_rtt_nom[i_port][ma0odt01_dimm][ma0odt0_rank]);
+ }
+ FAPI_DBG("[P%d:D%d:R%d] 0ODT0 RD TERMINATION = %4.2f (%d)", i_port, i_dimm, i_rank, eff_term_rd, i_dram_rtt_nom[i_port][ma0odt01_dimm][ma0odt0_rank]);
+
+ }
+// 0ODT1
+ if (((i_dimm_rank_odt_rd[i_port][i_dimm][i_rank] & 0x40) != 0) && (i_dram_rtt_nom[i_port][ma0odt01_dimm][ma0odt1_rank] != fapi::ENUM_ATTR_EFF_DRAM_RTT_NOM_DISABLE))
+ {
+ if (eff_term_rd == 0)
+ {
+ eff_term_rd = i_dram_rtt_nom[i_port][ma0odt01_dimm][ma0odt1_rank];
+ }
+ else
+ {
+ eff_term_rd = (eff_term_rd * i_dram_rtt_nom[i_port][ma0odt01_dimm][ma0odt1_rank]) / (eff_term_rd + i_dram_rtt_nom[i_port][ma0odt01_dimm][ma0odt1_rank]);
+ }
+ FAPI_DBG("[P%d:D%d:R%d] 0ODT1 RD TERMINATION = %4.2f (%d)", i_port, i_dimm, i_rank, eff_term_rd, i_dram_rtt_nom[i_port][ma0odt01_dimm][ma0odt1_rank]);
+ }
+// 1ODT0
+ if (((i_dimm_rank_odt_rd[i_port][i_dimm][i_rank] & 0x20) != 0) && (i_dram_rtt_nom[i_port][ma1odt01_dimm][ma1odt0_rank] != fapi::ENUM_ATTR_EFF_DRAM_RTT_NOM_DISABLE))
+ {
+ if (eff_term_rd == 0)
+ {
+ eff_term_rd = i_dram_rtt_nom[i_port][ma1odt01_dimm][ma1odt0_rank];
+ }
+ else
+ {
+ eff_term_rd = (eff_term_rd * i_dram_rtt_nom[i_port][ma1odt01_dimm][ma1odt0_rank]) / (eff_term_rd + i_dram_rtt_nom[i_port][ma1odt01_dimm][ma1odt0_rank]);
+ }
+ FAPI_DBG("[P%d:D%d:R%d] 1ODT0 RD TERMINATION = %4.2f (%d)", i_port, i_dimm, i_rank, eff_term_rd, i_dram_rtt_nom[i_port][ma1odt01_dimm][ma1odt0_rank]);
+ }
+// 1ODT1
+ if (((i_dimm_rank_odt_rd[i_port][i_dimm][i_rank] & 0x10) != 0) && (i_dram_rtt_nom[i_port][ma1odt01_dimm][ma1odt1_rank] != fapi::ENUM_ATTR_EFF_DRAM_RTT_NOM_DISABLE))
+ {
+ if (eff_term_rd == 0)
+ {
+ eff_term_rd = i_dram_rtt_nom[i_port][ma1odt01_dimm][ma1odt1_rank];
+ }
+ else
+ {
+ eff_term_rd = (eff_term_rd * i_dram_rtt_nom[i_port][ma1odt01_dimm][ma1odt1_rank]) / (eff_term_rd + i_dram_rtt_nom[i_port][ma1odt01_dimm][ma1odt1_rank]);
+ }
+ FAPI_DBG("[P%d:D%d:R%d] 1ODT1 RD TERMINATION = %4.2f (%d)", i_port, i_dimm, i_rank, eff_term_rd, i_dram_rtt_nom[i_port][ma1odt01_dimm][ma1odt1_rank]);
+ }
+ // calculate out effective read termination
+ if (eff_term_rd != 0)
+ {
+ eff_net_term_rd = (float((float(eff_term_rd * i_cen_dq_dqs_rcv_imp[i_port]) / (eff_term_rd + i_cen_dq_dqs_rcv_imp[i_port])) * i_dimm_dram_ron[i_port][i_dimm]) / ((float(eff_term_rd * i_cen_dq_dqs_rcv_imp[i_port]) / (eff_term_rd + i_cen_dq_dqs_rcv_imp[i_port])) + i_dimm_dram_ron[i_port][i_dimm])) + (float(eff_term_rd * i_cen_dq_dqs_rcv_imp[i_port]) / (eff_term_rd + i_cen_dq_dqs_rcv_imp[i_port]));
+ term_odt_mult_rd = 1.25;
+ }
+ else
+ {
+ eff_net_term_rd = (float((i_cen_dq_dqs_rcv_imp[i_port]) * i_dimm_dram_ron[i_port][i_dimm]) / ((i_cen_dq_dqs_rcv_imp[i_port]) + i_dimm_dram_ron[i_port][i_dimm])) + (i_cen_dq_dqs_rcv_imp[i_port]);
+ term_odt_mult_rd = 1;
+ }
+// writes
+/////////////////////////////////////////////////
+// calculate out effective termination for writes
+/////////////////////////////////////////////////
+ eff_term_wr = 0;
+
+// check to see if ODT is tied high (rank is not one of the ranks that get ODT driven to it, and rtt_wr or rtt_nom are enabled)
+ if (((((i_rank != ma0odt0_rank) && (i_rank != ma0odt1_rank)) && (i_dimm == 0)) || (((i_rank != ma1odt0_rank) && (i_rank != ma1odt1_rank)) && (i_dimm == 1))) && ((i_dram_rtt_wr[i_port][i_dimm][i_rank] != fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_DISABLE) || (i_dram_rtt_nom[i_port][i_dimm][i_rank] != fapi::ENUM_ATTR_EFF_DRAM_RTT_NOM_DISABLE)))
+ {
+ // dynamic ODT enabled, so use rtt_wr (only if the rank being written to has it enabled)
+ if (i_dram_rtt_wr[i_port][i_dimm][i_rank] != fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_DISABLE)
+ {
+ if (eff_term_wr == 0)
+ {
+ eff_term_wr = i_dram_rtt_wr[i_port][i_dimm][i_rank];
+ }
+ else
+ {
+ eff_term_wr = (eff_term_wr * i_dram_rtt_wr[i_port][i_dimm][i_rank]) / (eff_term_wr + i_dram_rtt_wr[i_port][i_dimm][i_rank]);
+ }
+ }
+ // dynamic ODT disabled, so use rtt_nom
+ else if (i_dram_rtt_nom[i_port][i_dimm][i_rank] != fapi::ENUM_ATTR_EFF_DRAM_RTT_NOM_DISABLE)
+ {
+ if (eff_term_wr == 0)
+ {
+ eff_term_wr = i_dram_rtt_nom[i_port][i_dimm][i_rank];
+ }
+ else
+ {
+ eff_term_wr = (eff_term_wr * i_dram_rtt_nom[i_port][i_dimm][i_rank]) / (eff_term_wr + i_dram_rtt_nom[i_port][i_dimm][i_rank]);
+ }
+
+ }
+ FAPI_DBG("[P%d:D%d:R%d] WR TERMINATION = %4.2f (%d/%d)", i_port, i_dimm, i_rank, eff_term_wr, i_dram_rtt_wr[i_port][i_dimm][i_rank], i_dram_rtt_nom[i_port][i_dimm][i_rank]);
+ }
+/// 0ODT0
+ if (((i_dimm_rank_odt_wr[i_port][i_dimm][i_rank] & 0x80) != 0) && ((i_dram_rtt_wr[i_port][ma0odt01_dimm][ma0odt0_rank] != fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_DISABLE) || (i_dram_rtt_nom[i_port][ma0odt01_dimm][ma0odt0_rank] != fapi::ENUM_ATTR_EFF_DRAM_RTT_NOM_DISABLE)))
+ {
+ // dynamic ODT enabled, so use rtt_wr (only if the rank being written to has it enabled)
+ if ((i_dram_rtt_wr[i_port][ma0odt01_dimm][ma0odt0_rank] != fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_DISABLE) && (i_dimm == 0) && (i_rank == ma0odt0_rank))
+ {
+ if (eff_term_wr == 0)
+ {
+ eff_term_wr = i_dram_rtt_wr[i_port][ma0odt01_dimm][ma0odt0_rank];
+ }
+ else
+ {
+ eff_term_wr = (eff_term_wr * i_dram_rtt_wr[i_port][ma0odt01_dimm][ma0odt0_rank]) / (eff_term_wr + i_dram_rtt_wr[i_port][ma0odt01_dimm][ma0odt0_rank]);
+ }
+ }
+ // dynamic ODT disabled, so use rtt_nom
+ else if (i_dram_rtt_nom[i_port][ma0odt01_dimm][ma0odt0_rank] != fapi::ENUM_ATTR_EFF_DRAM_RTT_NOM_DISABLE)
+ {
+ if (eff_term_wr == 0)
+ {
+ eff_term_wr = i_dram_rtt_nom[i_port][ma0odt01_dimm][ma0odt0_rank];
+ }
+ else
+ {
+ eff_term_wr = (eff_term_wr * i_dram_rtt_nom[i_port][ma0odt01_dimm][ma0odt0_rank]) / (eff_term_wr + i_dram_rtt_nom[i_port][ma0odt01_dimm][ma0odt0_rank]);
+ }
+
+ }
+ FAPI_DBG("[P%d:D%d:R%d] 0ODT0 WR TERMINATION = %4.2f (%d/%d)", i_port, i_dimm, i_rank, eff_term_wr, i_dram_rtt_nom[i_port][ma0odt01_dimm][ma0odt0_rank], i_dram_rtt_wr[i_port][ma0odt01_dimm][ma0odt0_rank]);
+ }
+// 0ODT1
+ if (((i_dimm_rank_odt_wr[i_port][i_dimm][i_rank] & 0x40) != 0) && ((i_dram_rtt_wr[i_port][ma0odt01_dimm][ma0odt1_rank] != fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_DISABLE) || (i_dram_rtt_nom[i_port][ma0odt01_dimm][ma0odt1_rank] != fapi::ENUM_ATTR_EFF_DRAM_RTT_NOM_DISABLE)))
+ {
+ // dynamic ODT enabled, so use rtt_wr (only if the rank being written to has it enabled)
+ if ((i_dram_rtt_wr[i_port][ma0odt01_dimm][ma0odt1_rank] != fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_DISABLE) && (i_dimm == 0) && (i_rank == ma0odt1_rank))
+ {
+ if (eff_term_wr == 0)
+ {
+ eff_term_wr = i_dram_rtt_wr[i_port][ma0odt01_dimm][ma0odt1_rank];
+ }
+ else
+ {
+ eff_term_wr = (eff_term_wr * i_dram_rtt_wr[i_port][ma0odt01_dimm][ma0odt1_rank]) / (eff_term_wr + i_dram_rtt_wr[i_port][ma0odt01_dimm][ma0odt1_rank]);
+ }
+ }
+ // dynamic ODT disabled, so use rtt_nom
+ else if (i_dram_rtt_nom[i_port][ma0odt01_dimm][ma0odt1_rank] != fapi::ENUM_ATTR_EFF_DRAM_RTT_NOM_DISABLE)
+ {
+ if (eff_term_wr == 0)
+ {
+ eff_term_wr = i_dram_rtt_nom[i_port][ma0odt01_dimm][ma0odt1_rank];
}
- if (l_found_entry_in_table == 0)
+ else
{
- FAPI_ERR( "WARNING: Failed to Find DIMM Power Values, so default values will be used [%d:%d][%d:%d]", port, dimm, l_power_slope_array[port][dimm], l_power_int_array[port][dimm] );
+ eff_term_wr = (eff_term_wr * i_dram_rtt_nom[i_port][ma0odt01_dimm][ma0odt1_rank]) / (eff_term_wr + i_dram_rtt_nom[i_port][ma0odt01_dimm][ma0odt1_rank]);
+ }
+
+ }
+ FAPI_DBG("[P%d:D%d:R%d] 0ODT1 WR TERMINATION = %4.2f (%d/%d)", i_port, i_dimm, i_rank, eff_term_wr, i_dram_rtt_nom[i_port][ma0odt01_dimm][ma0odt1_rank], i_dram_rtt_wr[i_port][ma0odt01_dimm][ma0odt1_rank]);
+ }
+// 1ODT0
+ if (((i_dimm_rank_odt_wr[i_port][i_dimm][i_rank] & 0x20) != 0) && ((i_dram_rtt_wr[i_port][ma1odt01_dimm][ma1odt0_rank] != fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_DISABLE) || (i_dram_rtt_nom[i_port][ma1odt01_dimm][ma1odt0_rank] != fapi::ENUM_ATTR_EFF_DRAM_RTT_NOM_DISABLE)))
+ {
+ // dynamic ODT enabled, so use rtt_wr (only if the rank being written to has it enabled)
+ if ((i_dram_rtt_wr[i_port][ma1odt01_dimm][ma1odt0_rank] != fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_DISABLE) && (i_dimm == 1) && (i_rank == ma1odt0_rank))
+ {
+ if (eff_term_wr == 0)
+ {
+ eff_term_wr = i_dram_rtt_wr[i_port][ma1odt01_dimm][ma1odt0_rank];
+ }
+ else
+ {
+ eff_term_wr = (eff_term_wr * i_dram_rtt_wr[i_port][ma1odt01_dimm][ma1odt0_rank]) / (eff_term_wr + i_dram_rtt_wr[i_port][ma1odt01_dimm][ma1odt0_rank]);
+ }
+ }
+ // dynamic ODT disabled, so use rtt_nom
+ else if (i_dram_rtt_nom[i_port][ma1odt01_dimm][ma1odt0_rank] != fapi::ENUM_ATTR_EFF_DRAM_RTT_NOM_DISABLE)
+ {
+ if (eff_term_wr == 0)
+ {
+ eff_term_wr = i_dram_rtt_nom[i_port][ma1odt01_dimm][ma1odt0_rank];
+ }
+ else
+ {
+ eff_term_wr = (eff_term_wr * i_dram_rtt_nom[i_port][ma1odt01_dimm][ma1odt0_rank]) / (eff_term_wr + i_dram_rtt_nom[i_port][ma1odt01_dimm][ma1odt0_rank]);
+ }
+
+ }
+ FAPI_DBG("[P%d:D%d:R%d] 1ODT0 WR TERMINATION = %4.2f (%d/%d)", i_port, i_dimm, i_rank, eff_term_wr, i_dram_rtt_nom[i_port][ma1odt01_dimm][ma1odt0_rank], i_dram_rtt_wr[i_port][ma1odt01_dimm][ma1odt0_rank]);
+ }
+// 1ODT1
+ if (((i_dimm_rank_odt_wr[i_port][i_dimm][i_rank] & 0x10) != 0) && ((i_dram_rtt_wr[i_port][ma1odt01_dimm][ma1odt1_rank] != fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_DISABLE) || (i_dram_rtt_nom[i_port][ma1odt01_dimm][ma1odt1_rank] != fapi::ENUM_ATTR_EFF_DRAM_RTT_NOM_DISABLE)))
+ {
+ // dynamic ODT enabled, so use rtt_wr (only if the rank being written to has it enabled)
+ if ((i_dram_rtt_wr[i_port][ma1odt01_dimm][ma1odt1_rank] != fapi::ENUM_ATTR_EFF_DRAM_RTT_WR_DISABLE) && (i_dimm == 1) && (i_rank == ma1odt1_rank))
+ {
+ if (eff_term_wr == 0)
+ {
+ eff_term_wr = i_dram_rtt_wr[i_port][ma1odt01_dimm][ma1odt1_rank];
+ }
+ else
+ {
+ eff_term_wr = (eff_term_wr * i_dram_rtt_wr[i_port][ma1odt01_dimm][ma1odt1_rank]) / (eff_term_wr + i_dram_rtt_wr[i_port][ma1odt01_dimm][ma1odt1_rank]);
}
}
+ // dynamic ODT disabled, so use rtt_nom
+ else if (i_dram_rtt_nom[i_port][ma1odt01_dimm][ma1odt1_rank] != fapi::ENUM_ATTR_EFF_DRAM_RTT_NOM_DISABLE)
+ {
+ if (eff_term_wr == 0)
+ {
+ eff_term_wr = i_dram_rtt_nom[i_port][ma1odt01_dimm][ma1odt1_rank];
+ }
+ else
+ {
+ eff_term_wr = (eff_term_wr * i_dram_rtt_nom[i_port][ma1odt01_dimm][ma1odt1_rank]) / (eff_term_wr + i_dram_rtt_nom[i_port][ma1odt01_dimm][ma1odt1_rank]);
+ }
+
+ }
+ FAPI_DBG("[P%d:D%d:R%d] 1ODT1 WR TERMINATION = %4.2f (%d/%d)", i_port, i_dimm, i_rank, eff_term_wr, i_dram_rtt_nom[i_port][ma1odt01_dimm][ma1odt1_rank], i_dram_rtt_wr[i_port][ma1odt01_dimm][ma1odt1_rank]);
+ }
+
+// Translate enum value to a resistance value for i_cen_dq_dqs_drv_imp[i_port]
+ rc = mss_eff_config_thermal_get_cen_drv_value(
+ i_cen_dq_dqs_drv_imp[i_port],
+ cen_dq_dqs_drv_imp_value
+ );
+ if(rc)
+ {
+ FAPI_ERR("Error (0x%x) calling mss_eff_config_thermal_get_cen_drv_value", static_cast<uint32_t>(rc));
+ return rc;
+ }
+
+ if (eff_term_wr != 0)
+ {
+ eff_net_term_wr = (float(eff_term_wr * cen_dq_dqs_drv_imp_value) / (eff_term_wr + cen_dq_dqs_drv_imp_value)) + eff_term_wr;
+ term_odt_mult_wr = 1.25;
+ }
+ else
+ {
+ eff_net_term_wr = cen_dq_dqs_drv_imp_value;
+ term_odt_mult_wr = 1;
+ }
+
+// From Warren:
+// Termination power = (voltage/net termination) * number of nets * (% of traffic on bus*1.25)
+// The net termination is the effective termination that exists between the power rail and ground. So in my calculations this is all the active termination in parallel with the driver impedance + all the active termination in parallel. The value is different for reads and writes.
+// Number of nets includes the strobe nets (2 nets per strobe)
+// % of traffic on bus is the % of the bus used for data traffic split out from reads and writes. The 1.25 factor is due to the odt_en signals being active longer then the data windows.
+// Value here is in Watts (W)
+ o_dimm_power_adder_termination = float(i_dimm_voltage) / 1000 * (((float(i_dimm_voltage) / 1000 / eff_net_term_rd) * (number_nets_term_rd) * (float(ACTIVE_DIMM_UTILIZATION) / 100) * (float(DATA_BUS_READ_PERCENT) / 100) * (term_odt_mult_rd)) + ((float(i_dimm_voltage) / 1000 / eff_net_term_wr) * (number_nets_term_wr) * (float(ACTIVE_DIMM_UTILIZATION) / 100) * (float(DATA_BUS_WRITE_PERCENT) / 100) * (term_odt_mult_wr)));
+ FAPI_DBG("%s TERM:[P%d:D%d:R%d] CEN[DRV=%d RCV=%d] DRAM[DRV=%d ODT_RD=%4.2f ODT_WR=%4.2f]", i_nom_or_wc_term, i_port, i_dimm, i_rank, cen_dq_dqs_drv_imp_value, i_cen_dq_dqs_rcv_imp[i_port], i_dimm_dram_ron[i_port][i_dimm], eff_term_rd, eff_term_wr);
+ FAPI_DBG("%s TERM POWER:[P%d:D%d:R%d] RD[Nets=%d EffTerm=%3.2f ODTMult=%1.2f] WR[Nets=%d EffTerm=%3.2f ODTMult=%1.2f] TermPower(%d%%)=%2.2f W", i_nom_or_wc_term, i_port, i_dimm, i_rank, number_nets_term_rd, eff_net_term_rd, term_odt_mult_rd, number_nets_term_wr, eff_net_term_wr, term_odt_mult_wr, ACTIVE_DIMM_UTILIZATION, o_dimm_power_adder_termination);
+ }
+
+ return rc;
+ }
+
+//------------------------------------------------------------------------------
+// @brief mss_eff_config_thermal_get_wc_term(): This function finds the worst case termination settings possible for a given set
+// of termination settings
+//
+// @param const fapi::Target &i_target_mba: MBA Target
+// @param uint8_t i_port: MBA port being worked on
+// @param uint8_t &o_cen_dq_dqs_rcv_imp_wc: Worst Case Centaur DQ/DQS receiver impedance (output)
+// @param uint8_t &o_cen_dq_dqs_drv_imp_wc: Worst Case Centaur DQ/DQS driver impedance (output)
+//
+// @return fapi::ReturnCode
+//------------------------------------------------------------------------------
+
+ fapi::ReturnCode mss_eff_config_thermal_get_wc_term(
+ const fapi::Target &i_target_mba,
+ uint8_t i_port,
+ uint8_t &o_cen_dq_dqs_rcv_imp_wc,
+ uint8_t &o_cen_dq_dqs_drv_imp_wc
+ )
+ {
+ fapi::ReturnCode rc = fapi::FAPI_RC_SUCCESS;
+
+ uint8_t l_cen_dq_dqs_rcv_imp[NUM_PORTS];
+ uint8_t l_cen_dq_dqs_drv_imp[NUM_PORTS];
+ uint32_t l_cen_dq_dqs_rcv_imp_schmoo[NUM_PORTS];
+ uint32_t l_cen_dq_dqs_drv_imp_schmoo[NUM_PORTS];
+ uint32_t l_loop;
+ uint32_t l_schmoo_mask;
+
+// This lists out the number and enum values for the centaur dq/dqs receiver and driver impedance. Have the list go from strongest to weakest termination.
+// If the size changes at all, then updates are needed below to get the correct mask
+
+ const uint8_t MAX_CEN_RCV_IMP = 10;
+ uint8_t cen_rcv_imp_array[] = {
+ fapi::ENUM_ATTR_EFF_CEN_RCV_IMP_DQ_DQS_OHM15,
+ fapi::ENUM_ATTR_EFF_CEN_RCV_IMP_DQ_DQS_OHM20,
+ fapi::ENUM_ATTR_EFF_CEN_RCV_IMP_DQ_DQS_OHM30,
+ fapi::ENUM_ATTR_EFF_CEN_RCV_IMP_DQ_DQS_OHM40,
+ fapi::ENUM_ATTR_EFF_CEN_RCV_IMP_DQ_DQS_OHM48,
+ fapi::ENUM_ATTR_EFF_CEN_RCV_IMP_DQ_DQS_OHM60,
+ fapi::ENUM_ATTR_EFF_CEN_RCV_IMP_DQ_DQS_OHM80,
+ fapi::ENUM_ATTR_EFF_CEN_RCV_IMP_DQ_DQS_OHM120,
+ fapi::ENUM_ATTR_EFF_CEN_RCV_IMP_DQ_DQS_OHM160,
+ fapi::ENUM_ATTR_EFF_CEN_RCV_IMP_DQ_DQS_OHM240
+ };
+
+ const uint8_t MAX_CEN_DRV_IMP = 16;
+ uint8_t cen_drv_imp_array[] = {
+ fapi::ENUM_ATTR_EFF_CEN_DRV_IMP_DQ_DQS_OHM24_FFE0,
+ fapi::ENUM_ATTR_EFF_CEN_DRV_IMP_DQ_DQS_OHM30_FFE0,
+ fapi::ENUM_ATTR_EFF_CEN_DRV_IMP_DQ_DQS_OHM30_FFE480,
+ fapi::ENUM_ATTR_EFF_CEN_DRV_IMP_DQ_DQS_OHM30_FFE240,
+ fapi::ENUM_ATTR_EFF_CEN_DRV_IMP_DQ_DQS_OHM30_FFE160,
+ fapi::ENUM_ATTR_EFF_CEN_DRV_IMP_DQ_DQS_OHM30_FFE120,
+ fapi::ENUM_ATTR_EFF_CEN_DRV_IMP_DQ_DQS_OHM34_FFE0,
+ fapi::ENUM_ATTR_EFF_CEN_DRV_IMP_DQ_DQS_OHM34_FFE480,
+ fapi::ENUM_ATTR_EFF_CEN_DRV_IMP_DQ_DQS_OHM34_FFE240,
+ fapi::ENUM_ATTR_EFF_CEN_DRV_IMP_DQ_DQS_OHM34_FFE160,
+ fapi::ENUM_ATTR_EFF_CEN_DRV_IMP_DQ_DQS_OHM34_FFE120,
+ fapi::ENUM_ATTR_EFF_CEN_DRV_IMP_DQ_DQS_OHM40_FFE0,
+ fapi::ENUM_ATTR_EFF_CEN_DRV_IMP_DQ_DQS_OHM40_FFE480,
+ fapi::ENUM_ATTR_EFF_CEN_DRV_IMP_DQ_DQS_OHM40_FFE240,
+ fapi::ENUM_ATTR_EFF_CEN_DRV_IMP_DQ_DQS_OHM40_FFE160,
+ fapi::ENUM_ATTR_EFF_CEN_DRV_IMP_DQ_DQS_OHM40_FFE120
+ };
+
+// Get attributes for nominal settings and possible settings to choose from
+ rc = FAPI_ATTR_GET(ATTR_EFF_CEN_RCV_IMP_DQ_DQS, &i_target_mba, l_cen_dq_dqs_rcv_imp);
+ if(rc) return rc;
+ rc = FAPI_ATTR_GET(ATTR_EFF_CEN_DRV_IMP_DQ_DQS, &i_target_mba, l_cen_dq_dqs_drv_imp);
+ if(rc) return rc;
+ rc = FAPI_ATTR_GET(ATTR_EFF_CEN_RCV_IMP_DQ_DQS_SCHMOO, &i_target_mba, l_cen_dq_dqs_rcv_imp_schmoo);
+ if(rc) return rc;
+ rc = FAPI_ATTR_GET(ATTR_EFF_CEN_DRV_IMP_DQ_DQS_SCHMOO, &i_target_mba, l_cen_dq_dqs_drv_imp_schmoo);
+ if(rc) return rc;
+
+// initialize to default values in case below does not find a match
+ o_cen_dq_dqs_rcv_imp_wc = l_cen_dq_dqs_rcv_imp[i_port];
+ o_cen_dq_dqs_drv_imp_wc = l_cen_dq_dqs_drv_imp[i_port];
+
+// find strongest termination setting that could be used, if none found, then use nominal
+ l_schmoo_mask = 0x00000000;
+ for (l_loop=0; l_loop < MAX_CEN_RCV_IMP; l_loop++)
+ {
+ switch (l_loop)
+ {
+ case 0:
+ l_schmoo_mask = 0x80000000;
+ break;
+ case 1:
+ l_schmoo_mask = 0x40000000;
+ break;
+ case 2:
+ l_schmoo_mask = 0x20000000;
+ break;
+ case 3:
+ l_schmoo_mask = 0x10000000;
+ break;
+ case 4:
+ l_schmoo_mask = 0x08000000;
+ break;
+ case 5:
+ l_schmoo_mask = 0x04000000;
+ break;
+ case 6:
+ l_schmoo_mask = 0x02000000;
+ break;
+ case 7:
+ l_schmoo_mask = 0x01000000;
+ break;
+ case 8:
+ l_schmoo_mask = 0x00800000;
+ break;
+ case 9:
+ l_schmoo_mask = 0x00400000;
+ break;
+ default:
+ o_cen_dq_dqs_rcv_imp_wc = l_cen_dq_dqs_rcv_imp[i_port];
+ }
+ if ((l_cen_dq_dqs_rcv_imp_schmoo[i_port] & l_schmoo_mask) != 0)
+ {
+ o_cen_dq_dqs_rcv_imp_wc = cen_rcv_imp_array[l_loop];
+ break;
}
}
-// write output attributes
- l_rc = FAPI_ATTR_SET(ATTR_MSS_POWER_SLOPE, &i_target, l_power_slope_array);
- if(l_rc) return l_rc;
- l_rc = FAPI_ATTR_SET(ATTR_MSS_POWER_INT, &i_target, l_power_int_array);
- if(l_rc) return l_rc;
- l_rc = FAPI_ATTR_SET(ATTR_MSS_THROTTLE_NUMERATOR, &i_target, l_dimm_throttle_n_array);
- if(l_rc) return l_rc;
- l_rc = FAPI_ATTR_SET(ATTR_MSS_THROTTLE_DENOMINATOR, &i_target, l_dimm_throttle_d_array);
- if(l_rc) return l_rc;
- l_rc = FAPI_ATTR_SET(ATTR_MSS_THROTTLE_CHANNEL_NUMERATOR, &i_target, l_channel_throttle_n_array);
- if(l_rc) return l_rc;
- l_rc = FAPI_ATTR_SET(ATTR_MSS_THROTTLE_CHANNEL_DENOMINATOR, &i_target, l_channel_throttle_d_array);
- if(l_rc) return l_rc;
+ l_schmoo_mask = 0x00000000;
+ for (l_loop=0; l_loop < MAX_CEN_DRV_IMP; l_loop++)
+ {
+ switch (l_loop)
+ {
+ case 0:
+ l_schmoo_mask = 0x80000000;
+ break;
+ case 1:
+ l_schmoo_mask = 0x40000000;
+ break;
+ case 2:
+ l_schmoo_mask = 0x20000000;
+ break;
+ case 3:
+ l_schmoo_mask = 0x10000000;
+ break;
+ case 4:
+ l_schmoo_mask = 0x08000000;
+ break;
+ case 5:
+ l_schmoo_mask = 0x04000000;
+ break;
+ case 6:
+ l_schmoo_mask = 0x02000000;
+ break;
+ case 7:
+ l_schmoo_mask = 0x01000000;
+ break;
+ case 8:
+ l_schmoo_mask = 0x00800000;
+ break;
+ case 9:
+ l_schmoo_mask = 0x00400000;
+ break;
+ case 10:
+ l_schmoo_mask = 0x00200000;
+ break;
+ case 11:
+ l_schmoo_mask = 0x00100000;
+ break;
+ case 12:
+ l_schmoo_mask = 0x00080000;
+ break;
+ case 13:
+ l_schmoo_mask = 0x00040000;
+ break;
+ case 14:
+ l_schmoo_mask = 0x00020000;
+ break;
+ case 15:
+ l_schmoo_mask = 0x00010000;
+ break;
+ default:
+ o_cen_dq_dqs_drv_imp_wc = l_cen_dq_dqs_drv_imp[i_port];
+ }
+ if ((l_cen_dq_dqs_drv_imp_schmoo[i_port] & l_schmoo_mask) != 0)
+ {
+ o_cen_dq_dqs_drv_imp_wc = cen_drv_imp_array[l_loop];
+ break;
+ }
+ }
- FAPI_INF("*** %s COMPLETE ***", procedure_name);
- return l_rc;
+ return rc;
}
+
+//------------------------------------------------------------------------------
+// @brief mss_eff_config_thermal_get_cen_drv_value(): This function will translate
+// the centaur driver impedance enum value to a termination resistance
+//
+// @param uint8_t &i_cen_dq_dqs_drv_imp: Centaur DQ/DQS driver impedance enum setting (input)
+// @param uint8_t &o_cen_dq_dqs_drv_imp: Centaur DQ/DQS driver impedance value (output)
+//
+// @return fapi::ReturnCode
+//------------------------------------------------------------------------------
+
+ fapi::ReturnCode mss_eff_config_thermal_get_cen_drv_value(
+ uint8_t i_cen_dq_dqs_drv_imp,
+ uint8_t &o_cen_dq_dqs_drv_imp
+ )
+ {
+ fapi::ReturnCode rc = fapi::FAPI_RC_SUCCESS;
+
+ switch (i_cen_dq_dqs_drv_imp)
+ {
+ case fapi::ENUM_ATTR_EFF_CEN_DRV_IMP_DQ_DQS_OHM24_FFE0:
+ o_cen_dq_dqs_drv_imp = 24;
+ break;
+ case fapi::ENUM_ATTR_EFF_CEN_DRV_IMP_DQ_DQS_OHM30_FFE0:
+ o_cen_dq_dqs_drv_imp = 30;
+ break;
+ case fapi::ENUM_ATTR_EFF_CEN_DRV_IMP_DQ_DQS_OHM30_FFE480:
+ o_cen_dq_dqs_drv_imp = 30;
+ break;
+ case fapi::ENUM_ATTR_EFF_CEN_DRV_IMP_DQ_DQS_OHM30_FFE240:
+ o_cen_dq_dqs_drv_imp = 30;
+ break;
+ case fapi::ENUM_ATTR_EFF_CEN_DRV_IMP_DQ_DQS_OHM30_FFE160:
+ o_cen_dq_dqs_drv_imp = 30;
+ break;
+ case fapi::ENUM_ATTR_EFF_CEN_DRV_IMP_DQ_DQS_OHM30_FFE120:
+ o_cen_dq_dqs_drv_imp = 30;
+ break;
+ case fapi::ENUM_ATTR_EFF_CEN_DRV_IMP_DQ_DQS_OHM34_FFE0:
+ o_cen_dq_dqs_drv_imp = 34;
+ break;
+ case fapi::ENUM_ATTR_EFF_CEN_DRV_IMP_DQ_DQS_OHM34_FFE480:
+ o_cen_dq_dqs_drv_imp = 34;
+ break;
+ case fapi::ENUM_ATTR_EFF_CEN_DRV_IMP_DQ_DQS_OHM34_FFE240:
+ o_cen_dq_dqs_drv_imp = 34;
+ break;
+ case fapi::ENUM_ATTR_EFF_CEN_DRV_IMP_DQ_DQS_OHM34_FFE160:
+ o_cen_dq_dqs_drv_imp = 34;
+ break;
+ case fapi::ENUM_ATTR_EFF_CEN_DRV_IMP_DQ_DQS_OHM34_FFE120:
+ o_cen_dq_dqs_drv_imp = 34;
+ break;
+ case fapi::ENUM_ATTR_EFF_CEN_DRV_IMP_DQ_DQS_OHM40_FFE0:
+ o_cen_dq_dqs_drv_imp = 40;
+ break;
+ case fapi::ENUM_ATTR_EFF_CEN_DRV_IMP_DQ_DQS_OHM40_FFE480:
+ o_cen_dq_dqs_drv_imp = 40;
+ break;
+ case fapi::ENUM_ATTR_EFF_CEN_DRV_IMP_DQ_DQS_OHM40_FFE240:
+ o_cen_dq_dqs_drv_imp = 40;
+ break;
+ case fapi::ENUM_ATTR_EFF_CEN_DRV_IMP_DQ_DQS_OHM40_FFE160:
+ o_cen_dq_dqs_drv_imp = 40;
+ break;
+ case fapi::ENUM_ATTR_EFF_CEN_DRV_IMP_DQ_DQS_OHM40_FFE120:
+ o_cen_dq_dqs_drv_imp = 40;
+ break;
+ default:
+ o_cen_dq_dqs_drv_imp = 24;
+ }
+
+ return rc;
+ }
+
+
} //end extern C
diff --git a/src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_eff_config_thermal.H b/src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_eff_config_thermal.H
index 0e5e395cf..f4d7c7861 100644
--- a/src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_eff_config_thermal.H
+++ b/src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_eff_config_thermal.H
@@ -20,7 +20,7 @@
/* Origin: 30 */
/* */
/* IBM_PROLOG_END_TAG */
-// $Id: mss_eff_config_thermal.H,v 1.3 2012/04/03 22:13:03 pardeik Exp $
+// $Id: mss_eff_config_thermal.H,v 1.4 2012/10/15 13:05:10 pardeik Exp $
// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/centaur/working/procedures/ipl/fapi/mss_eff_config_thermal.H,v $
//------------------------------------------------------------------------------
// *! (C) Copyright International Business Machines Corp. 2011
@@ -42,6 +42,7 @@
//------------------------------------------------------------------------------
// Version:| Author: | Date: | Comment:
//---------|----------|---------|-----------------------------------------------
+// 1.4 | pardeik |11-OCT-12| change i_target to i_target_mba
// 1.3 | pardeik |03-APR-12| use mba target instead of mbs
// 1.2 | pardeik |26-MAR-12| Removed structure (going into .C file)
// | pardeik |01-DEC-11| Added structures and defines
@@ -58,19 +59,19 @@
#include <fapi.H>
-typedef fapi::ReturnCode (*mss_eff_config_thermal_FP_t)(const fapi::Target & i_target);
+typedef fapi::ReturnCode (*mss_eff_config_thermal_FP_t)(const fapi::Target & i_target_mba);
extern "C" {
/**
* @brief mss_eff_config_thermal procedure. Sets up dimm power curve attributes and dimm and channel throttle attributes
*
- * @param[in] i_target Reference to centaur mba target
+ * @param[in] i_target_mba Reference to centaur mba target
*
* @return ReturnCode
*/
- fapi::ReturnCode mss_eff_config_thermal(const fapi::Target & i_target);
+ fapi::ReturnCode mss_eff_config_thermal(const fapi::Target & i_target_mba);
} //extern C
diff --git a/src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_eff_grouping.C b/src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_eff_grouping.C
index 66566da3e..48c356339 100644
--- a/src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_eff_grouping.C
+++ b/src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_eff_grouping.C
@@ -20,7 +20,7 @@
/* Origin: 30 */
/* */
/* IBM_PROLOG_END_TAG */
-// $Id: mss_eff_grouping.C,v 1.10 2012/09/27 11:11:53 bellows Exp $
+// $Id: mss_eff_grouping.C,v 1.16 2012/12/14 08:41:20 gpaulraj Exp $
//------------------------------------------------------------------------------
// *! (C) Copyright International Business Machines Corp. 2011
// *! All Rights Reserved -- Property of IBM
@@ -38,6 +38,11 @@
//------------------------------------------------------------------------------
// Version:| Author: | Date: | Comment:
//---------|----------|---------|-----------------------------------------------
+// 1.16 | gpaulraj | 12-14-12| Modified "unable to group dimm size" as Error message
+// 1.15 | bellows | 12-11-12| Picked up latest updates from Girisankar
+// 1.14 | bellows | 12-11-12| added ; to DBG line
+// 1.13 | bellows | 12-07-12| fix for interleaving attr and array bounds
+// 1.11 | bellows | 11-27-12| review updates
// 1.10 | bellows | 09-27-12| Additional Review Updates
// 1.9 | bellows | 09-25-12| updates from review, code from Girisankar
// 1.8 | bellows | 09-06-12| updates suggested by Van
@@ -66,7 +71,7 @@ extern "C" {
//----------------------------------------------------
ReturnCode mss_eff_grouping(const fapi::Target & i_target, std::vector<fapi::Target> & i_associated_centaurs); // Target is Proc target & Each MCS connected to each Centaur. Associated centaur is collection of the Centaure location for the processor
- uint8_t mss_eff_grouping_recursion(uint8_t number);
+ uint8_t mss_eff_grouping_recursion(uint32_t number);
//ReturnCode mba_collection(std::vector<fapi::Target> & associated_centaurs);
//ReturnCode mcs_grouping(const fapi::Target & target);
//ReturnCode mcs_grouping_general();
@@ -104,11 +109,12 @@ extern "C" {
std::vector<fapi::Target> & i_associated_centaurs
) {
ReturnCode rc;
- Eff_Grouping_Data eff_grouping_data;
+ Eff_Grouping_Data eff_grouping_data,tempgpID;
//Eff_Grouping_Data &eff_grouping_data;
//eff_grouping_data.groupID[16][16]={{0}};
- uint32_t pos=0;
+ //uint32_t pos=0;
uint64_t mss_base_address;
+ uint64_t mirror_base;
//uint32_t MBA_size[8][2]={{0}};
//uint32_t MCS_size[8]={0};
uint32_t l_unit_pos =0;
@@ -194,137 +200,298 @@ extern "C" {
FAPI_INF("MCS SIZE %d \n",eff_grouping_data.MCS_size[i]);
}
FAPI_INF("Group parsing Starting..");
- rc = FAPI_ATTR_GET(ATTR_MSS_INTERLEAVE_ENABLE,&i_target,min_group);
- if(!rc.ok()) {FAPI_ERR("MSS_INTERLEAV_ENABLE is not available"); return rc;}
- //rc=mcs_grouping_general();
- if(!rc.ok()) {FAPI_ERR("MCS Grouping: fails at generating the MCS size"); return rc;}
// groupID[i][0]=Size;
// groupID[i][1]= number of MBA in the group for example 4 MBA in the group
// groupID[i][2]= Total size of memory
// groupID[i][3] to groupIDsize[i][6] - group pos indication
- uint32_t temp[12];
- uint8_t min_group = 1;
- uint32_t max_group = 8;
- uint32_t mirroring =0;
- uint8_t pos_t=0;
+ // uint32_t temp[12];
uint8_t count=0;
- uint8_t onemcs=0;
- if ((((eff_grouping_data.MCS_size[0] == eff_grouping_data.MCS_size[4])
- && (eff_grouping_data.MCS_size[1] == eff_grouping_data.MCS_size[5]))
- &&(eff_grouping_data.MCS_size[3]==eff_grouping_data.MCS_size[4])
- &&(eff_grouping_data.MCS_size[5]==eff_grouping_data.MCS_size[6])
- &&((eff_grouping_data.MCS_size[2] == eff_grouping_data.MCS_size[6])
- &&(eff_grouping_data.MCS_size[3] ==eff_grouping_data.MCS_size[7])))
- && l_unit_pos==8)
- {
- eff_grouping_data.groupID[0][1] =4;
- eff_grouping_data.groupID[0][4] =0;
- eff_grouping_data.groupID[0][5] =2;
- eff_grouping_data.groupID[0][6] =1;
- eff_grouping_data.groupID[0][7] =3;
- eff_grouping_data.groupID[0][0] = eff_grouping_data.MCS_size[4];
- gp_pos=1;
- mirroring =1;
- FAPI_INF("Mirroring enabled\n");
- }
- else if ((((eff_grouping_data.MCS_size[0] == eff_grouping_data.MCS_size[1])
- &&(eff_grouping_data.MCS_size[0] == eff_grouping_data.MCS_size[4])
- &&(eff_grouping_data.MCS_size[4] == eff_grouping_data.MCS_size[5]))
- ||((eff_grouping_data.MCS_size[2] == eff_grouping_data.MCS_size[3])
- &&(eff_grouping_data.MCS_size[2] == eff_grouping_data.MCS_size[6])
- &&(eff_grouping_data.MCS_size[6] == eff_grouping_data.MCS_size[7])))
- && l_unit_pos==4)
- {
- eff_grouping_data.groupID[0][1] =2;
- eff_grouping_data.groupID[0][4] =4;
- eff_grouping_data.groupID[0][5] =5;
- eff_grouping_data.groupID[0][0] = eff_grouping_data.MCS_size[4];
- eff_grouping_data.groupID[1][1] =2;
- eff_grouping_data.groupID[1][4] =6;
- eff_grouping_data.groupID[1][5] =7;
- eff_grouping_data.groupID[1][0] = eff_grouping_data.MCS_size[5];
- gp_pos=2;
- mirroring =1;
- FAPI_INF("Mirroring enabled\n");
- }
- else
- {
- while(max_group>=min_group)
+ uint8_t done;
+ uint8_t pos;
+ uint8_t config_4MCS[6][4]={{0,1,4,5},{2,3,6,7},{0,1,6,7},{2,3,4,5},{0,1,2,3},{4,5,6,7}};
+ int flag;
+ uint8_t config4_pos[6];
+ uint8_t groups_allowed;
+ // uint8_t tempgpID.groupID[16][16];
+ uint8_t grouped[16];
+ uint8_t check_board;
+ uint8_t gp=0;
+ uint8_t pos1=0;
+ uint8_t pos2=0;
+ uint8_t allowed=0;
+
+
+
+ for(uint8_t i=0;i<6;i++)
+ config4_pos[i]=0;
+
+ rc = FAPI_ATTR_GET(ATTR_MSS_INTERLEAVE_ENABLE,&i_target,groups_allowed);
+ if(!rc.ok()) {FAPI_ERR("MSS_INTERLEAVE_ENABLE is not available"); return rc; }
+ rc = FAPI_ATTR_GET(ATTR_ALL_MCS_IN_INTERLEAVING_GROUP, NULL,check_board); // system level attribute
+ if (!rc.ok()) { FAPI_ERR("Error reading ATTR_ALL_MCS_IN_INTERLEAVING_GROUP"); return rc; }
+
+
+
+ for(uint8_t i=0;i<16;i++)
{
- for(uint8_t i=0;i<16;i++)
- for(uint8_t j=0;j<16;j++)
- eff_grouping_data.groupID[i][j]=0;
- gp_pos=0;
- count=0;
- for(pos=0;pos<8;pos++)
- {
- eff_grouping_data.groupID[gp_pos][0] = eff_grouping_data.MCS_size[pos];
- eff_grouping_data.groupID[gp_pos][1] = 1;
- eff_grouping_data.groupID[gp_pos][4]= pos;
- gp_pos++;
- }
- for(pos_t=0;pos_t<=gp_pos;pos_t++)
- {
- for(pos=pos_t+1; pos<=gp_pos;pos++)
- {
- if(eff_grouping_data.groupID[pos_t][0] == eff_grouping_data.groupID[pos][0])
- {
- if( eff_grouping_data.groupID[pos_t][1]<max_group)
+ grouped[i]=0;
+ for(uint8_t j=0;j<16;j++)
+ {
+ eff_grouping_data.groupID[i][j]=0;
+ tempgpID.groupID[i][j]=0;
+ }
+ }
+
+
+ gp_pos=0;
+
+ for(pos=0;pos<8;pos++)
+ {
+ eff_grouping_data.groupID[gp_pos][0] = eff_grouping_data.MCS_size[pos];
+ eff_grouping_data.groupID[gp_pos][1] = 1;
+ eff_grouping_data.groupID[gp_pos][4]= pos;
+
+ if(eff_grouping_data.MBA_size[pos][0]>eff_grouping_data.MBA_size[pos][1])
+ eff_grouping_data.groupID[gp_pos][15]= eff_grouping_data.MBA_size[pos][0];
+ else
+ eff_grouping_data.groupID[gp_pos][15]= eff_grouping_data.MBA_size[pos][1];
+
+ gp_pos++;
+ }
+
+
+ done = 0 ;
+ if(!done && (groups_allowed & 0x08) && check_board)
+ {
+
+ count =0;
+ for(pos=0;pos< gp_pos;pos++)
{
- eff_grouping_data.groupID[pos_t][1]++;
- eff_grouping_data.groupID[pos_t][eff_grouping_data.groupID[pos_t][1]+3]=pos;
+ if(eff_grouping_data.groupID[0][0] == eff_grouping_data.groupID[pos][0] && eff_grouping_data.groupID[pos][0] !=0)
+ {
+ count++;
+ }
+ }
+
+ if(count == 8)
+ {
+ done=1;
+ eff_grouping_data.groupID[0][1] = 8;
+ eff_grouping_data.groupID[0][4] = 0;
+ eff_grouping_data.groupID[0][5] = 4;
+ eff_grouping_data.groupID[0][6] = 1;
+ eff_grouping_data.groupID[0][7] = 5;
+ eff_grouping_data.groupID[0][8] = 2;
+ eff_grouping_data.groupID[0][9] = 6;
+ eff_grouping_data.groupID[0][10] = 3;
+ eff_grouping_data.groupID[0][11] = 7;
+ for(uint8_t i=1;i<16;i++)
+ for(uint8_t j=0;j<16;j++)
+ eff_grouping_data.groupID[i][j]=0;
+ }
+
+ }
+ if(!done && (groups_allowed & 0x04) && check_board)
+ {
+ count=0;
+ for(uint8_t i=0;i<6;i++)
+ {
+ flag=0;
+ for( int j=0;j<4;j++)
+ {
+ if((eff_grouping_data.groupID[config_4MCS[i][0]][0]== 0) || (eff_grouping_data.groupID[config_4MCS[i][0]][0] != eff_grouping_data.groupID[config_4MCS[i][j]][0]))
+ {
+ flag=1;
+ }
+ }
+ if(!flag)
+ {
+
+ config4_pos[i]=1;
+ count++;
+ }
+ }
+ if(count>=2)
+ {
+ if(config4_pos[0] && config4_pos[1])
+ {
+ allowed=1;
+ pos1=0;
+ pos2=1;
+ }
+ else if(config4_pos[2] && config4_pos[3])
+ {
+ allowed=1;
+ pos1=2;
+ pos2=3;
+ }
+ else if(config4_pos[4] && config4_pos[5])
+ {
+ allowed=1;
+ pos1=4;
+ pos2=5;
+ }
+ }
+ if(allowed)
+ {
+ done =1;
+ //define the group_data
+ eff_grouping_data.groupID[0][0] =eff_grouping_data.groupID[config_4MCS[pos1][0]][0];
+ eff_grouping_data.groupID[0][1] = 4;
+ eff_grouping_data.groupID[0][4] = config_4MCS[pos1][0];
+ eff_grouping_data.groupID[0][5] = config_4MCS[pos1][2];
+ eff_grouping_data.groupID[0][6] = config_4MCS[pos1][1];
+ eff_grouping_data.groupID[0][7] = config_4MCS[pos1][3];
+ eff_grouping_data.groupID[0][15] =eff_grouping_data.groupID[config_4MCS[pos1][0]][15];
+
+ eff_grouping_data.groupID[1][0] =eff_grouping_data.groupID[config_4MCS[pos2][0]][0];
+ eff_grouping_data.groupID[1][1] = 4;
+ eff_grouping_data.groupID[1][4] = config_4MCS[pos2][0];
+ eff_grouping_data.groupID[1][5] = config_4MCS[pos2][2];
+ eff_grouping_data.groupID[1][6] = config_4MCS[pos2][1];
+ eff_grouping_data.groupID[1][7] = config_4MCS[pos2][3];
+ eff_grouping_data.groupID[1][15] =eff_grouping_data.groupID[config_4MCS[pos2][0]][15];
+
+ for(uint8_t i=2;i<16;i++)
+ for(uint8_t j=0;j<16;j++)
+ eff_grouping_data.groupID[i][j]=0;
+ }
+ else if (count ==1 || !allowed )
+ {
+ for(uint8_t i=0;i<6;i++)
+ {
+ if(config4_pos[i])
+ {
+ allowed=1;
+ pos1=i;
+ break;
+ }
+ }
+ if(allowed)
+ {
+ //define the group_data
+ tempgpID.groupID[0][0] = eff_grouping_data.groupID[config_4MCS[pos1][0]][0];
+ tempgpID.groupID[0][1] = 4;
+ tempgpID.groupID[0][4] = config_4MCS[pos1][0];
+ tempgpID.groupID[0][5] = config_4MCS[pos1][2];
+ tempgpID.groupID[0][6] = config_4MCS[pos1][1];
+ tempgpID.groupID[0][7] = config_4MCS[pos1][3];
+ tempgpID.groupID[0][15] = eff_grouping_data.groupID[config_4MCS[pos1][0]][15];
+ gp++;
+ for(int i=0; i<4;i++)
+ {
+ eff_grouping_data.groupID[config_4MCS[pos1][i]][0]=0;
+ grouped[config_4MCS[config4_pos[0]][i]]=1;
+ }
+ }
+ }
+ }
+ if(!done && (groups_allowed & 0x02) && check_board)
+ {
+ for(pos=0;pos< gp_pos;pos=pos+2)
+ {
+ if(eff_grouping_data.groupID[pos][0] == eff_grouping_data.groupID[pos+1][0] && eff_grouping_data.groupID[pos][0] !=0 )
+ {
+ //group
+ tempgpID.groupID[gp][0] =eff_grouping_data.groupID[pos][0] ;
+ tempgpID.groupID[gp][1] = 2;
+ tempgpID.groupID[gp][4] = pos;
+ tempgpID.groupID[gp][5] = pos+1;
+ tempgpID.groupID[gp][15] =eff_grouping_data.groupID[pos][15] ;
+ grouped[pos]=1;
+ grouped[pos+1]=1;
eff_grouping_data.groupID[pos][0]=0;
- eff_grouping_data.groupID[pos][1]=0;
- }
- else {}
+ eff_grouping_data.groupID[pos+1][0]=0;
+ gp++;
+ }
+ }
+ }
+ if(!done && (groups_allowed & 0x01)&& !check_board)
+ {
+ for(pos=0;pos< gp_pos;pos++)
+ {
+ if(eff_grouping_data.groupID[pos][0] !=0 )
+ {
+ //group
+ tempgpID.groupID[gp][0] =eff_grouping_data.groupID[pos][0] ;
+ tempgpID.groupID[gp][1] = 1;
+ tempgpID.groupID[gp][4] = pos;
+ tempgpID.groupID[gp][15] =eff_grouping_data.groupID[pos][15] ;
+ grouped[pos]=1;
+ eff_grouping_data.groupID[pos][0]=0;
+ gp++;
+ }
+ }
+ }
+ if(!done)
+ {
+ for(uint8_t i=0;i<8;i++)
+ {
+ if(grouped[i] !=1 && eff_grouping_data.groupID[i][0] != 0 )
+ FAPI_ERR ("UNABLE TO GROUP MCS%d size is %d", i,eff_grouping_data.groupID[i][0]);
}
- }
- }
- for(uint8_t i=0;i<8;i++)
- {
- if ((eff_grouping_data.groupID[i][0]!= 0) && (eff_grouping_data.groupID[i][1] == max_group))
- { count += eff_grouping_data.groupID[i][1];FAPI_INF("group ID %dMCS size %d\n",i,eff_grouping_data.groupID[i][1]);}
- }
- if (count == l_unit_pos) { FAPI_INF("group done correctly\n");onemcs=0;break;}
- else{ FAPI_INF("this grouping is not possible with %d\n",max_group);onemcs=0;}
- max_group= max_group/2;
- }
- }
- // uint32_t temp[12];
+
+ for(uint8_t i=0;i<gp;i++)
+ for(uint8_t j=0;j<16;j++)
+ eff_grouping_data.groupID[i][j]=tempgpID.groupID[i][j];
+
+ for(uint8_t i=gp ; i<8 ; i++)
+ for(uint8_t j=0;j<16;j++)
+ eff_grouping_data.groupID[i][j]=0;
+ }
+ flag=0;
+ for(uint8_t i=0;i<16;i++)
+ if(grouped[i])
+ flag=1;
+ gp_pos=0;
+ if(done || flag)
+ {
+ for(uint8_t i=0;i<16;i++)
+ {
+ if( eff_grouping_data.groupID[i][0] !=0)
+ {
+ gp_pos++;
+ FAPI_INF(" group no= %d , num of MCS = %d , size of MCS = %d \n ", i,eff_grouping_data.groupID[i][1],eff_grouping_data.groupID[i][0]);
+ for(uint8_t k=0 ; k< eff_grouping_data.groupID[i][1];k++)
+ {
+ FAPI_INF("MCSID%d = %d \n ", k, eff_grouping_data.groupID[i][4+k]);
+ }
+ }
+ }
+ }
+ uint32_t temp[16];
uint8_t i=0;
uint8_t j=0;
- //uint8_t count=0;
- for(i=0;i<8;i++)
- {
- for(j=0;j<12;j++)
- {
- FAPI_INF(" groupID[%d][%d] = %d",i,j,eff_grouping_data.groupID[i][j]);
- }
- FAPI_INF("\n");
- }
- for(pos=0;pos<=gp_pos;pos++)
+ count=0;
+
+ for(pos=0;pos<=gp_pos;pos++)
{
eff_grouping_data.groupID[pos][2] = eff_grouping_data.groupID[pos][0]*eff_grouping_data.groupID[pos][1];
+ //eff_grouping_data.groupID[pos+8][2]= eff_grouping_data.groupID[pos][2]/2; // group size when mirrored
+
count = mss_eff_grouping_recursion(eff_grouping_data.groupID[pos][2]);
if(count>1)
{
FAPI_INF("MCS pos %d needs alternate bars defintation group Size %d\n",pos,eff_grouping_data.groupID[pos][3]);
- if (eff_grouping_data.MBA_size[pos][1] > eff_grouping_data.MBA_size[pos][0])
- {
- eff_grouping_data.groupID[pos][2] = eff_grouping_data.MBA_size[pos][1]*2*eff_grouping_data.groupID[pos][1];
- eff_grouping_data.groupID[pos][13] = eff_grouping_data.groupID[pos][1]*eff_grouping_data.MBA_size[pos][1];
- }
- else
- {
- eff_grouping_data.groupID[pos][2] = eff_grouping_data.MBA_size[pos][0]*2*eff_grouping_data.groupID[pos][1];
- eff_grouping_data.groupID[pos][13] = eff_grouping_data.groupID[pos][1]*eff_grouping_data.MBA_size[pos][0];
- }
- eff_grouping_data.groupID[pos][12] =1;
- }
+
+
+
+ eff_grouping_data.groupID[pos][2] = eff_grouping_data.groupID[pos][15]*2*eff_grouping_data.groupID[pos][1];
+ eff_grouping_data.groupID[pos][13] = eff_grouping_data.groupID[pos][1]*(eff_grouping_data.groupID[pos][0]-eff_grouping_data.groupID[pos][15]);
+
+ //mirrored group
+ //eff_grouping_data.groupID[pos+8][2] = eff_grouping_data.groupID[pos][2]/2; //group size with alternate bars
+ //eff_grouping_data.groupID[pos+8][13] = eff_grouping_data.groupID[pos][13]/2;
+ eff_grouping_data.groupID[pos][12] =1;
+ }
}
- for(pos=0;pos<=gp_pos;pos++)
+ for(i=0;i<gp_pos;i++)
{
- eff_grouping_data.groupID[pos][2] = eff_grouping_data.groupID[pos][0]*eff_grouping_data.groupID[pos][1];
+ for(j=0;j<12;j++)
+ {
+ FAPI_INF(" groupID[%d][%d] = %d",i,j,eff_grouping_data.groupID[i][j]);
+ }
+ FAPI_INF("\n");
}
for(pos=0;pos<=gp_pos;pos++)
{
@@ -332,37 +499,102 @@ extern "C" {
{
if ( eff_grouping_data.groupID[i][2] > eff_grouping_data.groupID[pos][2])
{
- for(j=0;j<12;j++) temp[j] = eff_grouping_data.groupID[pos][j];
- for(j=0;j<12;j++) eff_grouping_data.groupID[pos][j] = eff_grouping_data.groupID[i][j];
- for(j=0;j<12;j++) eff_grouping_data.groupID[i][j] = temp[j];
+ for(j=0;j<16;j++) temp[j] = eff_grouping_data.groupID[pos][j];
+ for(j=0;j<16;j++) eff_grouping_data.groupID[pos][j] = eff_grouping_data.groupID[i][j];
+ for(j=0;j<16;j++) eff_grouping_data.groupID[i][j] = temp[j];
}
else {}
- }
- }
+ }
+ }
+
+
+ // calcutate mirrored group size
+ for(pos=0;pos<gp_pos;pos++)
+ {
+ if(eff_grouping_data.groupID[pos][0]!=0 && eff_grouping_data.groupID[pos][1]>1 )
+ {
+ eff_grouping_data.groupID[pos+8][2]= eff_grouping_data.groupID[pos][2]/2; // group size when mirrored
+
+
+ if(eff_grouping_data.groupID[pos][12])
+ {
+ FAPI_INF("Mirrored group pos %d needs alternate bars defintation group Size %d\n",pos,eff_grouping_data.groupID[pos][3]);
+ //mirrored group
+ eff_grouping_data.groupID[pos+8][2] = eff_grouping_data.groupID[pos][2]/2; //group size with alternate bars
+ eff_grouping_data.groupID[pos+8][13] = eff_grouping_data.groupID[pos][13]/2;
+
+ }
+ }
+ }
+
rc = FAPI_ATTR_GET(ATTR_PROC_MEM_BASE,&i_target,mss_base_address);
mss_base_address = mss_base_address >> 30;
if(!rc.ok()) return rc;
- for(pos=0;pos<=gp_pos;pos++)
+
+ rc = FAPI_ATTR_GET(ATTR_PROC_MIRROR_BASE,&i_target,mirror_base);
+ mirror_base = mirror_base >> 30;
+
+ if(!rc.ok()) return rc;
+
+ for(pos=0;pos<gp_pos;pos++)
{
if(pos==0)
{
- eff_grouping_data.groupID[pos][3] = mss_base_address;
+
+ eff_grouping_data.groupID[pos][3] =mss_base_address;
+ eff_grouping_data.groupID[pos+8][3]=mirror_base; //mirrored base address
if(eff_grouping_data.groupID[pos][12])
{
- eff_grouping_data.groupID[pos][14] = eff_grouping_data.groupID[pos][3]+ eff_grouping_data.groupID[pos][2];
+
+ eff_grouping_data.groupID[pos][14] = eff_grouping_data.groupID[pos][3]+ eff_grouping_data.groupID[pos][2]/2;
+ eff_grouping_data.groupID[pos+8][14] = eff_grouping_data.groupID[pos+8][3]+ eff_grouping_data.groupID[pos+8][2]/2; //mirrored base address with alternate bars
}
}
else
{
eff_grouping_data.groupID[pos][3] = eff_grouping_data.groupID[pos-1][3]+eff_grouping_data.groupID[pos-1][2];
+ eff_grouping_data.groupID[pos+8][3]= eff_grouping_data.groupID[pos-1+8][3]+eff_grouping_data.groupID[pos-1+8][2];
+
if(eff_grouping_data.groupID[pos][12])
{
- eff_grouping_data.groupID[pos][14] = eff_grouping_data.groupID[pos][3]+ eff_grouping_data.groupID[pos][2];
+ eff_grouping_data.groupID[pos][14] = eff_grouping_data.groupID[pos][3]+ eff_grouping_data.groupID[pos][2]/2;
+ eff_grouping_data.groupID[pos+8][14] = eff_grouping_data.groupID[pos+8][3]+ eff_grouping_data.groupID[pos+8][2]/2; //mirrored base address with alternate bars
}
}
}
+ ecmdDataBufferBase MC_IN_GP(8);
+ uint8_t mcs_in_group[8];
+ for(uint8_t i=0;i<8;i++)
+ mcs_in_group[i]=0;
+ for(uint8_t i=0;i<gp_pos;i++)
+ {
+ count=0;
+ MC_IN_GP.flushTo0();
+ if(eff_grouping_data.groupID[i][0]!=0)
+ {
+ count = eff_grouping_data.groupID[i][1];
+ for(uint8_t j=0;j<count;j++)
+ MC_IN_GP.setBit(eff_grouping_data.groupID[i][4+j]);
+ mcs_in_group[i]= MC_IN_GP.getByte(0);
+ }
+ }
+ FAPI_DBG(" ATTR_MSS_MEM_MC_IN_GROUP[0]: 0x%x", mcs_in_group[0]);
+ FAPI_DBG(" ATTR_MSS_MEM_MC_IN_GROUP[1]: 0x%x", mcs_in_group[1]);
+ FAPI_DBG(" ATTR_MSS_MEM_MC_IN_GROUP[2]: 0x%x", mcs_in_group[2]);
+ FAPI_DBG(" ATTR_MSS_MEM_MC_IN_GROUP[3]: 0x%x", mcs_in_group[3]);
+ FAPI_DBG(" ATTR_MSS_MEM_MC_IN_GROUP[4]: 0x%x", mcs_in_group[4]);
+ FAPI_DBG(" ATTR_MSS_MEM_MC_IN_GROUP[5]: 0x%x", mcs_in_group[5]);
+ FAPI_DBG(" ATTR_MSS_MEM_MC_IN_GROUP[6]: 0x%x", mcs_in_group[6]);
+ FAPI_DBG(" ATTR_MSS_MEM_MC_IN_GROUP[7]: 0x%x", mcs_in_group[7]);
+
+ rc= FAPI_ATTR_SET(ATTR_MSS_MEM_MC_IN_GROUP, &i_target, mcs_in_group);
+ if (!rc.ok())FAPI_ERR("Error writing ATTR_MSS_MEM_MC_IN_GROUP");
+
uint64_t mem_bases[8];
uint64_t l_memory_sizes[8];
+ //uint64_t mirror_base;
+ uint64_t mirror_bases[4];
+ uint64_t l_mirror_sizes[4];
//uint32_t temp[8];
for(uint8_t i=0;i<8;i++)
{
@@ -372,11 +604,17 @@ extern "C" {
FAPI_INF (" No of MCS %4d ",eff_grouping_data.groupID[i][1]);
FAPI_INF (" Group Size %4d ",eff_grouping_data.groupID[i][2]);
FAPI_INF (" Base Add. %4d ",eff_grouping_data.groupID[i][3]);
+ FAPI_INF (" Mirrored Group SIze %4d", eff_grouping_data.groupID[i+8][2]);
+ FAPI_INF (" Mirror Base Add %4d", eff_grouping_data.groupID[i+8][3]);
for(uint8_t j=4;j<4+eff_grouping_data.groupID[i][1];j++)
{
FAPI_INF (" MCSID%d- Pos %4d",(j-4),eff_grouping_data.groupID[i][j]);
}
FAPI_INF (" Alter-bar %4d",eff_grouping_data.groupID[i][12]);
+ FAPI_INF("Alter-bar base add = %4d",eff_grouping_data.groupID[i][14]);
+ FAPI_INF("Alter-bar size = %4d",eff_grouping_data.groupID[i][13]);
+ FAPI_INF("Alter-bar Mirrored Base add = %4d", eff_grouping_data.groupID[i+8][14]);
+ FAPI_INF("Alter-bar Mirrored size = %4d", eff_grouping_data.groupID[i+8][13]);
}
else
{
@@ -465,18 +703,88 @@ extern "C" {
FAPI_ERR("Error writing ATTR_PROC_MEM_SIZES");
break;
}
- rc = FAPI_ATTR_SET(ATTR_MSS_MCS_GROUP_32,&i_target,eff_grouping_data.groupID);
+ rc = FAPI_ATTR_GET(ATTR_PROC_MEM_SIZES, &i_target, l_memory_sizes);
+ if (!rc.ok())
+ {
+ FAPI_ERR("Error writing ATTR_PROC_MEM_SIZES");
+ break;
+ }
+ FAPI_DBG(" ATTR_PROC_MEM_SIZES[0]: %016llx", l_memory_sizes[0]);
+ FAPI_DBG(" ATTR_PROC_MEM_SIZES[1]: %016llx", l_memory_sizes[1]);
+ FAPI_DBG(" ATTR_PROC_MEM_SIZES[2]: %016llx", l_memory_sizes[2]);
+ FAPI_DBG(" ATTR_PROC_MEM_SIZES[3]: %016llx", l_memory_sizes[3]);
+ FAPI_DBG(" ATTR_PROC_MEM_SIZES[4]: %016llx", l_memory_sizes[4]);
+ FAPI_DBG(" ATTR_PROC_MEM_SIZES[5]: %016llx", l_memory_sizes[5]);
+ FAPI_DBG(" ATTR_PROC_MEM_SIZES[6]: %016llx", l_memory_sizes[6]);
+ FAPI_DBG(" ATTR_PROC_MEM_SIZES[7]: %016llx", l_memory_sizes[7]);
+
+ rc = FAPI_ATTR_SET(ATTR_MSS_MCS_GROUP_32,&i_target, eff_grouping_data.groupID);
if (!rc.ok())
{
FAPI_ERR("Error writing ATTR_MSS_MCS_GROUP");
break;
}
+ // process mirrored ranges
+ //
+
+ // read chip base address attribute
+/// rc = FAPI_ATTR_GET(ATTR_PROC_MIRROR_BASE, &i_chip_target, mirror_base);
+// if (!rc.ok())
+// {
+// FAPI_ERR("Error reading ATTR_PROC_MIRROR_BASE");
+// break;
+// }
+
+ // base addresses for distinct mirrored ranges
+ mirror_bases[0] = eff_grouping_data.groupID[8][3];
+ mirror_bases[1] = eff_grouping_data.groupID[9][3];
+ mirror_bases[2] = eff_grouping_data.groupID[10][3];
+ mirror_bases[3] = eff_grouping_data.groupID[11][3];
+
+ mirror_bases[0] = mirror_bases[0]<<30;
+ mirror_bases[1] = mirror_bases[1]<<30;
+ mirror_bases[2] = mirror_bases[2]<<30;
+ mirror_bases[3] = mirror_bases[3]<<30;
+ FAPI_DBG(" ATTR_PROC_MIRROR_BASES[0]: %016llx", mirror_bases[0]);
+ FAPI_DBG(" ATTR_PROC_MIRROR_BASES[1]: %016llx", mirror_bases[1]);
+ FAPI_DBG(" ATTR_PROC_MIRROR_BASES[2]: %016llx", mirror_bases[2]);
+ FAPI_DBG(" ATTR_PROC_MIRROR_BASES[3]: %016llx", mirror_bases[3]);
+
+ rc = FAPI_ATTR_SET(ATTR_PROC_MIRROR_BASES, &i_target, mirror_bases);
+ if (!rc.ok())
+ {
+ FAPI_ERR("Error writing ATTR_PROC_MIRROR_BASES");
+ break;
+ }
+
+ // sizes for distinct mirrored ranges
+ l_mirror_sizes[0]=eff_grouping_data.groupID[8][2];
+ l_mirror_sizes[1]=eff_grouping_data.groupID[9][2];
+ l_mirror_sizes[2]=eff_grouping_data.groupID[10][2];
+ l_mirror_sizes[3]=eff_grouping_data.groupID[11][2];
+
+ l_mirror_sizes[0] = l_mirror_sizes[0]<<30;
+ l_mirror_sizes[1] = l_mirror_sizes[1]<<30;
+ l_mirror_sizes[2] = l_mirror_sizes[2]<<30;
+ l_mirror_sizes[3] = l_mirror_sizes[3]<<30;
+
+ FAPI_DBG(" ATTR_PROC_MIRROR_SIZES[0]: %016llx", l_mirror_sizes[0]);
+ FAPI_DBG(" ATTR_PROC_MIRROR_SIZES[1]: %016llx", l_mirror_sizes[1]);
+ FAPI_DBG(" ATTR_PROC_MIRROR_SIZES[2]: %016llx", l_mirror_sizes[2]);
+ FAPI_DBG(" ATTR_PROC_MIRROR_SIZES[3]: %016llx", l_mirror_sizes[3]);
+
+ rc = FAPI_ATTR_SET(ATTR_PROC_MIRROR_SIZES, &i_target, l_mirror_sizes);
+ if (!rc.ok())
+ {
+ FAPI_ERR("Error writing ATTR_PROC_MIRROR_SIZES");
+ break;
+ }
}while(0);
return rc;
}
- uint8_t mss_eff_grouping_recursion(uint8_t number){
- uint8_t temp = number;
+ uint8_t mss_eff_grouping_recursion(uint32_t number){
+ uint32_t temp = number;
uint8_t count=0;
uint8_t buffersize=0;
while(1)
diff --git a/src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_throttle_to_power.C b/src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_throttle_to_power.C
new file mode 100644
index 000000000..b8c1211dd
--- /dev/null
+++ b/src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_throttle_to_power.C
@@ -0,0 +1,293 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_throttle_to_power.C $ */
+/* */
+/* IBM CONFIDENTIAL */
+/* */
+/* COPYRIGHT International Business Machines Corp. 2012 */
+/* */
+/* p1 */
+/* */
+/* Object Code Only (OCO) source materials */
+/* Licensed Internal Code Source Materials */
+/* IBM HostBoot Licensed Internal Code */
+/* */
+/* The source code for this program is not published or otherwise */
+/* divested of its trade secrets, irrespective of what has been */
+/* deposited with the U.S. Copyright Office. */
+/* */
+/* Origin: 30 */
+/* */
+/* IBM_PROLOG_END_TAG */
+// $Id: mss_throttle_to_power.C,v 1.8 2012/10/31 13:40:27 pardeik Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/centaur/working/procedures/ipl/fapi/mss_throttle_to_power.C,v $
+//------------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2011
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//------------------------------------------------------------------------------
+// *! TITLE : mss_throttle_to_power
+// *! DESCRIPTION : see additional comments below
+// *! OWNER NAME : Joab Henderson Email: joabhend@us.ibm.com
+// *! BACKUP NAME : Michael Pardeik Email: pardeik@us.ibm.com
+// *! ADDITIONAL COMMENTS :
+//
+// applicable CQ component memory_screen
+//
+// DESCRIPTION:
+// The purpose of this procedure is to set the power attributes for each dimm and channel pair
+//
+//------------------------------------------------------------------------------
+// Don't forget to create CVS comments when you check in your changes!
+//------------------------------------------------------------------------------
+// CHANGE HISTORY:
+//------------------------------------------------------------------------------
+// Version:| Author: | Date: | Comment:
+//---------|----------|---------|-----------------------------------------------
+// 1.8 | pardeik |25-OCT-12| updated FAPI_ERR sections, added CQ component comment line
+// 1.7 | pardeik |19-OCT-12| use ATTR_MSS_CHANNEL_PAIR_MAXPOWER instead of ATTR_MSS_CHANNEL_MAXPOWER
+// | pardeik |19-OCT-12| multiple throttle N values by 4 to get dram utilization
+// 1.6 | pardeik |11-OCT-12| updated to use new throttle attributes, made function mss_throttle_to_power_calc
+// 1.5 | pardeik |10-APR-12| power calculation updates and fixes
+// 1.5 | pardeik |10-APR-12| power calculation updates and fixes
+// 1.4 | pardeik |04-APR-12| moved cdimm power calculation to end of section instead of having it in multiple places
+// 1.3 | pardeik |04-APR-12| use else if instead of if after checking throttle denominator to zero
+// 1.2 | pardeik |03-APR-12| use mba target intead of mbs, added cdimm power calculation for half of cdimm
+// 1.1 | pardeik |01-APR-11| Updated to use attributes and fapi functions to loop through ports/dimms
+// | pardeik |01-DEC-11| First Draft.
+
+
+//------------------------------------------------------------------------------
+// My Includes
+//------------------------------------------------------------------------------
+#include <mss_throttle_to_power.H>
+
+//----------------------------------------------------------------------
+// Includes
+//----------------------------------------------------------------------
+#include <fapi.H>
+
+
+extern "C" {
+
+ using namespace fapi;
+
+
+//------------------------------------------------------------------------------
+// Funtions in this file
+//------------------------------------------------------------------------------
+ fapi::ReturnCode mss_throttle_to_power(const fapi::Target & i_target_mba);
+
+ fapi::ReturnCode mss_throttle_to_power_calc(
+ const fapi::Target &i_target_mba,
+ uint32_t i_throttle_n_per_mba,
+ uint32_t i_throttle_n_per_chip,
+ uint32_t i_throttle_d,
+ float &channel_pair_power
+ );
+
+
+//------------------------------------------------------------------------------
+// @brief mss_throttle_to_power(): This function will get the throttle attributes and call another function to determine the dimm and channel pair power based on those throttles
+//
+// @param const fapi::Target &i_target_mba: MBA Target
+//
+// @return fapi::ReturnCode
+//------------------------------------------------------------------------------
+
+ fapi::ReturnCode mss_throttle_to_power(const fapi::Target & i_target_mba)
+ {
+ fapi::ReturnCode rc = fapi::FAPI_RC_SUCCESS;
+
+ char procedure_name[32];
+ sprintf(procedure_name, "mss_throttle_to_power");
+ FAPI_INF("*** Running %s ***", procedure_name);
+
+ uint32_t throttle_n_per_mba;
+ uint32_t throttle_n_per_chip;
+ uint32_t throttle_d;
+ float channel_pair_power;
+
+// Get input attributes
+ rc = FAPI_ATTR_GET(ATTR_MSS_MEM_THROTTLE_NUMERATOR_PER_MBA, &i_target_mba, throttle_n_per_mba);
+ if(rc) return rc;
+ rc = FAPI_ATTR_GET(ATTR_MSS_MEM_THROTTLE_NUMERATOR_PER_CHIP, &i_target_mba, throttle_n_per_chip);
+ if(rc) return rc;
+ rc = FAPI_ATTR_GET(ATTR_MSS_MEM_THROTTLE_DENOMINATOR, &i_target_mba, throttle_d);
+ if(rc) return rc;
+
+// Call function mss_throttle_to_power_calc
+ rc = mss_throttle_to_power_calc(
+ i_target_mba,
+ throttle_n_per_mba,
+ throttle_n_per_chip,
+ throttle_d,
+ channel_pair_power
+ );
+ if(rc)
+ {
+ FAPI_ERR("Error (0x%x) calling mss_throttle_to_power_calc", static_cast<uint32_t>(rc));
+ return rc;
+ }
+
+ FAPI_INF("*** %s COMPLETE ***", procedure_name);
+ return rc;
+
+ }
+
+
+
+//------------------------------------------------------------------------------
+// @brief mss_throttle_to_power_calc(): This function will calculate the dimm and channel pair power and update attributes with the power values
+//
+// @param const fapi::Target &i_target_mba: MBA Target
+// @param uint32_t i_throttle_n_per_mba: Throttle value for cfg_nm_n_per_mba
+// @param uint32_t i_throttle_n_per_chip: Throttle value for cfg_nm_n_per_chip
+// @param uint32_t i_throttle_d: Throttle value for cfg_nm_m
+// @param float &o_channel_pair_power: channel pair power at these throttle settings
+//
+// @return fapi::ReturnCode
+//------------------------------------------------------------------------------
+
+ fapi::ReturnCode mss_throttle_to_power_calc(
+ const fapi::Target &i_target_mba,
+ uint32_t i_throttle_n_per_mba,
+ uint32_t i_throttle_n_per_chip,
+ uint32_t i_throttle_d,
+ float &o_channel_pair_power
+ )
+ {
+ fapi::ReturnCode rc = fapi::FAPI_RC_SUCCESS;
+
+ const uint8_t MAX_NUM_PORTS = 2; // number of ports per MBA
+ const uint8_t MAX_NUM_DIMMS = 2; // number of dimms per MBA port
+// If this is changed, also change mss_bulk_pwr_throttles MAX_UTIL
+ const float MAX_UTIL = 75; // Maximum theoretical data bus utilization (percent of max) (for ceiling)
+
+ uint32_t l_power_slope_array[MAX_NUM_PORTS][MAX_NUM_DIMMS];
+ uint32_t l_power_int_array[MAX_NUM_PORTS][MAX_NUM_DIMMS];
+ uint8_t l_dimm_ranks_array[MAX_NUM_PORTS][MAX_NUM_DIMMS];
+ uint8_t l_port;
+ uint8_t l_dimm;
+ float l_dimm_power_array[MAX_NUM_PORTS][MAX_NUM_DIMMS];
+ uint32_t l_dimm_power_array_integer[MAX_NUM_PORTS][MAX_NUM_DIMMS];
+ float l_utilization;
+ float l_channel_power_array[MAX_NUM_PORTS];
+ uint32_t l_channel_power_array_integer[MAX_NUM_PORTS];
+ uint32_t l_channel_pair_power_integer;
+ uint8_t l_num_dimms_on_port;
+
+// get input attributes
+ rc = FAPI_ATTR_GET(ATTR_MSS_POWER_SLOPE, &i_target_mba, l_power_slope_array);
+ if(rc) return rc;
+ rc = FAPI_ATTR_GET(ATTR_MSS_POWER_INT, &i_target_mba, l_power_int_array);
+ if(rc) return rc;
+ rc = FAPI_ATTR_GET(ATTR_EFF_NUM_RANKS_PER_DIMM, &i_target_mba, l_dimm_ranks_array);
+ if(rc) return rc;
+ rc = FAPI_ATTR_GET(ATTR_EFF_NUM_DROPS_PER_PORT, &i_target_mba, l_num_dimms_on_port);
+ if(rc) return rc;
+
+// add up the power from all dimms for this MBA (across both channels) using the throttle values
+ o_channel_pair_power = 0;
+ l_channel_pair_power_integer = 0;
+ for (l_port = 0; l_port < MAX_NUM_PORTS; l_port++)
+ {
+ l_channel_power_array[l_port] = 0;
+ l_channel_power_array_integer[l_port] = 0;
+ for (l_dimm=0; l_dimm < MAX_NUM_DIMMS; l_dimm++)
+ {
+// default dimm power is zero (used for dimms that are not physically present)
+ l_dimm_power_array[l_port][l_dimm] = 0;
+ l_dimm_power_array_integer[l_port][l_dimm] = 0;
+ l_utilization = 0;
+// See if there are any ranks present on the dimm (configured or deconfigured)
+ if (l_dimm_ranks_array[l_port][l_dimm] > 0)
+ {
+// N/M throttling has the dimm0 and dimm1 throttles the same for DIMM level throttling, which we plan to use
+// MBA or chip level throttling could limit the commands to a dimm (used along with the dimm level throttling)
+// If MBA/chip throttle is less than dimm throttle, then use MBA/chip throttle
+// If MBA/chip throttle is greater than dimm throttle, then use the dimm throttle
+// If either of these are above the MAX_UTIL, then use MAX_UTIL
+// Get power from each dimm here
+// Note that the MAX_UTIL effectively is the percent of maximum bandwidth for that dimm
+
+ if (i_throttle_d == 0)
+ {
+ // throttle denominator is zero (N/M throttling disabled), set dimm power to the maximum
+ FAPI_DBG("N/M Throttling is disabled (M=0). Use Max DIMM Power");
+ l_dimm_power_array[l_port][l_dimm] = (l_power_slope_array[l_port][l_dimm] * ((float)MAX_UTIL / 100) + l_power_int_array[l_port][l_dimm]);
+ l_utilization = (float)MAX_UTIL;
+ }
+ else if ((((float)i_throttle_n_per_mba * 100 * 4) / i_throttle_d * l_num_dimms_on_port) > (((float)i_throttle_n_per_chip * 100 * 4) / i_throttle_d))
+ {
+ // limited by the mba/chip throttles (ie. cfg_nm_n_per_chip)
+ if ((((float)i_throttle_n_per_chip * 100 * 4) / i_throttle_d) > MAX_UTIL)
+ {
+ // limited by the maximum utilization
+ l_dimm_power_array[l_port][l_dimm] = (l_power_slope_array[l_port][l_dimm] * ((float)MAX_UTIL / 100) + l_power_int_array[l_port][l_dimm]);
+ l_utilization = (float)MAX_UTIL;
+ }
+ else
+ {
+ // limited by the per chip throttles
+ l_dimm_power_array[l_port][l_dimm] = (l_power_slope_array[l_port][l_dimm] * (((float)i_throttle_n_per_chip * 4) / i_throttle_d) + l_power_int_array[l_port][l_dimm]);
+ l_utilization = (((float)i_throttle_n_per_chip * 100 * 4) / i_throttle_d);
+ }
+ }
+ else
+ {
+ // limited by the per mba throttles (ie. cfg_nm_n_per_mba)
+ if ((((float)i_throttle_n_per_mba * 100 * 4) / i_throttle_d * l_num_dimms_on_port) > MAX_UTIL)
+ {
+ // limited by the maximum utilization
+ l_dimm_power_array[l_port][l_dimm] = (l_power_slope_array[l_port][l_dimm] * ((float)MAX_UTIL / 100) + l_power_int_array[l_port][l_dimm]);
+ l_utilization = (float)MAX_UTIL;
+ }
+ else
+ {
+ // limited by the per mba throttles
+ // multiply by number of dimms on port since other dimm has same throttle value
+ l_dimm_power_array[l_port][l_dimm] = (l_power_slope_array[l_port][l_dimm] * (((float)i_throttle_n_per_mba * 4) / i_throttle_d * l_num_dimms_on_port) + l_power_int_array[l_port][l_dimm]);
+ l_utilization = (((float)i_throttle_n_per_mba * 100 * 4) / i_throttle_d * l_num_dimms_on_port);
+ }
+ }
+ }
+// Get dimm power in integer format (add on 1 since value will get truncated)
+ if (l_dimm_power_array[l_port][l_dimm] > 0)
+ {
+ l_dimm_power_array_integer[l_port][l_dimm] = (int)l_dimm_power_array[l_port][l_dimm] + 1;
+ }
+// calculate channel power by adding up the power of each dimm
+ l_channel_power_array[l_port] = l_channel_power_array[l_port] + l_dimm_power_array[l_port][l_dimm];
+ FAPI_DBG("[P%d:D%d][CH Util %4.2f/%4.2f][Slope:Int %d:%d][Power %4.2f cW]", l_port, l_dimm, l_utilization, MAX_UTIL, l_power_slope_array[l_port][l_dimm], l_power_int_array[l_port][l_dimm], l_dimm_power_array[l_port][l_dimm]);
+ }
+ FAPI_DBG("[P%d][Power %4.2f cW]", l_port, l_channel_power_array[l_port]);
+ }
+// get the channel pair power for this MBA (add on 1 since value will get truncated)
+ for (l_port = 0; l_port < MAX_NUM_PORTS; l_port++)
+ {
+ o_channel_pair_power = o_channel_pair_power + l_channel_power_array[l_port];
+ if (l_channel_power_array_integer[l_port] > 0)
+ {
+ l_channel_power_array_integer[l_port] = (int)l_channel_power_array[l_port] + 1;
+ }
+ }
+ FAPI_DBG("Channel Pair Power %4.2f cW]", o_channel_pair_power);
+
+ if (o_channel_pair_power > 0)
+ {
+ l_channel_pair_power_integer = (int)o_channel_pair_power + 1;
+ }
+
+// Update output attributes
+ rc = FAPI_ATTR_SET(ATTR_MSS_DIMM_MAXPOWER, &i_target_mba, l_dimm_power_array_integer);
+ if(rc) return rc;
+ rc = FAPI_ATTR_SET(ATTR_MSS_CHANNEL_PAIR_MAXPOWER, &i_target_mba, l_channel_pair_power_integer);
+ if(rc) return rc;
+
+ return rc;
+ }
+
+
+} //end extern C
diff --git a/src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_throttle_to_power.H b/src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_throttle_to_power.H
new file mode 100644
index 000000000..ee9398e70
--- /dev/null
+++ b/src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_throttle_to_power.H
@@ -0,0 +1,104 @@
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/hwpf/hwp/mc_config/mss_eff_config/mss_throttle_to_power.H $ */
+/* */
+/* IBM CONFIDENTIAL */
+/* */
+/* COPYRIGHT International Business Machines Corp. 2012 */
+/* */
+/* p1 */
+/* */
+/* Object Code Only (OCO) source materials */
+/* Licensed Internal Code Source Materials */
+/* IBM HostBoot Licensed Internal Code */
+/* */
+/* The source code for this program is not published or otherwise */
+/* divested of its trade secrets, irrespective of what has been */
+/* deposited with the U.S. Copyright Office. */
+/* */
+/* Origin: 30 */
+/* */
+/* IBM_PROLOG_END_TAG */
+// $Id: mss_throttle_to_power.H,v 1.3 2012/10/15 13:05:23 pardeik Exp $
+// $Source: /afs/awd/projects/eclipz/KnowledgeBase/.cvsroot/eclipz/chips/centaur/working/procedures/ipl/fapi/mss_throttle_to_power.H,v $
+//------------------------------------------------------------------------------
+// *! (C) Copyright International Business Machines Corp. 2011
+// *! All Rights Reserved -- Property of IBM
+// *! *** IBM Confidential ***
+//------------------------------------------------------------------------------
+// *! TITLE : mss_throttle_to_power.H
+// *! DESCRIPTION : see additional comments below
+// *! OWNER NAME : Joab Henderson Email: joabhend@us.ibm.com
+// *! BACKUP NAME : Michael Pardeik Email: pardeik@us.ibm.com
+// *! ADDITIONAL COMMENTS :
+//
+// Header file for mss_throttle_to_power.
+//
+//------------------------------------------------------------------------------
+// Don't forget to create CVS comments when you check in your changes!
+//------------------------------------------------------------------------------
+// CHANGE HISTORY:
+//------------------------------------------------------------------------------
+// Version:| Author: | Date: | Comment:
+//---------|----------|---------|-----------------------------------------------
+// 1.3 | pardeik |11-OCT-12| change i_target to i_target_mba
+// 1.2 | pardeik |03-APR-12| use mba target instead of mbs
+// 1.1 | pardeik |01-DEC-11| First Draft.
+
+
+
+#ifndef MSS_THROTTLE_TO_POWER_H_
+#define MSS_THROTTLE_TO_POWER_H_
+
+//----------------------------------------------------------------------
+// Includes
+//----------------------------------------------------------------------
+#include <fapi.H>
+
+typedef fapi::ReturnCode (*mss_throttle_to_power_FP_t)(const fapi::Target & i_target_mba);
+
+typedef fapi::ReturnCode (*mss_throttle_to_power_calc_FP_t)(
+ const fapi::Target &i_target_mba,
+ uint32_t i_throttle_n_per_mba,
+ uint32_t i_throttle_n_per_chip,
+ uint32_t i_throttle_d,
+ float &channel_pair_power
+ );
+
+extern "C"
+{
+
+//------------------------------------------------------------------------------
+// @brief mss_throttle_to_power(): This function will get the throttle attributes and call another function to determine the dimm and channel pair power based on those throttles
+//
+// @param const fapi::Target &i_target_mba: MBA Target
+//
+// @return fapi::ReturnCode
+//------------------------------------------------------------------------------
+
+ fapi::ReturnCode mss_throttle_to_power(const fapi::Target & i_target_mba);
+
+//------------------------------------------------------------------------------
+// @brief mss_throttle_to_power_calc(): This function will calculate the dimm and channel pair power and update attributes with the power values
+//
+// @param const fapi::Target &i_target_mba: MBA Target
+// @param uint32_t i_throttle_n_per_mba: Throttle value for cfg_nm_n_per_mba
+// @param uint32_t i_throttle_n_per_chip: Throttle value for cfg_nm_n_per_chip
+// @param uint32_t i_throttle_d: Throttle value for cfg_nm_m
+// @param float &o_channel_pair_power: channel pair power at these throttle settings
+//
+// @return fapi::ReturnCode
+//------------------------------------------------------------------------------
+
+ fapi::ReturnCode mss_throttle_to_power_calc(
+ const fapi::Target &i_target_mba,
+ uint32_t i_throttle_n_per_mba,
+ uint32_t i_throttle_n_per_chip,
+ uint32_t i_throttle_d,
+ float &channel_pair_power
+ );
+
+} // extern "C"
+
+#endif // MSS_THROTTLE_TO_POWER_H_
diff --git a/src/usr/hwpf/hwp/mc_config/mss_freq/mss_freq.C b/src/usr/hwpf/hwp/mc_config/mss_freq/mss_freq.C
index 63162d0d7..cfaec3cc1 100644
--- a/src/usr/hwpf/hwp/mc_config/mss_freq/mss_freq.C
+++ b/src/usr/hwpf/hwp/mc_config/mss_freq/mss_freq.C
@@ -1,27 +1,26 @@
-/* IBM_PROLOG_BEGIN_TAG
- * This is an automatically generated prolog.
- *
- * $Source: src/usr/hwpf/hwp/mc_init/mss_freq/mss_freq.C $
- *
- * IBM CONFIDENTIAL
- *
- * COPYRIGHT International Business Machines Corp. 2012
- *
- * p1
- *
- * Object Code Only (OCO) source materials
- * Licensed Internal Code Source Materials
- * IBM HostBoot Licensed Internal Code
- *
- * The source code for this program is not published or other-
- * wise divested of its trade secrets, irrespective of what has
- * been deposited with the U.S. Copyright Office.
- *
- * Origin: 30
- *
- * IBM_PROLOG_END_TAG
- */
-// $Id: mss_freq.C,v 1.17 2012/07/17 13:24:13 bellows Exp $
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/hwpf/hwp/mc_config/mss_freq/mss_freq.C $ */
+/* */
+/* IBM CONFIDENTIAL */
+/* */
+/* COPYRIGHT International Business Machines Corp. 2012 */
+/* */
+/* p1 */
+/* */
+/* Object Code Only (OCO) source materials */
+/* Licensed Internal Code Source Materials */
+/* IBM HostBoot Licensed Internal Code */
+/* */
+/* The source code for this program is not published or otherwise */
+/* divested of its trade secrets, irrespective of what has been */
+/* deposited with the U.S. Copyright Office. */
+/* */
+/* Origin: 30 */
+/* */
+/* IBM_PROLOG_END_TAG */
+// $Id: mss_freq.C,v 1.18 2012/09/07 22:22:08 jdsloat Exp $
/* File mss_volt.C created by JEFF SABROWSKI on Fri 21 Oct 2011. */
//------------------------------------------------------------------------------
@@ -58,6 +57,7 @@
// 1.15 | jdsloat | 06/04/12 | Added a Configuration check
// 1.16 | jdsloat | 06/08/12 | Updates per Firware request
// 1.17 | bellows | 07/16/12 | added in Id tag
+// 1.18 | jdsloat | 09/07/12 | Added FTB offset to TAA and TCK
//
// This procedure takes CENTAUR as argument. for each DIMM (under each MBA)
// DIMM SPD attributes are read to determine optimal DRAM frequency
@@ -95,12 +95,18 @@ fapi::ReturnCode mss_freq(const fapi::Target &i_target_memb)
std::vector<fapi::Target> l_dimm_targets;
uint8_t l_spd_mtb_dividend=0;
uint8_t l_spd_mtb_divisor=0;
+ uint8_t l_spd_ftb_dividend=0;
+ uint8_t l_spd_ftb_divisor=0;
uint32_t l_dimm_freq_calc=0;
uint32_t l_dimm_freq_min=9999;
uint8_t l_spd_min_tck_MTB=0;
+ uint8_t l_spd_tck_offset_FTB=0;
+ uint8_t l_spd_tck_offset=0;
uint32_t l_spd_min_tck=0;
uint32_t l_spd_min_tck_max=0;
uint8_t l_spd_min_taa_MTB=0;
+ uint8_t l_spd_taa_offset_FTB=0;
+ uint8_t l_spd_taa_offset=0;
uint32_t l_spd_min_taa=0;
uint32_t l_spd_min_taa_max=0;
uint32_t l_selected_dimm_freq=0;
@@ -195,10 +201,34 @@ fapi::ReturnCode mss_freq(const fapi::Target &i_target_memb)
FAPI_ERR("Unable to read the SPD number of ranks");
break;
}
+ l_rc = FAPI_ATTR_GET(ATTR_SPD_FINE_OFFSET_TAAMIN, &l_dimm_targets[j], l_spd_taa_offset_FTB); if(l_rc) return l_rc;
+ if (l_rc)
+ {
+ FAPI_ERR("Unable to read the SPD TAA offset (FTB)");
+ break;
+ }
+ l_rc = FAPI_ATTR_GET(ATTR_SPD_FINE_OFFSET_TCKMIN, &l_dimm_targets[j], l_spd_tck_offset_FTB); if(l_rc) return l_rc;
+ if (l_rc)
+ {
+ FAPI_ERR("Unable to read the SPD TCK offset (FTB)");
+ break;
+ }
+ l_rc = FAPI_ATTR_GET(ATTR_SPD_FTB_DIVIDEND, &l_dimm_targets[j], l_spd_ftb_dividend); if(l_rc) return l_rc;
+ if (l_rc)
+ {
+ FAPI_ERR("Unable to read the SPD FTB dividend");
+ break;
+ }
+ l_rc = FAPI_ATTR_GET(ATTR_SPD_FTB_DIVISOR, &l_dimm_targets[j], l_spd_ftb_divisor); if(l_rc) return l_rc;
+ if (l_rc)
+ {
+ FAPI_ERR("Unable to read the SPD FTB divisor");
+ break;
+ }
cur_dimm_spd_valid_u8array[cur_mba_port][cur_mba_dimm] = MSS_FREQ_VALID;
- if ((l_spd_min_tck_MTB == 0)||(l_spd_mtb_dividend == 0)||(l_spd_mtb_divisor == 0)||(l_spd_min_taa_MTB == 0))
+ if ((l_spd_min_tck_MTB == 0)||(l_spd_mtb_dividend == 0)||(l_spd_mtb_divisor == 0)||(l_spd_min_taa_MTB == 0)||(l_spd_ftb_dividend == 0)||(l_spd_ftb_divisor == 0))
{
//Invalid due to the fact that JEDEC dictates that these should be non-zero.
FAPI_ERR("Invalid data recieved from SPD within MTB Dividend, MTB Divisor, TCK Min, or TAA Min");
@@ -210,6 +240,34 @@ fapi::ReturnCode mss_freq(const fapi::Target &i_target_memb)
// Frequency listed with multiplication of 2 as clocking data on both +- edges
l_spd_min_tck = ( 1000 * l_spd_min_tck_MTB * l_spd_mtb_dividend ) / l_spd_mtb_divisor;
l_spd_min_taa = ( 1000 * l_spd_min_taa_MTB * l_spd_mtb_dividend ) / l_spd_mtb_divisor;
+
+ // Adjusting by tck offset -- tck offset represented in 2's compliment as it could be positive or negative adjustment
+ // No multiplication of 1000 as it is already in picoseconds.
+ if (l_spd_tck_offset_FTB & 0x80)
+ {
+ l_spd_tck_offset_FTB = ~( l_spd_tck_offset_FTB ) + 1;
+ l_spd_tck_offset = (l_spd_tck_offset_FTB * l_spd_ftb_dividend ) / l_spd_ftb_divisor;
+ l_spd_min_tck = l_spd_min_tck - l_spd_tck_offset;
+ }
+ else
+ {
+ l_spd_tck_offset = (l_spd_tck_offset_FTB * l_spd_ftb_dividend ) / l_spd_ftb_divisor;
+ l_spd_min_tck = l_spd_min_tck + l_spd_tck_offset;
+ }
+
+ // Adjusting by taa offset -- taa offset represented in 2's compliment as it could be positive or negative adjustment
+ if (l_spd_taa_offset_FTB & 0x80)
+ {
+ l_spd_taa_offset_FTB = ~( l_spd_taa_offset_FTB) + 1;
+ l_spd_taa_offset = (l_spd_taa_offset_FTB * l_spd_ftb_dividend ) / l_spd_ftb_divisor;
+ l_spd_min_taa = l_spd_min_taa - l_spd_taa_offset;
+ }
+ else
+ {
+ l_spd_taa_offset = (l_spd_taa_offset_FTB * l_spd_ftb_dividend ) / l_spd_ftb_divisor;
+ l_spd_min_taa = l_spd_min_taa + l_spd_taa_offset;
+ }
+
if ((l_spd_min_tck == 0)||(l_spd_min_taa == 0))
{
//Invalid due to the fact that JEDEC dictates that these should be non-zero.
diff --git a/src/usr/hwpf/hwp/mc_config/mss_volt/mss_volt.C b/src/usr/hwpf/hwp/mc_config/mss_volt/mss_volt.C
index 8aa152e37..3122a28a1 100644
--- a/src/usr/hwpf/hwp/mc_config/mss_volt/mss_volt.C
+++ b/src/usr/hwpf/hwp/mc_config/mss_volt/mss_volt.C
@@ -1,27 +1,26 @@
-/* IBM_PROLOG_BEGIN_TAG
- * This is an automatically generated prolog.
- *
- * $Source: src/usr/hwpf/hwp/mc_init/mss_volt/mss_volt.C $
- *
- * IBM CONFIDENTIAL
- *
- * COPYRIGHT International Business Machines Corp. 2012
- *
- * p1
- *
- * Object Code Only (OCO) source materials
- * Licensed Internal Code Source Materials
- * IBM HostBoot Licensed Internal Code
- *
- * The source code for this program is not published or other-
- * wise divested of its trade secrets, irrespective of what has
- * been deposited with the U.S. Copyright Office.
- *
- * Origin: 30
- *
- * IBM_PROLOG_END_TAG
- */
-// $Id: mss_volt.C,v 1.11 2012/07/17 13:24:49 bellows Exp $
+/* IBM_PROLOG_BEGIN_TAG */
+/* This is an automatically generated prolog. */
+/* */
+/* $Source: src/usr/hwpf/hwp/mc_config/mss_volt/mss_volt.C $ */
+/* */
+/* IBM CONFIDENTIAL */
+/* */
+/* COPYRIGHT International Business Machines Corp. 2012 */
+/* */
+/* p1 */
+/* */
+/* Object Code Only (OCO) source materials */
+/* Licensed Internal Code Source Materials */
+/* IBM HostBoot Licensed Internal Code */
+/* */
+/* The source code for this program is not published or otherwise */
+/* divested of its trade secrets, irrespective of what has been */
+/* deposited with the U.S. Copyright Office. */
+/* */
+/* Origin: 30 */
+/* */
+/* IBM_PROLOG_END_TAG */
+// $Id: mss_volt.C,v 1.12 2012/10/18 14:46:36 jdsloat Exp $
/* File mss_volt.C created by JEFF SABROWSKI on Fri 21 Oct 2011. */
//------------------------------------------------------------------------------
@@ -53,6 +52,7 @@
// 1.9 | jdsloat | 05/08/12 | Removed debug message
// 1.10 | jdsloat | 05/09/12 | Fixed typo
// 1.11 | bellows | 07/16/12 | added in Id tag
+// 1.11 | jdsloat | 10/18/12 | Added check for violation of tolerant voltages of non-functional dimms.
// This procedure takes a vector of Centaurs behind a voltage domain,
// reads in supported DIMM voltages from SPD and determines optimal
@@ -66,10 +66,18 @@
#include <fapi.H>
#include <mss_volt.H>
+//----------------------------------------------------------------------
+// Constants
+//----------------------------------------------------------------------
+const uint32_t MAX_TOLERATED_VOLT = 1500;
+const uint32_t MAX_TOLERATED_DDR3_VOLT = 1500;
+const uint32_t MAX_TOLERATED_DDR4_VOLT = 1200;
+
fapi::ReturnCode mss_volt(std::vector<fapi::Target> & i_targets_memb)
{
fapi::ReturnCode l_rc;
+ uint8_t l_dimm_functionality=0;
uint8_t l_spd_dramtype=0;
uint8_t l_spd_volts=0;
uint8_t l_spd_volts_all_dimms=0x06; //start assuming all voltages supported
@@ -77,6 +85,7 @@ fapi::ReturnCode mss_volt(std::vector<fapi::Target> & i_targets_memb)
uint8_t l_dram_ddr4_found_flag=0;
uint32_t l_selected_dram_voltage=0; //this gets written into all centaurs when done.
+ uint32_t l_tolerated_dram_voltage = MAX_TOLERATED_VOLT; //initially set to the max tolerated voltage
// Iterate through the list of centaurs
for (uint32_t i=0; i < i_targets_memb.size(); i++)
@@ -90,7 +99,7 @@ fapi::ReturnCode mss_volt(std::vector<fapi::Target> & i_targets_memb)
{
std::vector<fapi::Target> l_dimm_targets;
// Get a vector of DIMM targets
- l_rc = fapiGetAssociatedDimms(l_mbaChiplets[j], l_dimm_targets);
+ l_rc = fapiGetAssociatedDimms(l_mbaChiplets[j], l_dimm_targets, fapi::TARGET_STATE_PRESENT);
if (l_rc) return l_rc;
for (uint32_t k=0; k < l_dimm_targets.size(); k++)
{
@@ -98,6 +107,8 @@ fapi::ReturnCode mss_volt(std::vector<fapi::Target> & i_targets_memb)
if (l_rc) return l_rc;
l_rc = FAPI_ATTR_GET(ATTR_SPD_MODULE_NOMINAL_VOLTAGE, &l_dimm_targets[k], l_spd_volts);
if (l_rc) return l_rc;
+ l_rc = FAPI_ATTR_GET(ATTR_FUNCTIONAL, &l_dimm_targets[k], l_dimm_functionality);
+ if (l_rc) return l_rc;
// spd_volts: bit0= NOT 1.5V bit1=1.35V bit2=1.25V, assume a 1.20V in future for DDR4
// check for supported voltage/dram type combo DDR3=12, DDR4=13
@@ -116,8 +127,13 @@ fapi::ReturnCode mss_volt(std::vector<fapi::Target> & i_targets_memb)
FAPI_SET_HWP_ERROR(l_rc, RC_MSS_VOLT_UNRECOGNIZED_DRAM_DEVICE_TYPE);
return l_rc;
}
- //AND dimm voltage capabilities together to find aggregate voltage support on all dimms
- l_spd_volts_all_dimms = l_spd_volts_all_dimms & l_spd_volts;
+
+ if(l_dimm_functionality == fapi::ENUM_ATTR_FUNCTIONAL_FUNCTIONAL)
+ {
+ //AND dimm voltage capabilities together to find aggregate voltage support on all dimms
+ l_spd_volts_all_dimms = l_spd_volts_all_dimms & l_spd_volts;
+ }
+
}
}
}
@@ -126,37 +142,92 @@ fapi::ReturnCode mss_volt(std::vector<fapi::Target> & i_targets_memb)
// note: only support DDR3=1.35V and DDR4=1.2xV
if (l_dram_ddr3_found_flag && l_dram_ddr4_found_flag)
- {
+ {
FAPI_ERR("mss_volt: DDR3 and DDR4 mixing not allowed");
FAPI_SET_HWP_ERROR(l_rc, RC_MSS_VOLT_DDR_TYPE_MIXING_UNSUPPORTED);
return l_rc;
- }
+ }
if (l_dram_ddr3_found_flag && ((l_spd_volts_all_dimms & fapi::ENUM_ATTR_SPD_MODULE_NOMINAL_VOLTAGE_OP1_35) == fapi::ENUM_ATTR_SPD_MODULE_NOMINAL_VOLTAGE_OP1_35))
- {
+ {
l_selected_dram_voltage=1350;
- }
+ }
else if (l_dram_ddr4_found_flag && ((l_spd_volts_all_dimms & fapi::ENUM_ATTR_SPD_MODULE_NOMINAL_VOLTAGE_OP1_2X) == fapi::ENUM_ATTR_SPD_MODULE_NOMINAL_VOLTAGE_OP1_2X))
- {
+ {
l_selected_dram_voltage=1200;
- }
+ }
else if ((l_spd_volts_all_dimms & fapi::ENUM_ATTR_SPD_MODULE_NOMINAL_VOLTAGE_NOTOP1_5) != fapi::ENUM_ATTR_SPD_MODULE_NOMINAL_VOLTAGE_NOTOP1_5)
- {
+ {
l_selected_dram_voltage=1500;
- }
+ }
else
- {
+ {
FAPI_ERR("One or more DIMMs do not support required voltage for DIMM type");
FAPI_SET_HWP_ERROR(l_rc, RC_MSS_VOLT_DDR_TYPE_REQUIRED_VOLTAGE);
return l_rc;
- }
+ }
+
+/* if( l_selected_dram_voltage > l_supported_dram_voltage)
+ {
+ FAPI_INF( "Selected Voltage larger than highest supported voltage. Selected Voltage: %d Supported Voltage: %d ", l_selected_dram_voltage, l_supported_dram_voltage);
+ FAPI_INF( "Using supported Voltage.");
+ l_selected_dram_voltage = l_supported_dram_voltage;
+ }
+*/
+
+ // Must check to see if we violate Tolerent voltages of Non-functional Dimms
+ // If so we must error/deconfigure on the centaur level.
+ // Iterate through the list of centaurs
+ for (uint32_t i=0; i < i_targets_memb.size(); i++)
+ {
+ l_tolerated_dram_voltage = MAX_TOLERATED_VOLT; // using 1.5 as this is the largest supported voltage
+ std::vector<fapi::Target> l_mbaChiplets;
+ // Get associated MBA's on this centaur
+ l_rc=fapiGetChildChiplets(i_targets_memb[i], fapi::TARGET_TYPE_MBA_CHIPLET, l_mbaChiplets);
+ if (l_rc) return l_rc;
+ for (uint32_t j=0; j < l_mbaChiplets.size(); j++)
+ {
+ std::vector<fapi::Target> l_dimm_targets;
+ // Get a vector of DIMM targets
+ l_rc = fapiGetAssociatedDimms(l_mbaChiplets[j], l_dimm_targets, fapi::TARGET_STATE_PRESENT);
+ if (l_rc) return l_rc;
+ for (uint32_t k=0; k < l_dimm_targets.size(); k++)
+ {
+ l_rc = FAPI_ATTR_GET(ATTR_FUNCTIONAL, &l_dimm_targets[k], l_dimm_functionality);
+ if (l_rc) return l_rc;
+
+ if(l_dimm_functionality == fapi::ENUM_ATTR_FUNCTIONAL_NON_FUNCTIONAL)
+ {
+ if ( (l_spd_dramtype == fapi::ENUM_ATTR_SPD_DRAM_DEVICE_TYPE_DDR3) && (l_tolerated_dram_voltage > MAX_TOLERATED_DDR3_VOLT) )
+ {
+ l_tolerated_dram_voltage = MAX_TOLERATED_DDR3_VOLT;
+ }
+ if ( (l_spd_dramtype == fapi::ENUM_ATTR_SPD_DRAM_DEVICE_TYPE_DDR4) && (l_tolerated_dram_voltage > MAX_TOLERATED_DDR4_VOLT) )
+ {
+ l_tolerated_dram_voltage = MAX_TOLERATED_DDR4_VOLT;
+ }
+ }
+ }
+ }
+
+ if ( l_tolerated_dram_voltage < l_selected_dram_voltage )
+ {
+ FAPI_ERR("One or more DIMMs classified non-functional has a tolerated voltage below selected voltage.");
+ FAPI_ERR("Deconfiguring the associated Centaur.");
+ const fapi::Target & MASTER_CHIP = i_targets_memb[i];
+ FAPI_SET_HWP_ERROR(l_rc, RC_MSS_VOLT_TOLERATED_VOLTAGE_VIOLATION);
+ return l_rc;
+ }
+ }
+
// Iterate through the list of centaurs again, to update ATTR
for (uint32_t i=0; i < i_targets_memb.size(); i++)
- {
+ {
l_rc = FAPI_ATTR_SET(ATTR_MSS_VOLT, &i_targets_memb[i], l_selected_dram_voltage);
FAPI_INF( "mss_volt calculation complete. MSS_VOLT: %d", l_selected_dram_voltage);
if (l_rc) return l_rc;
- }
+ }
+
return l_rc;
}
OpenPOWER on IntegriCloud