diff options
author | Brian Silver <bsilver@us.ibm.com> | 2016-01-07 14:35:20 -0600 |
---|---|---|
committer | Daniel M. Crowell <dcrowell@us.ibm.com> | 2016-04-01 21:23:41 -0400 |
commit | 3a11ab737feeb6695f949f355f41081e64dec2f5 (patch) | |
tree | 4f1e16a5ac0351f8b8eb236322916ea587159db0 /src/import/chips/p9/procedures/hwp/memory/lib/mc | |
parent | dba9ee6be396b29a072d9c5fc87ff346542c396e (diff) | |
download | talos-hostboot-3a11ab737feeb6695f949f355f41081e64dec2f5.tar.gz talos-hostboot-3a11ab737feeb6695f949f355f41081e64dec2f5.zip |
Add mcbist L2 function
Change-Id: Ie902a404323fe781aca99af2c20ca6ba564a06da
Original-Change-Id: I8b98c188d6a642eb49d89deffcbd697d9cf7afdc
Reviewed-on: http://gfw160.aus.stglabs.ibm.com:8080/gerrit/23895
Tested-by: Jenkins Server
Reviewed-by: Craig C. Hamilton <cchamilt@us.ibm.com>
Reviewed-by: Andre A. Marin <aamarin@us.ibm.com>
Reviewed-by: Jennifer A. Stofer <stofer@us.ibm.com>
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/22768
Tested-by: FSP CI Jenkins
Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/import/chips/p9/procedures/hwp/memory/lib/mc')
3 files changed, 347 insertions, 2 deletions
diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/mc/mc.C b/src/import/chips/p9/procedures/hwp/memory/lib/mc/mc.C index 4b76445f9..274ec94a9 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/mc/mc.C +++ b/src/import/chips/p9/procedures/hwp/memory/lib/mc/mc.C @@ -28,11 +28,11 @@ // *HWP Consumed by: FSP:HB #include <fapi2.H> - #include <p9_mc_scom_addresses.H> #include "../utils/dump_regs.H" #include "../utils/scom.H" +#include "mc.H" using fapi2::TARGET_TYPE_MCA; using fapi2::TARGET_TYPE_MCS; @@ -40,6 +40,10 @@ using fapi2::TARGET_TYPE_MCS; namespace mss { +const uint64_t mcTraits<TARGET_TYPE_MCS>::xlate0_reg[] = {MCS_PORT02_MCP0XLT0, MCS_PORT13_MCP0XLT0}; +const uint64_t mcTraits<TARGET_TYPE_MCS>::xlate1_reg[] = {MCS_PORT02_MCP0XLT1, MCS_PORT13_MCP0XLT1}; +const uint64_t mcTraits<TARGET_TYPE_MCS>::xlate2_reg[] = {MCS_PORT02_MCP0XLT2, MCS_PORT13_MCP0XLT2}; + /// /// @brief Dump the registers of the MC (MCA_MBA, MCS) /// @param[in] i_target the MCS target @@ -178,4 +182,131 @@ fapi_try_exit: return fapi2::current_err; } +/// +/// @brief Perform initializations for the MC (MCA) +/// @param[in] i_target, the MCA to initialize +/// @return FAPI2_RC_SUCCESS iff ok +/// +template<> +fapi2::ReturnCode mc<TARGET_TYPE_MCA>::scominit(const fapi2::Target<TARGET_TYPE_MCA>& i_target) +{ + uint32_t l_throttle_denominator = 0; + FAPI_TRY( mss::runtime_mem_throttle_denominator(i_target, l_throttle_denominator) ); + + // #Register Name Final Arb Parms + // #Mnemonic MBA_FARB0Q + // #Attributes PAR:EVEN Bit Field Mnemonic Attribute or Setting to use + // #Description FARB command control + // #1. FARB0 bit 38: cfg_parity_after_cmd + // # - set this bit if DDR3 and (RDIMM or LDRIMM) + // + // # - clear this bit if DDR4 and (RDIMM or LDRIMM) + // #2. FARB0 bit 60: cfg_ignore_rcd_parity_err + // # - clear this bit if (RDIMM or LDRIMM) + // #3. FARB0 bit 61: cfg_enable_rcd_rw_retry + // # - set this bit if (RDIMM or LDRIMM) + + // Nimbus is always LR/RDIMM, DDR4. + // Not sure what happened to cfg_ignore_rcd_parity_err, cfg_enable_rcd_rw_retry - perhaps they're always ok since we don't + // support anything else? + { + fapi2::buffer<uint64_t> l_data; + + l_data.setBit<MCA_MBA_FARB0Q_CFG_PARITY_AFTER_CMD>(); + FAPI_TRY( mss::putScom(i_target, MCA_MBA_FARB0Q, l_data) ); + } + + { + // FABR1Q - Chip ID bits + } + { + // FARB2Q - ODT bits + } + + // #Register Name N/M Throttling Control + // #Mnemonic MBA_FARB3Q + // #Attributes PAR:EVEN Bit Field Mnemonic Attribute or Setting to use + // #Description N/M throttling control (Centaur only) + // # 0:14 cfg_nm_n_per_mba MSS_MEM_THROTTLE_NUMERATOR_PER_MBA (Centaur) + // # 15:30 cfg_nm_n_per_chip MSS_MEM_THROTTLE_NUMERATOR_PER_CHIP (Centaur) + // # 0:14 cfg_nm_n_per_slot MSS_MEM_THROTTLE_NUMERATOR_PER_SLOT (Nimbus) + // # 15:30 cfg_nm_n_per_port MSS_MEM_THROTTLE_NUMERATOR_PER_PORT (Nimbus) + // # 31:44 cfg_nm_m MSS_MEM_THROTTLE_DENOMINATOR + // # 51 cfg_nm_per_slot_enabled 1 (not on Nimbus?) + // # 52 cfg_nm_count_other_mba_dis Set to 0 for CDIMM, Set to 1 for everything else (not on Nimbus?) + // #cfg_nm_ras_weight, bits 45:47 = ATTR_MSS_THROTTLE_CONTROL_RAS_WEIGHT + // #cfg_nm_cas_weight, bits 48:50 = ATTR_MSS_THROTTLE_CONTROL_CAS_WEIGHT + { + fapi2::buffer<uint64_t> l_data; + uint32_t l_throttle_per_slot = 0; + uint32_t l_throttle_per_port = 0; + uint8_t l_ras_weight = 0; + uint8_t l_cas_weight = 0; + + FAPI_TRY( mss::runtime_mem_throttle_numerator_per_slot(i_target, l_throttle_per_slot) ); + FAPI_TRY( mss::runtime_mem_throttle_numerator_per_port(i_target, l_throttle_per_port) ); + FAPI_TRY( mss::throttle_control_ras_weight(i_target, l_ras_weight) ); + FAPI_TRY( mss::throttle_control_cas_weight(i_target, l_cas_weight) ); + + l_data.insertFromRight<MCA_MBA_FARB3Q_CFG_NM_N_PER_SLOT, MCA_MBA_FARB3Q_CFG_NM_N_PER_SLOT_LEN>(l_throttle_per_slot); + l_data.insertFromRight<MCA_MBA_FARB3Q_CFG_NM_N_PER_PORT, MCA_MBA_FARB3Q_CFG_NM_N_PER_PORT_LEN>(l_throttle_per_port); + l_data.insertFromRight<MCA_MBA_FARB3Q_CFG_NM_M, MCA_MBA_FARB3Q_CFG_NM_M_LEN>(l_throttle_denominator); + l_data.insertFromRight<MCA_MBA_FARB3Q_CFG_NM_RAS_WEIGHT, MCA_MBA_FARB3Q_CFG_NM_RAS_WEIGHT_LEN>(l_ras_weight); + l_data.insertFromRight<MCA_MBA_FARB3Q_CFG_NM_CAS_WEIGHT, MCA_MBA_FARB3Q_CFG_NM_CAS_WEIGHT_LEN>(l_ras_weight); + + FAPI_TRY( mss::putScom(i_target, MCA_MBA_FARB3Q, l_data) ); + } + + // Doesn't appear to be a row-hammer-mode in Nimbus + // # -- bits 27:41 (cfg_emer_n) = ATTR_MRW_SAFEMODE_MEM_THROTTLE_NUMERATOR_PER_SLOT + // # -- bits 42:55 (cfg_emer_m) = ATTR_MRW_MEM_THROTTLE_DENOMINATOR + { + fapi2::buffer<uint64_t> l_data; + uint32_t l_throttle_per_slot = 0; + + FAPI_TRY( mss::mrw_safemode_mem_throttle_numerator_per_slot(l_throttle_per_slot) ); + + l_data.insertFromRight<MCA_MBA_FARB4Q_EMERGENCY_M, MCA_MBA_FARB4Q_EMERGENCY_M_LEN>(l_throttle_denominator); + l_data.insertFromRight<MCA_MBA_FARB4Q_EMERGENCY_N, MCA_MBA_FARB4Q_EMERGENCY_N_LEN>(l_throttle_per_slot); + + FAPI_TRY( mss::putScom(i_target, MCA_MBA_FARB4Q, l_data) ); + } + + { + // TMR0Q - DDR data bus timing parameters + } + + { + // TMR1Q - DDR bank busy parameters + } + + { + // DSM0Q - Data State Machine Configurations + } + + { + // MBAREF0Q mba01 refresh settings + } + + { + // MBAPC0Q power control settings reg 0 + // MBAPC1Q power control settings reg 1 + } + + { + // MBAREF1Q MBA01 Rank-to-primary-CKE mapping table + // Doesn't exist in Nimbus. Leaving this as a comment to note that we didn't forget it. + // CKEs are fixed to chip selects for all P9 configs + } + + { + // CAL0Q (this timer to be used for zq cal) + // CAL1Q (this timer to be used for mem cal) + // CAL3Q (this timer to be used for mem cal) + } + +fapi_try_exit: + return fapi2::current_err; +} + } diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/mc/mc.H b/src/import/chips/p9/procedures/hwp/memory/lib/mc/mc.H index f239dd0c7..1e295dc8f 100644 --- a/src/import/chips/p9/procedures/hwp/memory/lib/mc/mc.H +++ b/src/import/chips/p9/procedures/hwp/memory/lib/mc/mc.H @@ -116,7 +116,7 @@ enum { THIS_ENTRY_VALID = 0, VALUE_OF_D_BIT_INDEX = 1, - 12GB_ENABLE_INDEX = 2, + GB12_ENABLE_INDEX = 2, MASTER_BIT_0_VALID_INDEX = 3, MASTER_BIT_1_VALID_INDEX = 4, SLAVE_BIT_0_VALID_INDEX = 5, diff --git a/src/import/chips/p9/procedures/hwp/memory/lib/mc/xlate.C b/src/import/chips/p9/procedures/hwp/memory/lib/mc/xlate.C new file mode 100644 index 000000000..f9f778ce6 --- /dev/null +++ b/src/import/chips/p9/procedures/hwp/memory/lib/mc/xlate.C @@ -0,0 +1,214 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: chips/p9/procedures/hwp/memory/lib/mc/xlate.C $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* EKB Project */ +/* */ +/* COPYRIGHT 2016 */ +/* [+] International Business Machines Corp. */ +/* */ +/* */ +/* 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. */ +/* */ +/* IBM_PROLOG_END_TAG */ + +/// +/// @file xlate.C +/// @brief Subroutines to manipulate the memory controller translation registers +/// +// *HWP HWP Owner: Brian Silver <bsilver@us.ibm.com> +// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com> +// *HWP Team: Memory +// *HWP Level: 2 +// *HWP Consumed by: FSP:HB + +#include <fapi2.H> + +#include "p9_mc_scom_addresses.H" +#include "p9_mc_scom_addresses_fld.H" + +#include "mss_attribute_accessors.H" + +#include "mc.H" +#include "../utils/scom.H" +#include "../dimm/kind.H" + +using fapi2::TARGET_TYPE_MCBIST; +using fapi2::TARGET_TYPE_PROC_CHIP; +using fapi2::TARGET_TYPE_SYSTEM; +using fapi2::TARGET_TYPE_MCA; +using fapi2::TARGET_TYPE_MCS; +using fapi2::TARGET_TYPE_DIMM; + +using fapi2::FAPI2_RC_SUCCESS; + + +namespace mss +{ + +/// +/// @brief Perform initializations of the MC translation +/// @tparm P, the fapi2::TargetType of the port +/// @tparm TT, the typename of the traits +/// @param[in] i_target, the target which has the MCA to map +/// @return FAPI2_RC_SUCCESS iff ok +/// +template<> +template<> +fapi2::ReturnCode mc<TARGET_TYPE_MCS>::setup_xlate_map(const fapi2::Target<TARGET_TYPE_MCA>& i_target) +{ + fapi2::buffer<uint64_t> l_xlate; + fapi2::buffer<uint64_t> l_xlate1; + fapi2::buffer<uint64_t> l_xlate2; + + const auto l_dimms = i_target.getChildren<TARGET_TYPE_DIMM>(); + + FAPI_INF("Setting up xlate registers for MCA%d (%d)", mss::pos(i_target), mss::index(i_target)); + + // We enable the DIMM select bit for slot1 if we have two DIMM installed + l_xlate.writeBit<MCS_PORT13_MCP0XLT0_SLOT1_D_VALUE>(l_dimms.size() == 2); + + // Get the functional DIMM on this port. + for (auto d : l_dimms) + { + // Our slot (0, 1) is the same as our general index. + const uint64_t l_slot = mss::index(d); + + // Our slot offset tells us which 16 bit section in the xlt register to use for this DIMM + // We'll either use the left most bits (slot 0) or move 16 bits to the right for slot 1. + const uint64_t l_slot_offset = l_slot * 16; + + // Get the translation array, based on this specific DIMM's config + dimm::kind l_dimm(d); + + // TK: Get the information from the translation table for this DIMM. + + FAPI_DBG("address translation for DIMM %s %dR %dgbx%d in slot %d", + mss::c_str(d), l_dimm.iv_master_ranks, l_dimm.iv_dram_density, l_dimm.iv_dram_width, l_slot); + + + // Set the proper bit if there is a DIMM in this slot. If there wasn't, we wouldn't see + // this DIMM in the vector, so this is always safe. + l_xlate.setBit(MCS_PORT02_MCP0XLT0_SLOT0_VALID + l_slot_offset); + + + // Set the 12G DIMM bit if either DIMM is 12G + // Is this correct? BRS + l_xlate.writeBit<MCS_PORT13_MCP0XLT0_12GB_ENABLE>(l_dimm.iv_size == 12); + + // Check our master ranks, and enable the proper bits. + // Note this seems a little backward. M0 is the left most bit, M1 the right most. + // So, M1 changes for ranks 0,1 and M0 changes for ranks 3,4 + if (l_dimm.iv_master_ranks > 0) + { + l_xlate.setBit(MCS_PORT13_MCP0XLT0_SLOT0_M1_VALID + l_slot_offset); + } + + if (l_dimm.iv_master_ranks > 2) + { + l_xlate.setBit(MCS_PORT13_MCP0XLT0_SLOT0_M0_VALID + l_slot_offset); + } + + + // Check slave ranks + // Note this sems a little backward. S0 is the left-most slave bit. So, + // if there are more than 0 slave ranks, S2 will increment first. + if (l_dimm.iv_slave_ranks > 0) + { + l_xlate.setBit(MCS_PORT13_MCP0XLT0_SLOT0_S2_VALID + l_slot_offset); + } + + if (l_dimm.iv_slave_ranks > 2) + { + l_xlate.setBit(MCS_PORT13_MCP0XLT0_SLOT0_S1_VALID + l_slot_offset); + } + + if (l_dimm.iv_slave_ranks > 4) + { + l_xlate.setBit(MCS_PORT13_MCP0XLT0_SLOT0_S0_VALID + l_slot_offset); + } + + + // Tell the MC which of the row bits are valid. + if (l_dimm.iv_rows >= 16) + { + l_xlate.setBit(MCS_PORT02_MCP0XLT0_SLOT0_ROW15_VALID + l_slot_offset); + } + + if (l_dimm.iv_rows >= 17) + { + l_xlate.setBit(MCS_PORT02_MCP0XLT0_SLOT0_ROW16_VALID + l_slot_offset); + } + + if (l_dimm.iv_rows >= 18) + { + l_xlate.setBit(MCS_PORT02_MCP0XLT0_SLOT0_ROW17_VALID + l_slot_offset); + } + + } + + // TK: remove and make general in the loop above BRS + + // Two rank DIMM, so master bit 1 (least significant) bit needs to be mapped. + l_xlate.insertFromRight<MCS_PORT02_MCP0XLT0_M1_BIT_MAP, MCS_PORT02_MCP0XLT0_M1_BIT_MAP_LEN>(0b01111); + + // Slot 1 isn't populated, so forget those bits for now. + + // DIMM bit map isn't exactly ignored for only one populated slot. It still needs to be + // set in the map. Per S. Powell. + // Master rank 0, 1 bit maps are ignored. + // Row 16,17 bit maps are ignored. + // Row 15 maps to Port Address bit 6 + l_xlate.insertFromRight<MCS_PORT02_MCP0XLT0_D_BIT_MAP, MCS_PORT02_MCP0XLT0_D_BIT_MAP_LEN>(0b00101); + l_xlate.insertFromRight<MCS_PORT02_MCP0XLT0_R15_BIT_MAP, MCS_PORT02_MCP0XLT0_R15_BIT_MAP_LEN>(0b00110); + + // Drop down the column assignments + l_xlate1.insertFromRight<MCS_PORT02_MCP0XLT1_COL4_BIT_MAP, + MCS_PORT02_MCP0XLT1_COL4_BIT_MAP_LEN>(0b01101); + + l_xlate1.insertFromRight<MCS_PORT02_MCP0XLT1_COL5_BIT_MAP, + MCS_PORT02_MCP0XLT1_COL5_BIT_MAP_LEN>(0b01100); + + l_xlate1.insertFromRight<MCS_PORT02_MCP0XLT1_COL6_BIT_MAP, + MCS_PORT02_MCP0XLT1_COL6_BIT_MAP_LEN>(0b01011); + + l_xlate1.insertFromRight<MCS_PORT02_MCP0XLT1_COL7_BIT_MAP, + MCS_PORT02_MCP0XLT1_COL7_BIT_MAP_LEN>(0b01010); + + l_xlate2.insertFromRight<MCS_PORT02_MCP0XLT2_COL8_BIT_MAP, + MCS_PORT02_MCP0XLT2_COL8_BIT_MAP_LEN>(0b01001); + + l_xlate2.insertFromRight<MCS_PORT02_MCP0XLT2_COL9_BIT_MAP, + MCS_PORT02_MCP0XLT2_COL9_BIT_MAP_LEN>(0b00111); + + l_xlate2.insertFromRight<MCS_PORT02_MCP0XLT2_BANK0_BIT_MAP, + MCS_PORT02_MCP0XLT2_BANK0_BIT_MAP_LEN>(0b01110); + + l_xlate2.insertFromRight<MCS_PORT02_MCP0XLT2_BANK1_BIT_MAP, + MCS_PORT02_MCP0XLT2_BANK1_BIT_MAP_LEN>(0b10000); + + l_xlate2.insertFromRight<MCS_PORT02_MCP0XLT2_BANK_GROUP0_BIT_MAP, + MCS_PORT02_MCP0XLT2_BANK_GROUP0_BIT_MAP_LEN>(0b10001); + + l_xlate2.insertFromRight<MCS_PORT02_MCP0XLT2_BANK_GROUP1_BIT_MAP, + MCS_PORT02_MCP0XLT2_BANK_GROUP1_BIT_MAP_LEN>(0b10010); + + FAPI_DBG("HACK: Cramming 0x%016lx in for MCP0XLT0", l_xlate); + FAPI_DBG("HACK: Cramming 0x%016lx in for MCP0XLT1", l_xlate1); + FAPI_DBG("HACK: Cramming 0x%016lx in for MCP0XLT2", l_xlate2); + + FAPI_TRY( mss::putScom(i_target.getParent<TARGET_TYPE_MCS>(), MCS_0_PORT02_MCP0XLT0, l_xlate) ); + FAPI_TRY( mss::putScom(i_target.getParent<TARGET_TYPE_MCS>(), MCS_0_PORT02_MCP0XLT1, l_xlate1) ); + FAPI_TRY( mss::putScom(i_target.getParent<TARGET_TYPE_MCS>(), MCS_0_PORT02_MCP0XLT2, l_xlate2) ); + +fapi_try_exit: + return fapi2::current_err; +} + + +} // namespace |