summaryrefslogtreecommitdiffstats
path: root/src/import/chips/centaur
diff options
context:
space:
mode:
authorLouis Stermole <stermole@us.ibm.com>2018-10-19 15:55:14 -0500
committerChristian R. Geddes <crgeddes@us.ibm.com>2018-10-30 13:06:59 -0500
commit7b0ac241e5dd190aa4df5429570d2b4eae6097a0 (patch)
tree1702fc6b4920ba24cc6f6a37b58d3a1be9edd183 /src/import/chips/centaur
parent59b84449bc4987b340c04c40a0d4c9d6dae43d72 (diff)
downloadtalos-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')
-rwxr-xr-xsrc/import/chips/centaur/procedures/hwp/memory/p9c_mss_ddr4_funcs.C27
-rwxr-xr-xsrc/import/chips/centaur/procedures/hwp/memory/p9c_mss_ddr4_funcs.H8
-rwxr-xr-xsrc/import/chips/centaur/procedures/hwp/memory/p9c_mss_draminit_training.C2
-rwxr-xr-xsrc/import/chips/centaur/procedures/hwp/memory/p9c_mss_draminit_training.H2
-rwxr-xr-xsrc/import/chips/centaur/procedures/hwp/memory/p9c_mss_funcs.C79
-rw-r--r--src/import/chips/centaur/procedures/hwp/memory/p9c_mss_row_repair.C67
-rw-r--r--src/import/chips/centaur/procedures/hwp/memory/p9c_mss_row_repair.H5
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
OpenPOWER on IntegriCloud