diff options
author | Louis Stermole <stermole@us.ibm.com> | 2018-10-19 15:55:14 -0500 |
---|---|---|
committer | Christian R. Geddes <crgeddes@us.ibm.com> | 2018-10-30 13:06:59 -0500 |
commit | 7b0ac241e5dd190aa4df5429570d2b4eae6097a0 (patch) | |
tree | 1702fc6b4920ba24cc6f6a37b58d3a1be9edd183 /src/import/chips/centaur | |
parent | 59b84449bc4987b340c04c40a0d4c9d6dae43d72 (diff) | |
download | talos-hostboot-7b0ac241e5dd190aa4df5429570d2b4eae6097a0.tar.gz talos-hostboot-7b0ac241e5dd190aa4df5429570d2b4eae6097a0.zip |
Fix MR0 corruption when applying rank1 row repair on p9c
Also fix RCD parity errors on 3DS parts
Change-Id: I4f1d2f524e0db04922123f9e52e92894ac86e752
CQ:SW449205
Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/67780
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Reviewed-by: STEPHEN GLANCY <sglancy@us.ibm.com>
Reviewed-by: ANDRE A. MARIN <aamarin@us.ibm.com>
Tested-by: Hostboot CI <hostboot-ci+hostboot@us.ibm.com>
Reviewed-by: Jennifer A. Stofer <stofer@us.ibm.com>
Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/67782
Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com>
Tested-by: Jenkins OP HW <op-hw-jenkins+hostboot@us.ibm.com>
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Reviewed-by: Christian R. Geddes <crgeddes@us.ibm.com>
Diffstat (limited to 'src/import/chips/centaur')
7 files changed, 97 insertions, 93 deletions
diff --git a/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_ddr4_funcs.C b/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_ddr4_funcs.C index c09887ff7..ea16424b3 100755 --- a/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_ddr4_funcs.C +++ b/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_ddr4_funcs.C @@ -2522,7 +2522,8 @@ uint8_t convert_rtt_wr_to_rtt_nom(uint8_t i_rtt_wr, uint8_t& i_rtt_nom) /// @brief Setup CCS for B-side writes /// @param[in] i_target mba target being calibrated /// @param[in] i_port port being calibrated -/// @param[in] i_rank rank being calibrated +/// @param[in] i_mrank mrank being calibrated +/// @param[in] i_srank srank being calibrated /// @param[in] i_address_16 A-side DRAM address /// @param[in] i_bank_3 A-side bank address /// @param[in] i_activate_1 activate bit @@ -2544,7 +2545,8 @@ uint8_t convert_rtt_wr_to_rtt_nom(uint8_t i_rtt_wr, uint8_t& i_rtt_nom) /// fapi2::ReturnCode setup_b_side_ccs(const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_target, const uint8_t i_port, - const uint32_t i_rank, + const uint8_t i_mrank, + const uint8_t i_srank, const fapi2::variable_buffer& i_address_16, const fapi2::variable_buffer& i_bank_3, const fapi2::variable_buffer& i_activate_1, @@ -2572,8 +2574,8 @@ fapi2::ReturnCode setup_b_side_ccs(const fapi2::Target<fapi2::TARGET_TYPE_MBA>& uint8_t l_is_sim = 0; uint8_t l_dram_stack[MAX_PORTS_PER_MBA][MAX_DIMM_PER_PORT] = {0}; uint8_t l_address_mirror_map[MAX_PORTS_PER_MBA][MAX_DIMM_PER_PORT] = {0}; //address_mirror_map[port][dimm] - const uint8_t l_dimm = (i_rank) / MAX_RANKS_PER_DIMM; - const uint8_t l_dimm_rank = i_rank - MAX_RANKS_PER_DIMM * l_dimm; + const uint8_t l_dimm = (i_mrank) / MAX_RANKS_PER_DIMM; + const uint8_t l_dimm_rank = i_mrank - MAX_RANKS_PER_DIMM * l_dimm; FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CEN_EFF_DIMM_TYPE, i_target, l_dimm_type)); FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_IS_SIMULATION, fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>(), l_is_sim)); @@ -2607,8 +2609,8 @@ fapi2::ReturnCode setup_b_side_ccs(const fapi2::Target<fapi2::TARGET_TYPE_MBA>& } // Only corresponding CS to rank - FAPI_TRY(l_csn_8.setBit(0, 8)); - FAPI_TRY(l_csn_8.clearBit(i_rank)); + access_address l_addr = {0, 0, i_mrank, i_srank, 0, 0}; + FAPI_TRY(cs_decode(i_target, l_addr, l_dram_stack[i_port][l_dimm], l_csn_8)); FAPI_TRY(mss_disable_cid(i_target, l_csn_8, l_cke_4)); @@ -2655,7 +2657,7 @@ fapi_try_exit: /// fapi2::ReturnCode setup_wr_lvl_mrs_ddr4(const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_target, const uint8_t i_port, - const uint32_t i_rank, + const uint8_t i_rank, const uint8_t i_state, uint32_t& io_ccs_inst_cnt) { @@ -2764,7 +2766,7 @@ fapi2::ReturnCode setup_wr_lvl_mrs_ddr4(const fapi2::Target<fapi2::TARGET_TYPE_M io_ccs_inst_cnt++; // Do a B side MRS write - FAPI_TRY( setup_b_side_ccs(i_target, i_port, i_rank, l_data_buffer_16_backup, + FAPI_TRY( setup_b_side_ccs(i_target, i_port, i_rank, 0, l_data_buffer_16_backup, l_bank_3_backup, l_activate_1, l_rasn_1, l_casn_1, l_wen_1, l_cke_4, l_odt_4, l_ddr_cal_type_4, l_num_idles_16, l_num_repeat_16, l_data_20, l_read_compare_1, l_rank_cal_4, l_ddr_cal_enable_1, @@ -3004,7 +3006,7 @@ fapi2::ReturnCode mss_ddr4_rtt_nom_rtt_wr_swap( io_ccs_inst_cnt++; //do a B side MRS write if needed - FAPI_TRY( setup_b_side_ccs(i_target, i_port_number, i_rank, l_address_16_backup, + FAPI_TRY( setup_b_side_ccs(i_target, i_port_number, i_rank, 0, l_address_16_backup, l_bank_3_backup, l_activate_1, l_rasn_1, l_casn_1, l_wen_1, l_cke_4, l_odt_4, l_ddr_cal_type_4, l_num_idles_16, l_num_repeat_16, l_data_20, l_read_compare_1, l_rank_cal_4, l_ddr_cal_enable_1, @@ -4802,6 +4804,7 @@ fapi2::ReturnCode add_mrs_to_ccs_ddr4(const fapi2::Target<fapi2::TARGET_TYPE_MBA // CCS Array 0 buffers fapi2::variable_buffer addr_16(16); + fapi2::variable_buffer addr_16_pre_swizzle(16); fapi2::variable_buffer bank_3(3); fapi2::variable_buffer ddr4_activate_1(1); fapi2::variable_buffer rasn_1(1); @@ -4835,6 +4838,7 @@ fapi2::ReturnCode add_mrs_to_ccs_ddr4(const fapi2::Target<fapi2::TARGET_TYPE_MBA FAPI_TRY(addr_16.extract(l_data_16)); l_data_16.reverse(); FAPI_TRY(addr_16.insert((uint16_t)l_data_16)); + FAPI_TRY(addr_16_pre_swizzle.insert((uint16_t)l_data_16)); FAPI_TRY(bank_3.insertFromRight(i_addr.bank, 0, 3)); FAPI_TRY(bank_3.extract(l_data_8, 0, 3)); l_data_8.reverse(); @@ -4842,9 +4846,10 @@ fapi2::ReturnCode add_mrs_to_ccs_ddr4(const fapi2::Target<fapi2::TARGET_TYPE_MBA FAPI_INF("%s add_MRS_to_ccs ADDR : 0x%04X MR : 0x%X", mss::c_str(i_target_mba), i_addr.row_addr, i_addr.bank); FAPI_TRY(cs_decode(i_target_mba, i_addr, l_stack_type_u8array[0][0], csn_8)); + cke_4.flush<1>(); + FAPI_TRY(mss_disable_cid(i_target_mba, csn_8, cke_4)); // Command structure setup - cke_4.flush<1>(); FAPI_TRY(rasn_1.clearBit(0)); FAPI_TRY(casn_1.clearBit(0)); FAPI_TRY(wen_1.clearBit(0)); @@ -4896,7 +4901,7 @@ fapi2::ReturnCode add_mrs_to_ccs_ddr4(const fapi2::Target<fapi2::TARGET_TYPE_MBA ++io_instruction_number; // Do a B side MRS write - FAPI_TRY( setup_b_side_ccs(i_target_mba, l_port, i_addr.mrank, addr_16, + FAPI_TRY( setup_b_side_ccs(i_target_mba, l_port, i_addr.mrank, i_addr.srank, addr_16_pre_swizzle, bank_3, ddr4_activate_1, rasn_1, casn_1, wen_1, cke_4, odt_4, cal_type_4, idles_16, repeat_16, pattern_20, read_compare_1, rank_cal_4, cal_enable_1, diff --git a/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_ddr4_funcs.H b/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_ddr4_funcs.H index e2d87c0b9..328bc42ae 100755 --- a/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_ddr4_funcs.H +++ b/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_ddr4_funcs.H @@ -164,7 +164,7 @@ fapi2::ReturnCode mss_ddr4_rtt_nom_rtt_wr_swap(const fapi2::Target<fapi2::TARGET /// fapi2::ReturnCode setup_wr_lvl_mrs_ddr4(const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_target, const uint8_t i_port, - const uint32_t i_rank, + const uint8_t i_rank, const uint8_t i_state, uint32_t& io_ccs_inst_cnt); @@ -172,7 +172,8 @@ fapi2::ReturnCode setup_wr_lvl_mrs_ddr4(const fapi2::Target<fapi2::TARGET_TYPE_M /// @brief Setup CCS for B-side writes /// @param[in] i_target mba target being calibrated /// @param[in] i_port port being calibrated -/// @param[in] i_rank rank being calibrated +/// @param[in] i_mrank mrank being calibrated +/// @param[in] i_srank srank being calibrated /// @param[in] i_address_16 A-side DRAM address /// @param[in] i_bank_3 A-side bank address /// @param[in] i_activate_1 activate bit @@ -194,7 +195,8 @@ fapi2::ReturnCode setup_wr_lvl_mrs_ddr4(const fapi2::Target<fapi2::TARGET_TYPE_M /// fapi2::ReturnCode setup_b_side_ccs(const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_target, const uint8_t i_port, - const uint32_t i_rank, + const uint8_t i_mrank, + const uint8_t i_srank, const fapi2::variable_buffer& i_address_16, const fapi2::variable_buffer& i_bank_3, const fapi2::variable_buffer& i_activate_1, diff --git a/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_draminit_training.C b/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_draminit_training.C index fcba16ebe..abbe5d013 100755 --- a/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_draminit_training.C +++ b/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_draminit_training.C @@ -3318,7 +3318,7 @@ extern "C" { /// fapi2::ReturnCode send_wr_lvl_mrs(const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_target, const uint8_t i_port, - const uint32_t i_rank, + const uint8_t i_rank, const uint8_t i_state, uint32_t& io_ccs_inst_cnt) { diff --git a/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_draminit_training.H b/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_draminit_training.H index c5e7f5708..3f52b2413 100755 --- a/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_draminit_training.H +++ b/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_draminit_training.H @@ -218,7 +218,7 @@ extern "C" /// fapi2::ReturnCode send_wr_lvl_mrs(const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_target, const uint8_t i_port, - const uint32_t i_rank, + const uint8_t i_rank, const uint8_t i_state, uint32_t& io_ccs_inst_cnt); diff --git a/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_funcs.C b/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_funcs.C index 23ef5c9a5..0c84fe73f 100755 --- a/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_funcs.C +++ b/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_funcs.C @@ -445,23 +445,9 @@ fapi2::ReturnCode mss_ccs_inst_arry_0( uint32_t l_num_retry = 0; uint32_t l_timer = 0; uint8_t l_cs_start = 0; - uint8_t l_cke_start = 0; - uint8_t l_odt_start = 0; - uint8_t l_csn_4 = 0b00000000; - uint8_t l_csn_8 = 0; - uint8_t l_csn_mask = 0b11110000; + uint8_t l_csn_dimm0 = 0; uint8_t l_parity_bit = 0; - constexpr uint64_t l_data_buffer_mask_0_15 = 0xFFFF000000000000; - constexpr uint64_t l_data_buffer_mask_17_23 = 0x00007F0000000000; - constexpr uint64_t l_data_buffer_mask_34_35 = 0x0000000030000000; - constexpr uint64_t l_data_buffer_mask_38_39 = 0x0000000003000000; - constexpr uint64_t l_data_buffer_mask_46_47 = 0x0000000000300000; uint8_t l_parity_bit_even = 0; - uint64_t l_data_buffer_0_15 = 0; - uint64_t l_data_buffer_17_23 = 0; - uint64_t l_data_buffer_34_35 = 0; - uint64_t l_data_buffer_38_39 = 0; - uint64_t l_data_buffer_46_47 = 0; FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CEN_EFF_DIMM_TYPE, i_target, l_dimm_type)); @@ -533,65 +519,42 @@ fapi2::ReturnCode mss_ccs_inst_arry_0( if((l_dimm_type == fapi2::ENUM_ATTR_CEN_EFF_DIMM_TYPE_LRDIMM || l_dimm_type == fapi2::ENUM_ATTR_CEN_EFF_DIMM_TYPE_RDIMM) ) { - FAPI_DBG("CCS: RDIMM/LRDIMM\n"); - //Port A control signals - Port A chip select set - FAPI_TRY(i_csn.extract(l_csn_8)); + FAPI_TRY(i_csn.extractToRight(l_csn_dimm0, 0, 2)); - if(mss::bit_count(l_csn_8) < 8) + if (i_port == 0) { - //DIMM0 - DIMM0 CS set - l_csn_4 = l_csn_8 & l_csn_mask; - - if(mss::bit_count(l_csn_4) < 4) + // If any DIMM0 CS bits are cleared, we're selecting DIMM0 + if (l_csn_dimm0 != 3) { - l_cke_start = 24; l_cs_start = 32; - l_odt_start = 48; } - //DIMM1 + // If not, we're selecting DIMM1 else { - l_cke_start = 26; l_cs_start = 36; - l_odt_start = 50; } } - //Port B control signals else { - l_cke_start = 30; - l_cs_start = 44; - l_odt_start = 54; + // If any DIMM0 CS bits are cleared, we're selecting DIMM0 + if (l_csn_dimm0 != 3) + { + l_cs_start = 40; + } + // If not, we're selecting DIMM1 + else + { + l_cs_start = 44; + } } - FAPI_TRY(l_data_buffer.extract(l_data_64)); - - //adds CIDs + 1 extra bit for CID2 - l_data_buffer_0_15 = l_data_64 & l_data_buffer_mask_0_15; - l_data_buffer_17_23 = l_data_64 & l_data_buffer_mask_17_23; - l_data_buffer_34_35 = l_data_64 & l_data_buffer_mask_34_35; - l_data_buffer_38_39 = l_data_64 & l_data_buffer_mask_38_39; - l_data_buffer_46_47 = l_data_64 & l_data_buffer_mask_46_47; - - switch(l_cs_start) - { - case 32: - l_parity_bit = mss::bit_count(l_data_buffer_0_15) + mss::bit_count(l_data_buffer_17_23) + mss::bit_count( - l_data_buffer_34_35) ; - - case 36: - l_parity_bit = mss::bit_count(l_data_buffer_0_15) + mss::bit_count(l_data_buffer_17_23) + mss::bit_count( - l_data_buffer_38_39) ; - - case 44: - l_parity_bit = mss::bit_count(l_data_buffer_0_15) + mss::bit_count(l_data_buffer_17_23) + mss::bit_count( - l_data_buffer_46_47) ; - } + // CKE, CS, and ODT fields don't get counted for parity + // CID is the exception, if we're talking to a TSV part + l_parity_bit = l_data_buffer.getNumBitsSet(0, 16) + l_data_buffer.getNumBitsSet(17, + 7) + l_data_buffer.getNumBitsSet(l_cs_start + 2, 2); l_parity_bit_even = l_parity_bit % 2; - FAPI_DBG("Address %d BA/BG/CMD %d parity %d O/E %d - cke,cs,odt starts - %d,%d,%d \n", - mss::bit_count(l_data_buffer_0_15), - mss::bit_count(l_data_buffer_17_23), l_parity_bit, l_parity_bit_even, l_cke_start, l_cs_start, l_odt_start); + FAPI_TRY(l_data_buffer.insertFromRight(l_parity_bit_even, 60, 1)); } diff --git a/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_row_repair.C b/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_row_repair.C index 324e3fc33..ebd58f40d 100644 --- a/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_row_repair.C +++ b/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_row_repair.C @@ -60,8 +60,7 @@ extern "C" constexpr uint64_t REFRESH_BIT = CEN_MBA_MBAREF0Q_CFG_REFRESH_ENABLE; constexpr uint32_t NUM_POLL = 10; constexpr uint32_t WAIT_TIMER = 1500; - constexpr uint32_t ENABLE_PPR = 0x0020; - constexpr uint32_t DISABLE_PPR = 0; + constexpr uint32_t PPR_ENABLE = 5; constexpr uint8_t TMOD = 24; const std::vector<uint64_t> MR0_SHADOW_REGS = @@ -78,11 +77,8 @@ extern "C" // MRS address sequence for sPPR setup // Note that we need to set a valid column address for these, so we use '0' - const std::vector<access_address> l_mrs_addrs = + const std::vector<access_address> l_guard_key_sequence = { - // Puts the DRAM into PPR mode - {ENABLE_PPR, 0, i_mrank, i_srank, MRS4_BA, i_port}, - // Writes the guard key sequence to MR0 (4 commands) {0x0CFF, 0, i_mrank, i_srank, MRS0_BA, i_port}, {0x07FF, 0, i_mrank, i_srank, MRS0_BA, i_port}, {0x0BFF, 0, i_mrank, i_srank, MRS0_BA, i_port}, @@ -90,12 +86,18 @@ extern "C" }; const uint8_t l_bg_bank = (i_bank << 2) | i_bg; + const uint8_t l_dimm = i_mrank / MAX_RANKS_PER_DIMM; + const uint8_t l_dimm_rank = i_mrank % MAX_RANKS_PER_DIMM; access_address l_addr = {i_row, 0, i_mrank, i_srank, l_bg_bank, i_port}; + access_address l_enable_sppr = l_addr; + fapi2::variable_buffer l_data_16(16); + fapi2::variable_buffer l_bank_3(3); fapi2::buffer<uint64_t> l_row; fapi2::buffer<uint64_t> l_bank; fapi2::buffer<uint64_t> l_saved_mr0; fapi2::buffer<uint64_t> l_reg_buffer; fapi2::buffer<uint64_t> l_dram_scratch; + fapi2::buffer<uint16_t> l_mr_value_16; uint64_t l_write_pattern = 0; uint32_t l_instruction_number = 0; uint8_t l_refresh = 0; @@ -150,7 +152,16 @@ extern "C" FAPI_TRY(add_precharge_all_to_ccs(i_target_mba, l_addr, l_trcd, l_odt, l_stack_type_u8array, l_instruction_number)); // Put the DRAM into sPPR mode - for (auto l_mrs_addr : l_mrs_addrs) + FAPI_TRY(mss_ddr4_load_nominal_mrs_pda(i_target_mba, l_bank_3, l_data_16, MRS4_BA, i_port, l_dimm, l_dimm_rank)); + FAPI_TRY(l_data_16.setBit(PPR_ENABLE)); + l_data_16.extractToRight(l_mr_value_16, 0, 16); + l_mr_value_16.reverse(); + l_mr_value_16.extractToRight(l_enable_sppr.row_addr, 0, 16); + l_enable_sppr.bank = MRS4_BA; + FAPI_TRY(add_mrs_to_ccs_ddr4(i_target_mba, l_enable_sppr, TMOD, l_instruction_number)); + + // Enter the guard key sequence + for (auto l_mrs_addr : l_guard_key_sequence) { FAPI_TRY(add_mrs_to_ccs_ddr4(i_target_mba, l_mrs_addr, TMOD, l_instruction_number)); } @@ -159,9 +170,13 @@ extern "C" FAPI_DBG("%s Enabling CCS", mss::c_str(i_target_mba)); FAPI_TRY(fapi2::getScom(i_target_mba, CEN_MBA_CCS_MODEQ, l_reg_buffer)); FAPI_TRY(l_reg_buffer.setBit(29)); //Enable CCS + FAPI_TRY(l_reg_buffer.setBit(51)); //ACT high FAPI_TRY(l_reg_buffer.setBit(52)); //RAS high FAPI_TRY(l_reg_buffer.setBit(53)); //CAS high FAPI_TRY(l_reg_buffer.setBit(54)); //WE high + // Enables manual calculation of CCS parity + // Manual calculation is needed to workaround a hardware bug calculating parity for DDR4 in CCS + FAPI_TRY(l_reg_buffer.setBit(61)); FAPI_TRY(fapi2::putScom(i_target_mba, CEN_MBA_CCS_MODEQ, l_reg_buffer)); // Subtract one from the instruction count because set_end_bit increments it @@ -193,27 +208,36 @@ extern "C" // Issue precharge all command FAPI_TRY(add_precharge_all_to_ccs(i_target_mba, l_addr, l_trcd, l_odt, l_stack_type_u8array, l_instruction_number)); - // Issue DES command for tPGM_exit (12 clks) - FAPI_TRY(add_des_with_repeat_to_ccs(i_target_mba, l_addr, 0, 12, l_instruction_number)); + // Issue DES command for tPGM_exit (18 clks) + FAPI_TRY(add_des_with_repeat_to_ccs(i_target_mba, l_addr, 0, 18, l_instruction_number)); - // Take the DRAM out of PPR mode (MR4 command) - l_addr.row_addr = DISABLE_PPR; + // Take the DRAM out of PPR mode (MR4 command) and restore original value + FAPI_TRY(mss_ddr4_load_nominal_mrs_pda(i_target_mba, l_bank_3, l_data_16, MRS4_BA, i_port, l_dimm, l_dimm_rank)); + l_data_16.extractToRight(l_mr_value_16, 0, 16); + l_mr_value_16.reverse(); + l_mr_value_16.extractToRight(l_addr.row_addr, 0, 16); l_addr.bank = MRS4_BA; FAPI_TRY(add_mrs_to_ccs_ddr4(i_target_mba, l_addr, TMOD, l_instruction_number)); - // Put the DRAM into the original MR0 mode + // Restore MR0 to nominal value + FAPI_TRY(mss_ddr4_load_nominal_mrs_pda(i_target_mba, l_bank_3, l_data_16, MRS0_BA, i_port, l_dimm, l_dimm_rank)); + l_data_16.extractToRight(l_mr_value_16, 0, 16); + l_mr_value_16.reverse(); + l_mr_value_16.extractToRight(l_addr.row_addr, 0, 16); l_addr.bank = MRS0_BA; - FAPI_TRY(l_saved_mr0.clearBit(55)); //clear the dll reset. - l_saved_mr0.extractToRight(l_addr.row_addr, 46, 18); FAPI_TRY(add_mrs_to_ccs_ddr4(i_target_mba, l_addr, TMOD, l_instruction_number)); // Enable CCS and set RAS/CAS/WE high during idles FAPI_DBG("%s Enabling CCS", mss::c_str(i_target_mba)); FAPI_TRY(fapi2::getScom(i_target_mba, CEN_MBA_CCS_MODEQ, l_reg_buffer)); FAPI_TRY(l_reg_buffer.setBit(29)); //Enable CCS + FAPI_TRY(l_reg_buffer.setBit(51)); //ACT high FAPI_TRY(l_reg_buffer.setBit(52)); //RAS high FAPI_TRY(l_reg_buffer.setBit(53)); //CAS high FAPI_TRY(l_reg_buffer.setBit(54)); //WE high + // Enables manual calculation of CCS parity + // Manual calculation is needed to workaround a hardware bug calculating parity for DDR4 in CCS + FAPI_TRY(l_reg_buffer.setBit(61)); FAPI_TRY(fapi2::putScom(i_target_mba, CEN_MBA_CCS_MODEQ, l_reg_buffer)); // Subtract one from the instruction count because set_end_bit increments it @@ -485,6 +509,8 @@ extern "C" /// @return FAPI2_RC_SUCCESS iff successful fapi2::ReturnCode p9c_mss_activate_all_spare_rows(const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_target_mba) { + constexpr uint8_t NUM_BG = 4; + uint8_t l_ranks_configed[MAX_PORTS_PER_MBA][MAX_DIMM_PER_PORT] = {0}; uint8_t num_mranks[MAX_PORTS_PER_MBA][MAX_DIMM_PER_PORT] = {0}; uint8_t num_ranks[MAX_PORTS_PER_MBA][MAX_DIMM_PER_PORT] = {0}; @@ -519,13 +545,16 @@ extern "C" uint8_t l_port_rank = 0; // Note: setting row = rank so we don't use row0 for every repair uint32_t l_row = l_mrank; - // Note: DIMM can only support one repair per BG, so we use BG=0 and BA=0 - uint8_t l_bg = 0; - uint8_t l_bank = 0; - l_port_rank = (l_dimm_index * MAX_RANKS_PER_DIMM) + l_mrank; + // Note: DIMM can only support one repair per BG, so we loop on BG and use BA=0 + for (uint8_t l_bg = 0; l_bg < NUM_BG; ++l_bg) + { + uint8_t l_bank = 0; + + l_port_rank = (l_dimm_index * MAX_RANKS_PER_DIMM) + l_mrank; - FAPI_TRY(p9c_mss_row_repair(i_target_mba, l_port, l_port_rank, l_srank, l_bg, l_bank, l_row, l_dram_bitmap)); + FAPI_TRY(p9c_mss_row_repair(i_target_mba, l_port, l_port_rank, l_srank, l_bg, l_bank, l_row, l_dram_bitmap)); + } } } } diff --git a/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_row_repair.H b/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_row_repair.H index 37e26275e..4269f8ba1 100644 --- a/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_row_repair.H +++ b/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_row_repair.H @@ -97,6 +97,11 @@ extern "C" const uint8_t (&i_bad_bits)[MAX_RANKS_PER_PORT][DIMM_DQ_RANK_BITMAP_SIZE], bool& o_uncalibrated); + /// @brief Deploy enough PPR row repairs to test all spare rows + /// @param[in] i_target_mba mba target + /// @return FAPI2_RC_SUCCESS iff successful + fapi2::ReturnCode p9c_mss_activate_all_spare_rows(const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_target_mba); + /// @brief Clear the corresponding bad_bits after a row repair operation /// @param[in] i_dram_width the DRAM width /// @param[in] i_dram the DRAM index |