summaryrefslogtreecommitdiffstats
path: root/src/import/chips/p9/procedures/hwp/memory/lib/dimm/eff_dimm.C
diff options
context:
space:
mode:
authorStephen Glancy <sglancy@us.ibm.com>2017-09-12 11:50:37 -0500
committerDaniel M. Crowell <dcrowell@us.ibm.com>2017-09-18 10:04:32 -0400
commit6763e7269912f3e359dfd1e84a32dbe87975333c (patch)
tree1ca33ab01957266360b1f0fc6b3fa0d3aa3f822f /src/import/chips/p9/procedures/hwp/memory/lib/dimm/eff_dimm.C
parent189f9299047c253497f4c3cd419283dd27b04c53 (diff)
downloadtalos-hostboot-6763e7269912f3e359dfd1e84a32dbe87975333c.tar.gz
talos-hostboot-6763e7269912f3e359dfd1e84a32dbe87975333c.zip
Updates RCD power settings
RC09 contains a bit (IBT) that configures if ODT's should be sent to the DRAM during power down mode or not. This commit updates that setting to check on the ODT levels to set the IBT bit. Change-Id: I9f54a571e28f88c8589d3143562b03fded3f991f CQ:SW400213 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/46098 Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Reviewed-by: ANDRE A. MARIN <aamarin@us.ibm.com> Reviewed-by: Michael D. Pardeik <pardeik@us.ibm.com> Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Tested-by: Hostboot CI <hostboot-ci+hostboot@us.ibm.com> Reviewed-by: Louis Stermole <stermole@us.ibm.com> Reviewed-by: Jennifer A. Stofer <stofer@us.ibm.com> Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/46099 Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com> Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com> Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/import/chips/p9/procedures/hwp/memory/lib/dimm/eff_dimm.C')
-rw-r--r--src/import/chips/p9/procedures/hwp/memory/lib/dimm/eff_dimm.C71
1 files changed, 69 insertions, 2 deletions
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/eff_dimm.C b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/eff_dimm.C
index d7dbfd221..f3b3c628d 100644
--- a/src/import/chips/p9/procedures/hwp/memory/lib/dimm/eff_dimm.C
+++ b/src/import/chips/p9/procedures/hwp/memory/lib/dimm/eff_dimm.C
@@ -1485,13 +1485,80 @@ fapi_try_exit:
///
fapi2::ReturnCode eff_dimm::dimm_rc09()
{
- // TODO - RTC 160118: Clean up eff_config boiler plate that can moved into helper functions
+ // Sets up constant values
+ constexpr uint64_t CKE_POWER_DOWN_MODE_ENABLE = 4;
+ constexpr uint64_t CKE_POWER_DOWN_MODE_TOTAL_LEN = 1;
+ constexpr uint64_t ODT_POS_OFFSET = 4;
+ constexpr uint64_t ODT_ATTR_LEN = 2;
+ constexpr uint64_t IBT_OFF_POS = 5;
+ const auto l_num_dimms = mss::count_dimm(iv_mca);
+
// Retrieve MCS attribute data
uint8_t l_attrs_dimm_rc09[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
+
+ fapi2::buffer<uint8_t> l_rc09(iv_pDecoder->iv_raw_card.iv_rc09);
FAPI_TRY( eff_dimm_ddr4_rc09(iv_mcs, &l_attrs_dimm_rc09[0][0]) );
+ // If CKE power down mode is on and we're in dual drop mode, then we need to configure the IBT mode
+ if(l_rc09.getBit<CKE_POWER_DOWN_MODE_ENABLE, CKE_POWER_DOWN_MODE_TOTAL_LEN>() && l_num_dimms == 2)
+ {
+ FAPI_INF("%s Checking whether the DIMM needs IBT mode on or off", mss::c_str(iv_dimm));
+
+ // RCD's can be powered down to conserve power similar to DRAMs (by dropping CKE)
+ // This functionality is enabled by bit RC09 (bit 4 in our attribute)
+ // If CKE power down mode is enabled and the system has a dual drop on this MCA, then we need to reconfigure the attribute
+ // Currently, that is the case (check out the if above)
+ // The broadcast of ODT's to the DRAMs can be disabled if no ODT's are needed by the other DIMM for writes or reads
+ // So, we need to check that
+ // Steps to do so:
+ // 1) Gets the other DIMM
+ // 2) Gets the ODT values for the other DIMM
+ // 3) Checks whether this DIMM's ODTs are used for writes or reads that target the other DIMMs
+ // 4) Modify the value for IBT
+
+ // 1) Gets the other DIMM
+ const auto l_dimms = mss::find_targets<fapi2::TARGET_TYPE_DIMM>(iv_mca);
+ const auto l_this_dimm_pos = mss::relative_pos<fapi2::TARGET_TYPE_MCA>(iv_dimm);
+ const auto l_other_dimm_pos = l_this_dimm_pos == 0 ? 1 : 0;
+ const auto l_other_dimm = l_dimms[l_other_dimm_pos];
+ bool l_ibt_off = true;
+
+ // 2) Gets the ODT values for the other DIMM
+ uint8_t l_wr_odt[MAX_RANK_PER_DIMM] = {};
+ uint8_t l_rd_odt[MAX_RANK_PER_DIMM] = {};
+ FAPI_TRY(vpd_mt_odt_rd(l_other_dimm, l_rd_odt));
+ FAPI_TRY(vpd_mt_odt_wr(l_other_dimm, l_wr_odt));
+
+ // 3) Checks whether this DIMM's ODTs are used for writes or reads that target the other DIMMs
+ for(uint8_t l_rank = 0; l_rank < MAX_RANK_PER_DIMM; ++l_rank)
+ {
+ // Temporary buffers to make the math a bit easier
+ const fapi2::buffer<uint8_t> l_temp_wr(l_wr_odt[l_rank]);
+ const fapi2::buffer<uint8_t> l_temp_rd(l_rd_odt[l_rank]);
+
+ // The ODT attribute consists of a bitmask as follows 0->7
+ // [DIMM0 ODT0][DIMM0 ODT1][N/A][N/A][DIMM1 ODT0][DIMM1 ODT1][N/A][N/A]
+ // As we need whether any ODT is enabled for this DIMM, compute the appropriate offset based upon the DIMM index value
+ const auto l_this_dimm_odt = l_this_dimm_pos * ODT_POS_OFFSET;
+
+ // Are either the writed or read ODT's enabled for this DIMM?
+ if(l_temp_wr.getBit(l_this_dimm_odt, ODT_ATTR_LEN) || l_temp_rd.getBit(l_this_dimm_odt, ODT_ATTR_LEN))
+ {
+ // Either write or read ODT is enabled - IBT off needs to be false
+ // Note: this is taken from JEDEC so we have a double negative
+ l_ibt_off = false;
+ break;
+ }
+ }
+
+ // 4) Modifies the value
+ l_rc09.writeBit<IBT_OFF_POS>(l_ibt_off);
+ FAPI_INF("%s has IBT value of %s giving a value of 0x%02x", mss::c_str(iv_dimm), l_ibt_off ? "OFF - 1" : "ON - 0",
+ uint8_t(l_rc09));
+ }
+
// Update MCS attribute
- l_attrs_dimm_rc09[iv_port_index][iv_dimm_index] = iv_pDecoder->iv_raw_card.iv_rc09;
+ l_attrs_dimm_rc09[iv_port_index][iv_dimm_index] = l_rc09;
FAPI_INF( "%s: RC09 setting: %d", mss::c_str(iv_dimm), l_attrs_dimm_rc09[iv_port_index][iv_dimm_index] );
FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_DDR4_RC09, iv_mcs, l_attrs_dimm_rc09) );
OpenPOWER on IntegriCloud