summaryrefslogtreecommitdiffstats
path: root/src/import/chips/centaur
diff options
context:
space:
mode:
authorLouis Stermole <stermole@us.ibm.com>2018-07-03 14:17:13 -0500
committerDaniel M. Crowell <dcrowell@us.ibm.com>2018-10-03 09:52:35 -0500
commitbdf069fd13603c3ba43d7831df25fcb6f5b81c4a (patch)
tree450ee24ea97404b5903940d673f0a8fc4f444d22 /src/import/chips/centaur
parent5957dac24557166ad9c3fed5fbf48d717670f548 (diff)
downloadtalos-hostboot-bdf069fd13603c3ba43d7831df25fcb6f5b81c4a.tar.gz
talos-hostboot-bdf069fd13603c3ba43d7831df25fcb6f5b81c4a.zip
Add soft PPR (row repair) function for p9c
Change-Id: I728a494f91f1f460c0700bbeeca47a0e5739622f CQ:SW444976 Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/61829 Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Reviewed-by: STEPHEN GLANCY <sglancy@us.ibm.com> Tested-by: Hostboot CI <hostboot-ci+hostboot@us.ibm.com> Reviewed-by: ANDRE A. MARIN <aamarin@us.ibm.com> Reviewed-by: Jennifer A. Stofer <stofer@us.ibm.com> Reviewed-on: http://rchgit01.rchland.ibm.com/gerrit1/61896 Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com> Tested-by: Daniel M. Crowell <dcrowell@us.ibm.com>
Diffstat (limited to 'src/import/chips/centaur')
-rwxr-xr-xsrc/import/chips/centaur/procedures/hwp/memory/p9c_mss_ddr4_funcs.C123
-rwxr-xr-xsrc/import/chips/centaur/procedures/hwp/memory/p9c_mss_ddr4_funcs.H12
-rwxr-xr-xsrc/import/chips/centaur/procedures/hwp/memory/p9c_mss_funcs.C713
-rwxr-xr-xsrc/import/chips/centaur/procedures/hwp/memory/p9c_mss_funcs.H77
-rw-r--r--src/import/chips/centaur/procedures/hwp/memory/p9c_mss_row_repair.C215
-rw-r--r--src/import/chips/centaur/procedures/hwp/memory/p9c_mss_row_repair.H36
-rw-r--r--src/import/chips/centaur/procedures/hwp/memory/p9c_mss_row_repair.mk7
-rw-r--r--src/import/chips/centaur/procedures/xml/error_info/p9c_mss_funcs_errors.xml13
8 files changed, 1189 insertions, 7 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 ccb9b195c..1ed21be5d 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
@@ -4781,3 +4781,126 @@ fapi2::ReturnCode mss_ddr4_load_nominal_mrs_pda(const fapi2::Target<fapi2::TARGE
fapi_try_exit:
return fapi2::current_err;
}
+
+/// @brief Add an MRS command to the CCS program
+/// @param[in] i_target_mba mba target
+/// @param[in] i_addr address struct for MRS
+/// @param[in] i_delay delay associated with this instruction
+/// @param[in,out] io_instruction_number position in CCS program in which to insert MRS command (will be incremented)
+/// @return FAPI2_RC_SUCCESS iff successful
+fapi2::ReturnCode add_mrs_to_ccs_ddr4(const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_target_mba,
+ const access_address i_addr,
+ const uint32_t i_delay,
+ uint32_t& io_instruction_number)
+{
+ uint8_t l_is_sim = 0;
+ uint8_t l_address_mirror_map[MAX_PORTS_PER_MBA][MAX_DIMM_PER_PORT] = {0}; //address_mirror_map[port][dimm]
+ uint8_t l_stack_type_u8array[MAX_PORTS_PER_MBA][MAX_DIMM_PER_PORT] = {0};
+ const uint8_t l_dimm = i_addr.mrank / MAX_RANKS_PER_DIMM;
+ const uint8_t l_dimm_rank = i_addr.mrank % MAX_RANKS_PER_DIMM;
+
+ // CCS Array 0 buffers
+ fapi2::variable_buffer addr_16(16);
+ fapi2::variable_buffer bank_3(3);
+ fapi2::variable_buffer ddr4_activate_1(1);
+ fapi2::variable_buffer rasn_1(1);
+ fapi2::variable_buffer casn_1(1);
+ fapi2::variable_buffer wen_1(1);
+ fapi2::variable_buffer cke_4(4);
+ fapi2::variable_buffer csn_8(8);
+ fapi2::variable_buffer odt_4(4);
+ fapi2::variable_buffer cal_type_4(4);
+
+ // CCS Array 1 buffers
+ fapi2::variable_buffer idles_16(16);
+ fapi2::variable_buffer repeat_16(16);
+ fapi2::variable_buffer pattern_20(20);
+ fapi2::variable_buffer read_compare_1(1);
+ fapi2::variable_buffer rank_cal_4(4);
+ fapi2::variable_buffer cal_enable_1(1);
+ fapi2::variable_buffer ccs_end_1(1);
+ fapi2::buffer<uint8_t> l_data_8;
+ fapi2::buffer<uint16_t> l_data_16;
+ uint32_t l_port = i_addr.port;
+
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_IS_SIMULATION, fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>(), l_is_sim));
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CEN_EFF_DRAM_ADDRESS_MIRRORING, i_target_mba, l_address_mirror_map));
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CEN_EFF_STACK_TYPE, i_target_mba, l_stack_type_u8array));
+
+ // CCS Array 0 Setup
+
+ // Buffer conversions from inputs
+ FAPI_TRY(addr_16.insertFromRight(i_addr.row_addr, 0, 16));
+ FAPI_TRY(addr_16.extract(l_data_16));
+ l_data_16.reverse();
+ FAPI_TRY(addr_16.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();
+ FAPI_TRY(bank_3.insertFromRight((uint8_t)l_data_8, 0 , 3));
+ 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));
+
+ // 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));
+
+ FAPI_TRY(read_compare_1.clearBit(0));
+
+ // Final setup
+ odt_4.flush<0>();
+ cal_type_4.flush<0>();
+ FAPI_TRY(ddr4_activate_1.setBit(0));
+
+ if ((l_address_mirror_map[l_port][l_dimm] & (0x08 >> l_dimm_rank) ) && (l_is_sim == 0))
+ {
+ FAPI_TRY(mss_address_mirror_swizzle(i_target_mba, addr_16, bank_3));
+ }
+
+ FAPI_TRY(mss_ccs_inst_arry_0(i_target_mba,
+ io_instruction_number,
+ addr_16,
+ bank_3,
+ ddr4_activate_1,
+ rasn_1,
+ casn_1,
+ wen_1,
+ cke_4,
+ csn_8,
+ odt_4,
+ cal_type_4,
+ l_port));
+
+ // CCS Array 1 Setup
+ FAPI_TRY(idles_16.insertFromRight(i_delay, 0, 16));
+ repeat_16.flush<0>();
+ pattern_20.flush<0>();
+ read_compare_1.flush<0>();
+ rank_cal_4.flush<0>();
+ cal_enable_1.flush<0>();
+ ccs_end_1.flush<0>();
+
+ FAPI_TRY(mss_ccs_inst_arry_1(i_target_mba,
+ io_instruction_number,
+ idles_16,
+ repeat_16,
+ pattern_20,
+ read_compare_1,
+ rank_cal_4,
+ cal_enable_1,
+ ccs_end_1));
+ ++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,
+ 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,
+ ccs_end_1, io_instruction_number) );
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
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 eb20a97fd..56525f340 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
@@ -35,6 +35,7 @@
#ifndef _MSS_DDR4_FUNCS_H
#define _MSS_DDR4_FUNCS_H
+#include <p9c_mss_funcs.H>
//----------------------------------------------------------------------
// DDR4 FUNCS
@@ -212,6 +213,17 @@ fapi2::ReturnCode setup_b_side_ccs(const fapi2::Target<fapi2::TARGET_TYPE_MBA>&
const fapi2::variable_buffer& i_ccs_end_1,
uint32_t& io_ccs_inst_cnt);
+/// @brief Add an MRS command to the CCS program
+/// @param[in] i_target_mba mba target
+/// @param[in] i_addr address struct for MRS
+/// @param[in] i_delay delay associated with this instruction
+/// @param[in,out] io_instruction_number position in CCS program in which to insert MRS command (will be incremented)
+/// @return FAPI2_RC_SUCCESS iff successful
+fapi2::ReturnCode add_mrs_to_ccs_ddr4(const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_target_mba,
+ const access_address i_addr,
+ const uint32_t i_delay,
+ uint32_t& io_instruction_number);
+
#endif /* _MSS_DDR4_FUNCS_H */
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 716d31e7b..657366923 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
@@ -39,6 +39,7 @@
#include <fapi2.H>
#include <p9c_mss_funcs.H>
#include <cen_gen_scom_addresses.H>
+#include <cen_gen_scom_addresses_fld.H>
#include <generic/memory/lib/utils/c_str.H>
#include <generic/memory/lib/utils/bit_count.H>
@@ -2456,6 +2457,121 @@ fapi2::ReturnCode add_nop_to_ccs(const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_
cal_type_4,
l_port));
+ // CCS Array 1 Setup
+ FAPI_TRY(idles_16.insertFromRight(i_delay, 0, 16));
+ repeat_16.flush<0>();
+ pattern_20.flush<0>();
+ read_compare_1.flush<0>();
+ rank_cal_4.flush<0>();
+ cal_enable_1.flush<0>();
+ ccs_end_1.flush<0>();
+
+ FAPI_TRY(mss_ccs_inst_arry_1(i_target_mba,
+ io_instruction_number,
+ idles_16,
+ repeat_16,
+ pattern_20,
+ read_compare_1,
+ rank_cal_4,
+ cal_enable_1,
+ ccs_end_1));
+ ++io_instruction_number;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+/// @brief Add an MRS command to the CCS program
+/// @param[in] i_target_mba mba target
+/// @param[in] i_addr address struct for MRS
+/// @param[in] i_delay delay associated with this instruction
+/// @param[in,out] io_instruction_number position in CCS program in which to insert MRS command (will be incremented)
+/// @return FAPI2_RC_SUCCESS iff successful
+fapi2::ReturnCode add_mrs_to_ccs(const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_target_mba,
+ const access_address i_addr,
+ const uint32_t i_delay,
+ uint32_t& io_instruction_number)
+{
+ uint8_t l_is_sim = 0;
+ uint8_t l_address_mirror_map[MAX_PORTS_PER_MBA][MAX_DIMM_PER_PORT] = {0}; //address_mirror_map[port][dimm]
+ uint8_t l_stack_type_u8array[MAX_PORTS_PER_MBA][MAX_DIMM_PER_PORT] = {0};
+ const uint8_t l_dimm = i_addr.mrank / MAX_RANKS_PER_DIMM;
+ const uint8_t l_dimm_rank = i_addr.mrank - MAX_RANKS_PER_DIMM * l_dimm;
+
+ // CCS Array 0 buffers
+ fapi2::variable_buffer addr_16(16);
+ fapi2::variable_buffer bank_3(3);
+ fapi2::variable_buffer ddr4_activate_1(1);
+ fapi2::variable_buffer rasn_1(1);
+ fapi2::variable_buffer casn_1(1);
+ fapi2::variable_buffer wen_1(1);
+ fapi2::variable_buffer cke_4(4);
+ fapi2::variable_buffer csn_8(8);
+ fapi2::variable_buffer odt_4(4);
+ fapi2::variable_buffer cal_type_4(4);
+
+ // CCS Array 1 buffers
+ fapi2::variable_buffer idles_16(16);
+ fapi2::variable_buffer repeat_16(16);
+ fapi2::variable_buffer pattern_20(20);
+ fapi2::variable_buffer read_compare_1(1);
+ fapi2::variable_buffer rank_cal_4(4);
+ fapi2::variable_buffer cal_enable_1(1);
+ fapi2::variable_buffer ccs_end_1(1);
+ fapi2::buffer<uint8_t> l_data_8;
+ fapi2::buffer<uint16_t> l_data_16;
+ uint32_t l_port = i_addr.port;
+
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_IS_SIMULATION, fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>(), l_is_sim));
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CEN_EFF_DRAM_ADDRESS_MIRRORING, i_target_mba, l_address_mirror_map));
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CEN_EFF_STACK_TYPE, i_target_mba, l_stack_type_u8array));
+
+ // CCS Array 0 Setup
+
+ // Buffer conversions from inputs
+ FAPI_TRY(addr_16.insertFromRight(i_addr.row_addr, 0, 16));
+ FAPI_TRY(addr_16.extract(l_data_16));
+ l_data_16.reverse();
+ FAPI_TRY(addr_16.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();
+ FAPI_TRY(bank_3.insertFromRight((uint8_t)l_data_8, 0 , 3));
+ 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));
+
+ // 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));
+
+ FAPI_TRY(read_compare_1.clearBit(0));
+
+ // Final setup
+ odt_4.flush<0>();
+ cal_type_4.flush<0>();
+ FAPI_TRY(ddr4_activate_1.setBit(0));
+
+ if ((l_address_mirror_map[l_port][l_dimm] & (0x08 >> l_dimm_rank) ) && (l_is_sim == 0))
+ {
+ FAPI_TRY(mss_address_mirror_swizzle(i_target_mba, addr_16, bank_3));
+ }
+
+ FAPI_TRY(mss_ccs_inst_arry_0(i_target_mba,
+ io_instruction_number,
+ addr_16,
+ bank_3,
+ ddr4_activate_1,
+ rasn_1,
+ casn_1,
+ wen_1,
+ cke_4,
+ csn_8,
+ odt_4,
+ cal_type_4,
+ l_port));
// CCS Array 1 Setup
FAPI_TRY(idles_16.insertFromRight(i_delay, 0, 16));
@@ -2475,7 +2591,591 @@ fapi2::ReturnCode add_nop_to_ccs(const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_
rank_cal_4,
cal_enable_1,
ccs_end_1));
+ ++io_instruction_number;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+/// @brief Add an ACT command to the CCS program
+/// @param[in] i_target_mba mba target
+/// @param[in] i_addr address struct for command
+/// @param[in] i_delay delay associated with this instruction
+/// @param[in,out] io_instruction_number position in CCS program in which to insert command (will be incremented)
+/// @return FAPI2_RC_SUCCESS iff successful
+fapi2::ReturnCode add_activate_to_ccs(const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_target_mba,
+ const access_address i_addr,
+ const uint32_t i_delay,
+ uint32_t& io_instruction_number)
+{
+ uint8_t l_is_sim = 0;
+ uint8_t l_address_mirror_map[MAX_PORTS_PER_MBA][MAX_DIMM_PER_PORT] = {0}; //address_mirror_map[port][dimm]
+ uint8_t l_stack_type_u8array[MAX_PORTS_PER_MBA][MAX_DIMM_PER_PORT] = {0};
+ const uint8_t l_dimm = i_addr.mrank / MAX_RANKS_PER_DIMM;
+ const uint8_t l_dimm_rank = i_addr.mrank - MAX_RANKS_PER_DIMM * l_dimm;
+
+ // CCS Array 0 buffers
+ fapi2::variable_buffer addr_16(16);
+ fapi2::variable_buffer bank_3(3);
+ fapi2::variable_buffer ddr4_activate_1(1);
+ fapi2::variable_buffer rasn_1(1);
+ fapi2::variable_buffer casn_1(1);
+ fapi2::variable_buffer wen_1(1);
+ fapi2::variable_buffer cke_4(4);
+ fapi2::variable_buffer csn_8(8);
+ fapi2::variable_buffer odt_4(4);
+ fapi2::variable_buffer cal_type_4(4);
+
+ // CCS Array 1 buffers
+ fapi2::variable_buffer idles_16(16);
+ fapi2::variable_buffer repeat_16(16);
+ fapi2::variable_buffer pattern_20(20);
+ fapi2::variable_buffer read_compare_1(1);
+ fapi2::variable_buffer rank_cal_4(4);
+ fapi2::variable_buffer cal_enable_1(1);
+ fapi2::variable_buffer ccs_end_1(1);
+
+ uint8_t l_dram_type;
+ uint32_t l_port = i_addr.port;
+ fapi2::buffer<uint8_t> l_data_8;
+ fapi2::buffer<uint16_t> l_data_16;
+
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_IS_SIMULATION, fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>(), l_is_sim));
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CEN_EFF_DRAM_ADDRESS_MIRRORING, i_target_mba, l_address_mirror_map));
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CEN_EFF_DRAM_GEN, i_target_mba, l_dram_type));
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CEN_EFF_STACK_TYPE, i_target_mba, l_stack_type_u8array));
+
+ // CCS Array 0 Setup
+
+ // Buffer conversions from inputs
+ FAPI_TRY(bank_3.insertFromRight(i_addr.bank, 0, 3));
+ FAPI_TRY(bank_3.extract(l_data_8, 0, 3));
+ l_data_8.reverse();
+ FAPI_TRY(bank_3.insertFromRight((uint8_t)l_data_8, 0 , 3));
+ csn_8.flush<1>();
+ cke_4.flush<1>();
+
+ FAPI_TRY(cs_decode(i_target_mba, i_addr, l_stack_type_u8array[0][0], csn_8));
+
+ // Command structure setup
+ // executes DDR4 commands if neccessary, otherwise executes DDR3 commands
+ if(l_dram_type == fapi2::ENUM_ATTR_EFF_DRAM_GEN_DDR4)
+ {
+ FAPI_TRY(ddr4_activate_1.clearBit(0));
+
+ FAPI_TRY(wen_1.insert(i_addr.row_addr, 0 , 1 , 17));
+ FAPI_TRY(casn_1.insert(i_addr.row_addr, 0 , 1 , 16));
+ FAPI_TRY(rasn_1.insert(i_addr.row_addr, 0 , 1 , 15));
+
+ FAPI_TRY(addr_16.insertFromRight(i_addr.row_addr, 0, 16));
+ 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.insert(i_addr.row_addr, 14 , 1 , 14));
+ FAPI_TRY(addr_16.insert(i_addr.bank, 15 , 1 , 4));
+ }
+ else
+ {
+ FAPI_TRY(rasn_1.clearBit(0));
+ FAPI_TRY(casn_1.setBit(0));
+ FAPI_TRY(ddr4_activate_1.setBit(0));
+ FAPI_TRY(addr_16.insertFromRight(i_addr.row_addr, 0, 16));
+ FAPI_TRY(addr_16.extract(l_data_16));
+ l_data_16.reverse();
+ FAPI_TRY(addr_16.insert((uint16_t)l_data_16));
+ }
+
+ // Final setup
+ odt_4.flush<0>();
+ cal_type_4.flush<0>();
+
+ if ((l_address_mirror_map[l_port][l_dimm] & (0x08 >> l_dimm_rank) ) && (l_is_sim == 0))
+ {
+ FAPI_TRY(mss_address_mirror_swizzle(i_target_mba, addr_16, bank_3));
+ }
+
+ FAPI_TRY(mss_ccs_inst_arry_0(i_target_mba,
+ io_instruction_number,
+ addr_16,
+ bank_3,
+ ddr4_activate_1,
+ rasn_1,
+ casn_1,
+ wen_1,
+ cke_4,
+ csn_8,
+ odt_4,
+ cal_type_4,
+ l_port));
+ // CCS Array 1 Setup
+ FAPI_TRY(idles_16.insertFromRight(i_delay, 0, 16));
+ repeat_16.flush<0>();
+ pattern_20.flush<0>();
+ read_compare_1.flush<0>();
+ rank_cal_4.flush<0>();
+ cal_enable_1.flush<0>();
+ ccs_end_1.flush<0>();
+
+ FAPI_TRY(mss_ccs_inst_arry_1(i_target_mba,
+ io_instruction_number,
+ idles_16,
+ repeat_16,
+ pattern_20,
+ read_compare_1,
+ rank_cal_4,
+ cal_enable_1,
+ ccs_end_1));
+ ++io_instruction_number;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+/// @brief Add a WR command to the CCS program
+/// @param[in] i_target_mba mba target
+/// @param[in] i_addr address struct for command
+/// @param[in] i_delay delay associated with this instruction
+/// @param[in,out] io_instruction_number position in CCS program in which to insert command (will be incremented)
+/// @return FAPI2_RC_SUCCESS iff successful
+fapi2::ReturnCode add_write_to_ccs(const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_target_mba,
+ const access_address i_addr,
+ const uint32_t i_delay,
+ uint32_t& io_instruction_number)
+{
+ uint8_t l_is_sim = 0;
+ uint8_t l_address_mirror_map[MAX_PORTS_PER_MBA][MAX_DIMM_PER_PORT] = {0}; //address_mirror_map[port][dimm]
+ uint8_t l_stack_type_u8array[MAX_PORTS_PER_MBA][MAX_DIMM_PER_PORT] = {0};
+ const uint8_t l_dimm = i_addr.mrank / MAX_RANKS_PER_DIMM;
+ const uint8_t l_dimm_rank = i_addr.mrank - MAX_RANKS_PER_DIMM * l_dimm;
+
+ // CCS Array 0 buffers
+ fapi2::variable_buffer addr_16(16);
+ fapi2::variable_buffer bank_3(3);
+ fapi2::variable_buffer ddr4_activate_1(1);
+ fapi2::variable_buffer rasn_1(1);
+ fapi2::variable_buffer casn_1(1);
+ fapi2::variable_buffer wen_1(1);
+ fapi2::variable_buffer cke_4(4);
+ fapi2::variable_buffer csn_8(8);
+ fapi2::variable_buffer odt_4(4);
+ fapi2::variable_buffer cal_type_4(4);
+
+ // CCS Array 1 buffers
+ fapi2::variable_buffer idles_16(16);
+ fapi2::variable_buffer repeat_16(16);
+ fapi2::variable_buffer pattern_20(20);
+ fapi2::variable_buffer read_compare_1(1);
+ fapi2::variable_buffer rank_cal_4(4);
+ fapi2::variable_buffer cal_enable_1(1);
+ fapi2::variable_buffer ccs_end_1(1);
+
+ uint8_t l_dram_type;
+ uint8_t l_odt[MAX_PORTS_PER_MBA][MAX_DIMM_PER_PORT][MAX_RANKS_PER_DIMM];
+ uint32_t l_port = i_addr.port;
+ fapi2::buffer<uint8_t> l_data_8;
+ fapi2::buffer<uint16_t> l_data_16;
+
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_IS_SIMULATION, fapi2::Target<fapi2::TARGET_TYPE_SYSTEM>(), l_is_sim));
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CEN_EFF_DRAM_ADDRESS_MIRRORING, i_target_mba, l_address_mirror_map));
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CEN_EFF_DRAM_GEN, i_target_mba, l_dram_type));
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CEN_VPD_ODT_WR, i_target_mba, l_odt));
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CEN_EFF_STACK_TYPE, i_target_mba, l_stack_type_u8array));
+
+ // Buffer conversions from inputs
+ FAPI_TRY(bank_3.insertFromRight(i_addr.bank, 0, 3));
+ FAPI_TRY(bank_3.extract(l_data_8, 0, 3));
+ l_data_8.reverse();
+ FAPI_TRY(bank_3.insertFromRight((uint8_t)l_data_8, 0 , 3));
+
+ FAPI_TRY(cs_decode(i_target_mba, i_addr, l_stack_type_u8array[0][0], csn_8));
+
+ // Command structure setup
+ cke_4.flush<1>();
+ FAPI_TRY(rasn_1.setBit(0));
+ FAPI_TRY(casn_1.clearBit(0));
+ FAPI_TRY(wen_1.clearBit(0));
+
+ // Final setup
+ FAPI_TRY(odt_4.insert(l_odt[l_port][l_dimm][l_dimm_rank], 0, 4));
+ cal_type_4.flush<0>();
+ FAPI_TRY(ddr4_activate_1.setBit(0));
+
+ if(l_dram_type == fapi2::ENUM_ATTR_EFF_DRAM_GEN_DDR4)
+ {
+ FAPI_TRY(addr_16.insertFromRight(i_addr.col_addr, 0, 16));
+ 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.setBit(12)); // burst length 8
+
+ FAPI_TRY(addr_16.insert(i_addr.bank, 15 , 1 , 4));
+
+ }
+ else
+ {
+ FAPI_TRY(addr_16.insertFromRight(i_addr.col_addr, 0, 16));
+ 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.setBit(12)); // burst length 8
+ }
+
+ if ((l_address_mirror_map[l_port][l_dimm] & (0x08 >> l_dimm_rank) ) && (l_is_sim == 0))
+ {
+ FAPI_TRY(mss_address_mirror_swizzle(i_target_mba, addr_16, bank_3));
+ }
+
+ FAPI_TRY(mss_ccs_inst_arry_0(i_target_mba,
+ io_instruction_number,
+ addr_16,
+ bank_3,
+ ddr4_activate_1,
+ rasn_1,
+ casn_1,
+ wen_1,
+ cke_4,
+ csn_8,
+ odt_4,
+ cal_type_4,
+ l_port));
+
+ // CCS Array 1 Setup
+ FAPI_TRY(idles_16.insertFromRight(i_delay, 0, 16));
+ repeat_16.flush<0>();
+ pattern_20.flush<0>();
+ read_compare_1.flush<0>();
+ rank_cal_4.flush<0>();
+ cal_enable_1.flush<0>();
+ ccs_end_1.flush<0>();
+
+ FAPI_TRY(mss_ccs_inst_arry_1(i_target_mba,
+ io_instruction_number,
+ idles_16,
+ repeat_16,
+ pattern_20,
+ read_compare_1,
+ rank_cal_4,
+ cal_enable_1,
+ ccs_end_1));
+ ++io_instruction_number;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+/// @brief Add an ODT command to the CCS program
+/// @param[in] i_target_mba mba target
+/// @param[in] i_addr address struct for command
+/// @param[in] i_repeat number of repeats to specify in this instruction
+/// @param[in] i_delay delay associated with this instruction
+/// @param[in,out] io_instruction_number position in CCS program in which to insert command (will be incremented)
+/// @return FAPI2_RC_SUCCESS iff successful
+fapi2::ReturnCode add_odt_to_ccs(const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_target_mba,
+ const access_address i_addr,
+ const uint32_t i_repeat,
+ const uint32_t i_delay,
+ uint32_t& io_instruction_number)
+{
+ const uint8_t l_dimm = i_addr.mrank / MAX_RANKS_PER_DIMM;
+ const uint8_t l_dimm_rank = i_addr.mrank % MAX_RANKS_PER_DIMM;
+
+ // CCS Array 0 buffers
+ fapi2::variable_buffer addr_16(16);
+ fapi2::variable_buffer bank_3(3);
+ fapi2::variable_buffer ddr4_activate_1(1);
+ fapi2::variable_buffer rasn_1(1);
+ fapi2::variable_buffer casn_1(1);
+ fapi2::variable_buffer wen_1(1);
+ fapi2::variable_buffer cke_4(4);
+ fapi2::variable_buffer csn_8(8);
+ fapi2::variable_buffer odt_4(4);
+ fapi2::variable_buffer cal_type_4(4);
+
+ // CCS Array 1 buffers
+ fapi2::variable_buffer idles_16(16);
+ fapi2::variable_buffer repeat_16(16);
+ fapi2::variable_buffer pattern_20(20);
+ fapi2::variable_buffer read_compare_1(1);
+ fapi2::variable_buffer rank_cal_4(4);
+ fapi2::variable_buffer cal_enable_1(1);
+ fapi2::variable_buffer ccs_end_1(1);
+
+ uint8_t l_dram_type;
+ uint8_t l_odt[MAX_PORTS_PER_MBA][MAX_DIMM_PER_PORT][MAX_RANKS_PER_DIMM];
+ const uint32_t odt_cyc = 5;
+ uint32_t l_port = i_addr.port;
+ fapi2::buffer<uint8_t> l_data_8;
+ fapi2::buffer<uint16_t> l_data_16;
+
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CEN_EFF_DRAM_GEN, i_target_mba, l_dram_type));
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CEN_VPD_ODT_WR, i_target_mba, l_odt));
+
+ // Buffer conversions from inputs
+ addr_16.flush<0>();
+ bank_3.flush<0>();
+ csn_8.flush<1>();
+ FAPI_TRY(csn_8.clearBit(6));
+ FAPI_TRY(csn_8.clearBit(7)); // need to have a unused cs_n for the valid data to write out on the bus.
+
+ // Command structure setup
+ cke_4.flush<1>();
+ FAPI_TRY(rasn_1.setBit(0));
+ FAPI_TRY(casn_1.setBit(0));
+ FAPI_TRY(wen_1.setBit(0));
+
+ // Final setup
+ FAPI_TRY(odt_4.insert(l_odt[l_port][l_dimm][l_dimm_rank], 0, 4));
+ cal_type_4.flush<0>();
+ FAPI_TRY(ddr4_activate_1.setBit(0));
+
+ if(l_dram_type == fapi2::ENUM_ATTR_EFF_DRAM_GEN_DDR4)
+ {
+ FAPI_TRY(addr_16.setBit(12)); // burst length 8
+ }
+
+ FAPI_TRY(mss_ccs_inst_arry_0(i_target_mba,
+ io_instruction_number,
+ addr_16,
+ bank_3,
+ ddr4_activate_1,
+ rasn_1,
+ casn_1,
+ wen_1,
+ cke_4,
+ csn_8,
+ odt_4,
+ cal_type_4,
+ l_port));
+
+ // CCS Array 1 Setup
+ FAPI_TRY(idles_16.insertFromRight(i_delay, 0, 16));
+ repeat_16.flush<0>();
+ FAPI_TRY(repeat_16.insertFromRight((i_repeat + odt_cyc), 0, 16));
+ pattern_20.flush<0>();
+ read_compare_1.flush<0>();
+ rank_cal_4.flush<0>();
+ cal_enable_1.flush<0>();
+ ccs_end_1.flush<0>();
+
+ FAPI_TRY(mss_ccs_inst_arry_1(i_target_mba,
+ io_instruction_number,
+ idles_16,
+ repeat_16,
+ pattern_20,
+ read_compare_1,
+ rank_cal_4,
+ cal_enable_1,
+ ccs_end_1));
+ ++io_instruction_number;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+/// @brief Add a precharge all command to the CCS program
+/// @param[in] i_target_mba mba target
+/// @param[in] i_addr address struct for command
+/// @param[in] i_delay delay associated with this instruction
+/// @param[in] i_odt_wr value of ATTR_CEN_VPD_ODT_WR
+/// @param[in] i_stack_type value of ATTR_CEN_EFF_STACK_TYPE
+/// @param[in,out] io_instruction_number position in CCS program in which to insert command (will be incremented)
+/// @return FAPI2_RC_SUCCESS iff successful
+fapi2::ReturnCode add_precharge_all_to_ccs(const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_target_mba,
+ const access_address i_addr,
+ const uint32_t i_delay,
+ const uint8_t (&i_odt_wr)[MAX_PORTS_PER_MBA][MAX_DIMM_PER_PORT][MAX_RANKS_PER_DIMM],
+ const uint8_t (&i_stack_type)[MAX_PORTS_PER_MBA][MAX_DIMM_PER_PORT],
+ uint32_t& io_instruction_number)
+{
+ const uint8_t l_dimm = i_addr.mrank / MAX_RANKS_PER_DIMM;
+ const uint8_t l_dimm_rank = i_addr.mrank % MAX_RANKS_PER_DIMM;
+
+ // CCS Array 0 buffers
+ fapi2::variable_buffer addr_16(16);
+ fapi2::variable_buffer bank_3(3);
+ fapi2::variable_buffer ddr4_activate_1(1);
+ fapi2::variable_buffer rasn_1(1);
+ fapi2::variable_buffer casn_1(1);
+ fapi2::variable_buffer wen_1(1);
+ fapi2::variable_buffer cke_4(4);
+ fapi2::variable_buffer csn_8(8);
+ fapi2::variable_buffer odt_4(4);
+ fapi2::variable_buffer cal_type_4(4);
+
+ // CCS Array 1 buffers
+ fapi2::variable_buffer idles_16(16);
+ fapi2::variable_buffer repeat_16(16);
+ fapi2::variable_buffer pattern_20(20);
+ fapi2::variable_buffer read_compare_1(1);
+ fapi2::variable_buffer rank_cal_4(4);
+ fapi2::variable_buffer cal_enable_1(1);
+ fapi2::variable_buffer ccs_end_1(1);
+
+ uint32_t l_port = i_addr.port;
+ fapi2::buffer<uint8_t> l_data_8;
+ fapi2::buffer<uint16_t> l_data_16;
+
+ // Buffer conversions from inputs
+ FAPI_TRY(addr_16.insertFromRight(i_addr.col_addr, 0, 16));
+ FAPI_TRY(addr_16.extract(l_data_16));
+ l_data_16.reverse();
+ FAPI_TRY(addr_16.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();
+ FAPI_TRY(bank_3.insertFromRight((uint8_t)l_data_8, 0 , 3));
+
+ FAPI_TRY(cs_decode(i_target_mba, i_addr, i_stack_type[0][0], csn_8));
+
+ // Command structure setup
+ cke_4.flush<1>();
+ FAPI_TRY(rasn_1.clearBit(0));
+ FAPI_TRY(casn_1.setBit(0));
+ FAPI_TRY(wen_1.clearBit(0));
+ FAPI_TRY(addr_16.setBit(10));
+
+ // Final setup
+ FAPI_TRY(odt_4.insert(i_odt_wr[l_port][l_dimm][l_dimm_rank], 0, 4));
+ cal_type_4.flush<0>();
+ FAPI_TRY(ddr4_activate_1.setBit(0));
+
+ FAPI_TRY(mss_ccs_inst_arry_0(i_target_mba,
+ io_instruction_number,
+ addr_16,
+ bank_3,
+ ddr4_activate_1,
+ rasn_1,
+ casn_1,
+ wen_1,
+ cke_4,
+ csn_8,
+ odt_4,
+ cal_type_4,
+ l_port));
+
+ // CCS Array 1 Setup
+ FAPI_TRY(idles_16.insertFromRight(i_delay, 0, 16));
+ repeat_16.flush<0>();
+ pattern_20.flush<0>();
+ read_compare_1.flush<0>();
+ rank_cal_4.flush<0>();
+ cal_enable_1.flush<0>();
+ ccs_end_1.flush<0>();
+
+ FAPI_TRY(mss_ccs_inst_arry_1(i_target_mba,
+ io_instruction_number,
+ idles_16,
+ repeat_16,
+ pattern_20,
+ read_compare_1,
+ rank_cal_4,
+ cal_enable_1,
+ ccs_end_1));
+ ++io_instruction_number;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+/// @brief Add a DES command to the CCS program
+/// @param[in] i_target_mba mba target
+/// @param[in] i_addr address struct for command
+/// @param[in] i_repeat number of repeats to specify in this instruction
+/// @param[in] i_delay delay associated with this instruction
+/// @param[in,out] io_instruction_number position in CCS program in which to insert command (will be incremented)
+/// @return FAPI2_RC_SUCCESS iff successful
+fapi2::ReturnCode add_des_with_repeat_to_ccs(const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_target_mba,
+ const access_address i_addr,
+ const uint32_t i_repeat,
+ const uint32_t i_delay,
+ uint32_t& io_instruction_number)
+{
+ // CCS Array 0 buffers
+ fapi2::variable_buffer addr_16(16);
+ fapi2::variable_buffer bank_3(3);
+ fapi2::variable_buffer ddr4_activate_1(1);
+ fapi2::variable_buffer rasn_1(1);
+ fapi2::variable_buffer casn_1(1);
+ fapi2::variable_buffer wen_1(1);
+ fapi2::variable_buffer cke_4(4);
+ fapi2::variable_buffer csn_8(8);
+ fapi2::variable_buffer odt_4(4);
+ fapi2::variable_buffer cal_type_4(4);
+
+ // CCS Array 1 buffers
+ fapi2::variable_buffer idles_16(16);
+ fapi2::variable_buffer repeat_16(16);
+ fapi2::variable_buffer pattern_20(20);
+ fapi2::variable_buffer read_compare_1(1);
+ fapi2::variable_buffer rank_cal_4(4);
+ fapi2::variable_buffer cal_enable_1(1);
+ fapi2::variable_buffer ccs_end_1(1);
+ fapi2::buffer<uint8_t> l_data_8;
+ fapi2::buffer<uint16_t> l_data_16;
+ uint32_t l_port = i_addr.port;
+
+ // CCS Array 0 Setup
+
+ // Buffer conversions from inputs
+ FAPI_TRY(addr_16.insertFromRight(i_addr.row_addr, 0, 16));
+ FAPI_TRY(addr_16.extract(l_data_16));
+ l_data_16.reverse();
+ FAPI_TRY(addr_16.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();
+ FAPI_TRY(bank_3.insertFromRight((uint8_t)l_data_8, 0 , 3));
+ csn_8.flush<1>();
+
+ // Command structure setup
+ cke_4.flush<1>();
+ FAPI_TRY(rasn_1.setBit(0));
+ FAPI_TRY(casn_1.setBit(0));
+ FAPI_TRY(wen_1.setBit(0));
+
+ FAPI_TRY(read_compare_1.clearBit(0));
+
+ // Final setup
+ odt_4.flush<0>();
+ cal_type_4.flush<0>();
+ FAPI_TRY(ddr4_activate_1.setBit(0));
+
+ FAPI_TRY(mss_ccs_inst_arry_0(i_target_mba,
+ io_instruction_number,
+ addr_16,
+ bank_3,
+ ddr4_activate_1,
+ rasn_1,
+ casn_1,
+ wen_1,
+ cke_4,
+ csn_8,
+ odt_4,
+ cal_type_4,
+ l_port));
+
+ // CCS Array 1 Setup
+ idles_16.flush<0>();
+ FAPI_TRY(idles_16.insertFromRight(i_delay, 0, 16));
+ repeat_16.flush<0>();
+ FAPI_TRY(repeat_16.insertFromRight(i_repeat, 0, 16));
+ pattern_20.flush<0>();
+ read_compare_1.flush<0>();
+ rank_cal_4.flush<0>();
+ cal_enable_1.flush<0>();
+ ccs_end_1.flush<0>();
+
+ FAPI_TRY(mss_ccs_inst_arry_1(i_target_mba,
+ io_instruction_number,
+ idles_16,
+ repeat_16,
+ pattern_20,
+ read_compare_1,
+ rank_cal_4,
+ cal_enable_1,
+ ccs_end_1));
++io_instruction_number;
fapi_try_exit:
@@ -2501,8 +3201,8 @@ fapi2::ReturnCode cs_decode(const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_targe
if(i_stack_type == fapi2::ENUM_ATTR_CEN_EFF_STACK_TYPE_STACK_3DS)
{
- FAPI_TRY(mrank.insert(i_addr.rank, 4, 4 , 0));
- FAPI_TRY(cid.insert(i_addr.rank, 4, 4, 4));
+ FAPI_TRY(mrank.insert(i_addr.mrank, 4, 4, 4));
+ FAPI_TRY(cid.insert(i_addr.srank, 4, 4, 4));
uint8_t mrank_u8 = 0;
mrank.extract(mrank_u8, 0, 8);
@@ -2513,6 +3213,7 @@ fapi2::ReturnCode cs_decode(const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_targe
fapi2::CEN_MSS_CCS_MRANK_OUT_OF_BOUNDS()
.set_INDEX_VALUE(mrank_u8),
"mrank value: 0x%02X not supported\n", mrank_u8);
+
FAPI_ASSERT(cid_u8 < 8,
fapi2::CEN_MSS_CCS_SRANK_OUT_OF_BOUNDS()
.set_INDEX_VALUE(cid_u8),
@@ -2531,14 +3232,14 @@ fapi2::ReturnCode cs_decode(const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_targe
FAPI_TRY(o_csn_8.insert(cid_u8, 3, 1, 6));
}
- FAPI_DBG("%s Row: 0x%04x, Col: 0x%04x, Mrank: %d, Srank: %d, Bank: %d, Port: %d\n",
+ FAPI_DBG("%s Row: %x, Col: %x, Mrank: %d, Srank: %d, Bank: %d, Port: %d\n",
mss::c_str(i_target_mba), i_addr.row_addr, i_addr.col_addr, mrank_u8, cid_u8, i_addr.bank, i_addr.port);
}
else
{
- FAPI_TRY(o_csn_8.clearBit(i_addr.rank));
- FAPI_DBG("%s Row: 0x%04x, Col: 0x%04x, Rank: %d, Bank: %d, Port: %d\n",
- mss::c_str(i_target_mba), i_addr.row_addr, i_addr.col_addr, i_addr.rank, i_addr.bank, i_addr.port);
+ FAPI_TRY(o_csn_8.clearBit(i_addr.mrank));
+ FAPI_DBG("%s Row: %x, Col: %x, Rank: %d, Bank: %d, Port: %d\n",
+ mss::c_str(i_target_mba), i_addr.row_addr, i_addr.col_addr, i_addr.mrank, i_addr.bank, i_addr.port);
}
fapi_try_exit:
diff --git a/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_funcs.H b/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_funcs.H
index a1fa20c31..454cdb8fc 100755
--- a/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_funcs.H
+++ b/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_funcs.H
@@ -42,7 +42,8 @@ struct access_address
{
uint32_t row_addr;
uint32_t col_addr;
- uint8_t rank;
+ uint8_t mrank;
+ uint8_t srank;
uint8_t bank;
uint8_t port;
};
@@ -360,6 +361,80 @@ fapi2::ReturnCode add_nop_to_ccs(const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_
const uint32_t i_delay,
uint32_t& io_instruction_number);
+/// @brief Add an MRS command to the CCS program
+/// @param[in] i_target_mba mba target
+/// @param[in] i_addr address struct for MRS
+/// @param[in] i_delay delay associated with this instruction
+/// @param[in,out] io_instruction_number position in CCS program in which to insert command (will be incremented)
+/// @return FAPI2_RC_SUCCESS iff successful
+fapi2::ReturnCode add_mrs_to_ccs(const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_target_mba,
+ const access_address i_addr,
+ const uint32_t i_delay,
+ uint32_t& io_instruction_number);
+
+/// @brief Add an ACT command to the CCS program
+/// @param[in] i_target_mba mba target
+/// @param[in] i_addr address struct for command
+/// @param[in] i_delay delay associated with this instruction
+/// @param[in,out] io_instruction_number position in CCS program in which to insert command (will be incremented)
+/// @return FAPI2_RC_SUCCESS iff successful
+fapi2::ReturnCode add_activate_to_ccs(const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_target_mba,
+ const access_address i_addr,
+ const uint32_t i_delay,
+ uint32_t& io_instruction_number);
+
+/// @brief Add a WR command to the CCS program
+/// @param[in] i_target_mba mba target
+/// @param[in] i_addr address struct for command
+/// @param[in] i_delay delay associated with this instruction
+/// @param[in,out] io_instruction_number position in CCS program in which to insert command (will be incremented)
+/// @return FAPI2_RC_SUCCESS iff successful
+fapi2::ReturnCode add_write_to_ccs(const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_target_mba,
+ const access_address i_addr,
+ const uint32_t i_delay,
+ uint32_t& io_instruction_number);
+
+/// @brief Add an ODT command to the CCS program
+/// @param[in] i_target_mba mba target
+/// @param[in] i_addr address struct for command
+/// @param[in] i_repeat number of repeats to specify in this instruction
+/// @param[in] i_delay delay associated with this instruction
+/// @param[in,out] io_instruction_number position in CCS program in which to insert command (will be incremented)
+/// @return FAPI2_RC_SUCCESS iff successful
+fapi2::ReturnCode add_odt_to_ccs(const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_target_mba,
+ const access_address i_addr,
+ const uint32_t i_repeat,
+ const uint32_t i_delay,
+ uint32_t& io_instruction_number);
+
+/// @brief Add a precharge all command to the CCS program
+/// @param[in] i_target_mba mba target
+/// @param[in] i_addr address struct for command
+/// @param[in] i_delay delay associated with this instruction
+/// @param[in] i_odt_wr value of ATTR_CEN_VPD_ODT_WR
+/// @param[in] i_stack_type value of ATTR_CEN_EFF_STACK_TYPE
+/// @param[in,out] io_instruction_number position in CCS program in which to insert command (will be incremented)
+/// @return FAPI2_RC_SUCCESS iff successful
+fapi2::ReturnCode add_precharge_all_to_ccs(const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_target_mba,
+ const access_address i_addr,
+ const uint32_t i_delay,
+ const uint8_t (&i_odt_wr)[MAX_PORTS_PER_MBA][MAX_DIMM_PER_PORT][MAX_RANKS_PER_DIMM],
+ const uint8_t (&i_stack_type)[MAX_PORTS_PER_MBA][MAX_DIMM_PER_PORT],
+ uint32_t& io_instruction_number);
+
+/// @brief Add a DES command to the CCS program
+/// @param[in] i_target_mba mba target
+/// @param[in] i_addr address struct for command
+/// @param[in] i_repeat number of repeats to specify in this instruction
+/// @param[in] i_delay delay associated with this instruction
+/// @param[in,out] io_instruction_number position in CCS program in which to insert command (will be incremented)
+/// @return FAPI2_RC_SUCCESS iff successful
+fapi2::ReturnCode add_des_with_repeat_to_ccs(const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_target_mba,
+ const access_address i_addr,
+ const uint32_t i_repeat,
+ const uint32_t i_delay,
+ uint32_t& io_instruction_number);
+
/// @brief Get the CSN representation of a given address
/// @param[in] i_target_mba mba target
/// @param[in] i_addr address struct for MRS
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 a53075350..ed4841acb 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
@@ -22,3 +22,218 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+#include <p9c_mss_row_repair.H>
+#include <cen_gen_scom_addresses.H>
+#include <cen_gen_scom_addresses_fld.H>
+#include <generic/memory/lib/utils/c_str.H>
+#include <p9c_mss_funcs.H>
+#include <p9c_mss_ddr4_funcs.H>
+
+using namespace fapi2;
+
+extern "C"
+{
+ /// @brief Perform a PPR row repair operation
+ /// @param[in] i_target_mba mba target
+ /// @param[in] i_port port for repair
+ /// @param[in] i_mrank master rank of address to repair
+ /// @param[in] i_srank slave rank of address to repair
+ /// @param[in] i_bank bank bits of address to repair
+ /// @param[in] i_row row bits of address to repair
+ /// @param[in] i_dram_bitmap bitmap of DRAMs selected for repair (b'1 to repair, b'0 to not repair)
+ /// @return FAPI2_RC_SUCCESS iff successful
+ fapi2::ReturnCode p9c_mss_row_repair(const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_target_mba,
+ const uint8_t i_port,
+ const uint8_t i_mrank,
+ const uint8_t i_srank,
+ const uint8_t i_bank,
+ const uint32_t i_row,
+ const uint32_t i_dram_bitmap)
+ {
+ 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 uint8_t TMOD = 24;
+
+ // This is the value to shift the input DRAM position to the last 20 bits of l_write_pattern
+ constexpr uint8_t DRAM_START_BIT = 44;
+ constexpr uint8_t DRAM_LEN = 64 - DRAM_START_BIT;
+
+ const std::vector<uint64_t> MR0_SHADOW_REGS =
+ {
+ CEN_MBA_DDRPHY_PC_MR0_PRI_RP0_P0,
+ CEN_MBA_DDRPHY_PC_MR0_PRI_RP1_P0,
+ CEN_MBA_DDRPHY_PC_MR0_PRI_RP2_P0,
+ CEN_MBA_DDRPHY_PC_MR0_PRI_RP3_P0,
+ CEN_MBA_DDRPHY_PC_MR0_PRI_RP0_P1,
+ CEN_MBA_DDRPHY_PC_MR0_PRI_RP1_P1,
+ CEN_MBA_DDRPHY_PC_MR0_PRI_RP2_P1,
+ CEN_MBA_DDRPHY_PC_MR0_PRI_RP3_P1,
+ };
+
+ // 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 =
+ {
+ // 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},
+ {0x03FF, 0, i_mrank, i_srank, MRS0_BA, i_port},
+ };
+
+ access_address l_addr = {i_row, 0, i_mrank, i_srank, i_bank, i_port};
+ 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;
+ uint64_t l_write_pattern = 0;
+ uint32_t l_instruction_number = 0;
+ uint8_t l_refresh = 0;
+ uint8_t l_dram_gen = 0;
+ uint8_t l_dram_width = 0;
+ uint8_t l_stack_type_u8array[MAX_PORTS_PER_MBA][MAX_DIMM_PER_PORT] = {0};
+ uint8_t l_odt[MAX_PORTS_PER_MBA][MAX_DIMM_PER_PORT][MAX_RANKS_PER_DIMM] = {0};
+
+ uint8_t l_al = 0;
+ uint8_t l_trcd = 0;
+ uint8_t l_twr = 0;
+ uint8_t l_cwl = 0;
+ uint32_t l_trfc = 0;
+ uint8_t l_pl = 0;
+
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CEN_EFF_DRAM_GEN, i_target_mba, l_dram_gen));
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CEN_VPD_ODT_WR, i_target_mba, l_odt));
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CEN_EFF_STACK_TYPE, i_target_mba, l_stack_type_u8array));
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CEN_EFF_DRAM_TRCD, i_target_mba, l_trcd));
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CEN_EFF_DRAM_WR, i_target_mba, l_twr));
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CEN_EFF_DRAM_AL, i_target_mba, l_al));
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CEN_EFF_DRAM_CWL, i_target_mba, l_cwl));
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CEN_EFF_DRAM_TRFC, i_target_mba, l_trfc));
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CEN_EFF_CA_PARITY_LATENCY, i_target_mba, l_pl));
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CEN_EFF_DRAM_WIDTH, i_target_mba, l_dram_width));
+
+ // DDR3 doesn't support sPPR, so bail unless we're DDR4
+ FAPI_ASSERT(l_dram_gen == fapi2::ENUM_ATTR_CEN_EFF_DRAM_GEN_DDR4,
+ fapi2::CEN_MSS_ROW_REPAIR_NOT_SUPPORTED().
+ set_TARGET_MBA(i_target_mba).
+ set_PORT(i_port).
+ set_MRANK(i_mrank).
+ set_DRAM_GEN(l_dram_gen),
+ "%s Row repair is not supported on DDR3 parts. Port%d mrank%d is %s",
+ mss::c_str(i_target_mba), i_port, i_mrank, (l_dram_gen == 1 ? "DDR3" : "Unknown DRAM gen"));
+
+ // Compute the CCS write pattern to select the desired DRAM(s)
+ l_dram_scratch = i_dram_bitmap;
+ l_dram_scratch.invert();
+ l_dram_scratch.extractToRight<DRAM_START_BIT, DRAM_LEN>(l_write_pattern);
+
+ // Save MR0 data before we write guard key sequence
+ FAPI_TRY(fapi2::getScom(i_target_mba, MR0_SHADOW_REGS[0], l_saved_mr0));
+
+ // Turn off refresh
+ FAPI_TRY(fapi2::getScom(i_target_mba, CEN_MBA_MBAREF0Q, l_reg_buffer));
+ l_refresh = l_reg_buffer.getBit<REFRESH_BIT>();
+ l_reg_buffer.clearBit<REFRESH_BIT>();
+ FAPI_TRY(fapi2::putScom(i_target_mba, CEN_MBA_MBAREF0Q, l_reg_buffer));
+
+ // Precharge all ranks before we set sPPR mode
+ 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(add_mrs_to_ccs_ddr4(i_target_mba, l_mrs_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(52)); //RAS high
+ FAPI_TRY(l_reg_buffer.setBit(53)); //CAS high
+ FAPI_TRY(l_reg_buffer.setBit(54)); //WE high
+ 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
+ --l_instruction_number;
+ FAPI_TRY(mss_ccs_set_end_bit(i_target_mba, l_instruction_number), "CCS_SET_END_BIT FAILED");
+
+ // Execute the CCS program
+ FAPI_DBG("%s Executing the CCS array", mss::c_str(i_target_mba));
+ FAPI_TRY(mss_execute_ccs_inst_array(i_target_mba, NUM_POLL, WAIT_TIMER), " EXECUTE_CCS_INST_ARRAY FAILED");
+ l_instruction_number = 0;
+
+ // Restore the MR0 shadow regs
+ for (const auto l_mr0_reg : MR0_SHADOW_REGS)
+ {
+ FAPI_TRY(fapi2::putScom(i_target_mba, l_mr0_reg, l_saved_mr0));
+ }
+
+ // Issue ACT command with bank and row fail address
+ FAPI_TRY(add_activate_to_ccs(i_target_mba, l_addr, l_trcd, l_instruction_number));
+
+ // Issue WR command with (tWR + WL + 10) cycles delay, values are the result of lab experimentation
+ FAPI_TRY(add_write_to_ccs(i_target_mba, l_addr, (l_twr + l_cwl + l_al + l_pl + 10), l_instruction_number));
+
+ // Write pattern (back up the instruction count so we hit the write instruction)
+ --l_instruction_number;
+ FAPI_TRY(mss_ccs_load_data_pattern(i_target_mba, l_instruction_number, l_write_pattern));
+ ++l_instruction_number;
+
+ // 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));
+
+ // Take the DRAM out of PPR mode (MR4 command)
+ l_addr.row_addr = DISABLE_PPR;
+ 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
+ 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(52)); //RAS high
+ FAPI_TRY(l_reg_buffer.setBit(53)); //CAS high
+ FAPI_TRY(l_reg_buffer.setBit(54)); //WE high
+ 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
+ --l_instruction_number;
+ FAPI_TRY(mss_ccs_set_end_bit(i_target_mba, l_instruction_number), "CCS_SET_END_BIT FAILED");
+
+ // Execute the CCS program
+ FAPI_DBG("%s Executing the CCS array", mss::c_str(i_target_mba));
+ FAPI_TRY(mss_execute_ccs_inst_array(i_target_mba, NUM_POLL, WAIT_TIMER), " EXECUTE_CCS_INST_ARRAY FAILED");
+ l_instruction_number = 0;
+
+ // Disable CCS
+ FAPI_DBG("%s Disabling 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.clearBit(29));
+ FAPI_TRY(fapi2::putScom(i_target_mba, CEN_MBA_CCS_MODEQ, l_reg_buffer));
+
+ // Turn on refresh
+ FAPI_TRY(fapi2::getScom(i_target_mba, CEN_MBA_MBAREF0Q, l_reg_buffer));
+ l_reg_buffer.writeBit<REFRESH_BIT>(l_refresh);
+ FAPI_TRY(fapi2::putScom(i_target_mba, CEN_MBA_MBAREF0Q, l_reg_buffer));
+
+ fapi_try_exit:
+ return fapi2::current_err;
+ }
+
+}
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 1d4af14b9..aa113d762 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
@@ -22,3 +22,39 @@
/* permissions and limitations under the License. */
/* */
/* IBM_PROLOG_END_TAG */
+#ifndef __P9C_MSS_ROW_REPAIR__
+#define __P9C_MSS_ROW_REPAIR__
+
+#include <fapi2.H>
+
+typedef fapi2::ReturnCode (*p9c_mss_row_repair_FP_t)(const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_target_mba,
+ const uint8_t i_port,
+ const uint8_t i_mrank,
+ const uint8_t i_srank,
+ const uint8_t i_bank,
+ const uint32_t i_row,
+ const uint32_t i_dram_bitmap);
+
+extern "C"
+{
+
+ /// @brief Perform a PPR row repair operation
+ /// @param[in] i_target_mba mba target
+ /// @param[in] i_port port for repair
+ /// @param[in] i_mrank master rank of address to repair
+ /// @param[in] i_srank slave rank of address to repair
+ /// @param[in] i_bank bank bits of address to repair
+ /// @param[in] i_row row bits of address to repair
+ /// @param[in] i_dram_bitmap bitmap of DRAMs selected for repair (b'1 to repair, b'0 to not repair)
+ /// @return FAPI2_RC_SUCCESS iff successful
+ fapi2::ReturnCode p9c_mss_row_repair(const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_target_mba,
+ const uint8_t i_port,
+ const uint8_t i_mrank,
+ const uint8_t i_srank,
+ const uint8_t i_bank,
+ const uint32_t i_row,
+ const uint32_t i_dram_bitmap);
+
+}
+
+#endif
diff --git a/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_row_repair.mk b/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_row_repair.mk
index ea540b5ce..b291f595b 100644
--- a/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_row_repair.mk
+++ b/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_row_repair.mk
@@ -22,3 +22,10 @@
# permissions and limitations under the License.
#
# IBM_PROLOG_END_TAG
+-include 00common.mk
+
+PROCEDURE=p9c_mss_row_repair
+$(eval $(call ADD_MEMORY_INCDIRS,$(PROCEDURE)))
+lib${PROCEDURE}_DEPLIBS+=p9c_mss_ddr4_funcs
+lib${PROCEDURE}_DEPLIBS+=p9c_mss_funcs
+$(call BUILD_PROCEDURE)
diff --git a/src/import/chips/centaur/procedures/xml/error_info/p9c_mss_funcs_errors.xml b/src/import/chips/centaur/procedures/xml/error_info/p9c_mss_funcs_errors.xml
index 61a54bfb5..df5d195ec 100644
--- a/src/import/chips/centaur/procedures/xml/error_info/p9c_mss_funcs_errors.xml
+++ b/src/import/chips/centaur/procedures/xml/error_info/p9c_mss_funcs_errors.xml
@@ -206,4 +206,17 @@
</callout>
</hwpError>
+ <hwpError>
+ <rc>RC_CEN_MSS_ROW_REPAIR_NOT_SUPPORTED</rc>
+ <description>An sPPR row repair operation was attempted on a DDR3 part, which doesn't support it.</description>
+ <ffdc>TARGET_MBA</ffdc>
+ <ffdc>PORT</ffdc>
+ <ffdc>MRANK</ffdc>
+ <ffdc>DRAM_GEN</ffdc>
+ <callout>
+ <procedure>CODE</procedure>
+ <priority>HIGH</priority>
+ </callout>
+ </hwpError>
+
</hwpErrors>
OpenPOWER on IntegriCloud