summaryrefslogtreecommitdiffstats
path: root/src/import/chips/centaur/procedures
diff options
context:
space:
mode:
authorStephen Glancy <sglancy@us.ibm.com>2018-07-11 09:08:11 -0500
committerChristian R. Geddes <crgeddes@us.ibm.com>2018-07-17 10:36:12 -0400
commit8df62cd15e91e7a497573555ba781e3bf5e62fa4 (patch)
treea875f3b584d85b29191f88b56450221725d6b506 /src/import/chips/centaur/procedures
parenta9e7978b58168834c398f7a52862267e5f64cb63 (diff)
downloadtalos-hostboot-8df62cd15e91e7a497573555ba781e3bf5e62fa4.tar.gz
talos-hostboot-8df62cd15e91e7a497573555ba781e3bf5e62fa4.zip
Fixes Centaur RCD load sequence
A supplier had a bug where CKE needed to be held low and RC09 needed to be issued last. A sequence of toggling reset on RC06 is also added in to ensure safety. Change-Id: I2fbd29918b39ee59e4b31f163635d25c9efd1a92 CQ:SW437641 RTC:195505 Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/62321 Dev-Ready: STEPHEN GLANCY <sglancy@us.ibm.com> Reviewed-by: Louis Stermole <stermole@us.ibm.com> Reviewed-by: ANDRE A. MARIN <aamarin@us.ibm.com> Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com> Tested-by: Hostboot CI <hostboot-ci+hostboot@us.ibm.com> Reviewed-by: Jennifer A. Stofer <stofer@us.ibm.com> Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/62349 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/procedures')
-rwxr-xr-xsrc/import/chips/centaur/procedures/hwp/memory/p9c_mss_ddr4_funcs.C399
-rwxr-xr-xsrc/import/chips/centaur/procedures/hwp/memory/p9c_mss_ddr4_funcs.H35
-rwxr-xr-xsrc/import/chips/centaur/procedures/hwp/memory/p9c_mss_draminit.C8
-rwxr-xr-xsrc/import/chips/centaur/procedures/hwp/memory/p9c_mss_funcs.C48
-rwxr-xr-xsrc/import/chips/centaur/procedures/hwp/memory/p9c_mss_funcs.H14
5 files changed, 388 insertions, 116 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 87c6ae1a4..1c6f9e1db 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
@@ -775,19 +775,221 @@ fapi_try_exit:
return fapi2::current_err;
}
+/// @brief Writes the 4-bit RCD control words for DDR4 register.
+/// @param[in] i_target Reference to MBA Target<fapi2::TARGET_TYPE_MBA>.
+/// @param[in] i_port_number MBA port number
+/// @param[in] i_dimm the DIMM number to issue the RCW to
+/// @param[in] i_cke CKE bits to use
+/// @param[in] i_rcd_num RCD control word number
+/// @param[in] i_rcd_data RCD control word data
+/// @param[in] i_delay number of idles
+/// @param[in, out] io_ccs_inst_cnt CCS instruction count
+/// @return ReturnCode
+fapi2::ReturnCode mss_rcd_load_ddr4_4bit(
+ const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_target,
+ const uint32_t i_port_number,
+ const uint32_t i_dimm,
+ const fapi2::variable_buffer& i_cke,
+ const uint64_t i_rcd_num,
+ const uint64_t i_rcd_data,
+ const uint64_t i_delay,
+ uint32_t& io_ccs_inst_cnt)
+{
+
+ fapi2::variable_buffer l_address_16(16);
+ fapi2::variable_buffer l_bank_3(3);
+ fapi2::variable_buffer l_activate_1(1);
+ fapi2::variable_buffer l_rasn_1(1);
+ fapi2::variable_buffer l_casn_1(1);
+ fapi2::variable_buffer l_wen_1(1);
+ fapi2::variable_buffer l_odt_4(4);
+ fapi2::variable_buffer l_ddr_cal_type_4(4);
+ fapi2::variable_buffer l_num_idles_16(16);
+ fapi2::variable_buffer l_num_repeat_16(16);
+ fapi2::variable_buffer l_data_20(20);
+ fapi2::variable_buffer l_read_compare_1(1);
+ fapi2::variable_buffer l_rank_cal_4(4);
+ fapi2::variable_buffer l_ddr_cal_enable_1(1);
+ fapi2::variable_buffer l_ccs_end_1(1);
+ fapi2::variable_buffer l_csn_8(8);
+ auto l_cke = i_cke;
+
+ // ALL active CS lines at a time.
+ FAPI_TRY(generate_rcd_cs( i_target, i_dimm, l_csn_8, l_cke), "mss_4bit_load: Error setting up buffers %s",
+ mss::c_str(i_target));
+
+ // DBG1, DBG0, DBA1, DBA0 = 4`b0111
+ FAPI_TRY(l_bank_3.setBit(0, 3), "mss_4bit_load: Error setting up buffers %s", mss::c_str(i_target));
+ // DACT_n is HIGH
+ FAPI_TRY(l_activate_1.setBit(0), "mss_4bit_load: Error setting up buffers %s", mss::c_str(i_target));
+ // RAS_n/CAS_n/WE_n are LOW
+ FAPI_TRY(l_rasn_1.clearBit(0), "mss_4bit_load: Error setting up buffers %s", mss::c_str(i_target));
+ FAPI_TRY(l_casn_1.clearBit(0), "mss_4bit_load: Error setting up buffers %s", mss::c_str(i_target));
+ FAPI_TRY(l_wen_1.clearBit(0), "mss_4bit_load: Error setting up buffers %s", mss::c_str(i_target));
+ FAPI_TRY(l_odt_4.clearBit(0, 4));
+
+ //control word number code bits A[7:4]
+ // JEDEC vs CCS swizzle here
+ FAPI_TRY(l_address_16.clearBit(0, 16), "mss_4bit_load: Error setting up buffers %s", mss::c_str(i_target));
+ FAPI_TRY(l_address_16.insert(i_rcd_num, 7, 1, 60), "mss_4bit_load: Error setting up buffers %s", mss::c_str(i_target));
+ FAPI_TRY(l_address_16.insert(i_rcd_num, 6, 1, 61), "mss_4bit_load: Error setting up buffers %s", mss::c_str(i_target));
+ FAPI_TRY(l_address_16.insert(i_rcd_num, 5, 1, 62), "mss_4bit_load: Error setting up buffers %s", mss::c_str(i_target));
+ FAPI_TRY(l_address_16.insert(i_rcd_num, 4, 1, 63), "mss_4bit_load: Error setting up buffers %s", mss::c_str(i_target));
+
+ //control word values RCD0 = A0, RCD1 = A1, RCD2 = A2, RCD3 = A3
+ // JEDEC vs CCS swizzle here
+ FAPI_TRY(l_address_16.insert(i_rcd_data, 0, 1, 63), "mss_4bit_load: Error setting up buffers %s", mss::c_str(i_target));
+ FAPI_TRY(l_address_16.insert(i_rcd_data, 1, 1, 62), "mss_4bit_load: Error setting up buffers %s", mss::c_str(i_target));
+ FAPI_TRY(l_address_16.insert(i_rcd_data, 2, 1, 61), "mss_4bit_load: Error setting up buffers %s", mss::c_str(i_target));
+ FAPI_TRY(l_address_16.insert(i_rcd_data, 3, 1, 60), "mss_4bit_load: Error setting up buffers %s", mss::c_str(i_target));
+
+ // Insert the delays
+ FAPI_TRY(l_num_idles_16.insertFromRight(i_delay, 0, 16), "mss_4bit_load: Error setting up buffers %s",
+ mss::c_str(i_target));
+
+ // Send out to the CCS array
+ FAPI_TRY(mss_ccs_inst_arry_0( i_target,
+ io_ccs_inst_cnt,
+ l_address_16,
+ l_bank_3,
+ l_activate_1,
+ l_rasn_1,
+ l_casn_1,
+ l_wen_1,
+ l_cke,
+ l_csn_8,
+ l_odt_4,
+ l_ddr_cal_type_4,
+ i_port_number), "mss_4bit_load: Error setting up CCS array0 %s", mss::c_str(i_target));
+
+ FAPI_TRY(mss_ccs_inst_arry_1( i_target,
+ io_ccs_inst_cnt,
+ l_num_idles_16,
+ l_num_repeat_16,
+ l_data_20,
+ l_read_compare_1,
+ l_rank_cal_4,
+ l_ddr_cal_enable_1,
+ l_ccs_end_1), "mss_4bit_load: Error setting up CCS array1 %s", mss::c_str(i_target));
+
+ io_ccs_inst_cnt++;
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+/// @brief Sends out RC09 and resets the DRAM
+/// @param[in] i_target Reference to MBA Target<fapi2::TARGET_TYPE_MBA>.
+/// @param[in] i_port_number MBA port number
+/// @param[in] i_dimm - DIMM on which to operate
+/// @param[in, out] io_cke CKE bits to use
+/// @param[in, out] io_ccs_inst_cnt CCS instruction count
+/// @return ReturnCode
+fapi2::ReturnCode mss_rcd_load_workaround( const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_target,
+ const uint32_t i_port_number,
+ const uint32_t i_dimm,
+ fapi2::variable_buffer& io_cke,
+ uint32_t& io_ccs_inst_cnt)
+{
+ // Hit RC09 + enable the CKE's
+ {
+ constexpr uint64_t CKE_PER_DIMM = 2;
+ constexpr uint64_t CKE_PER_PORT = 4;
+
+ // Setup the RCD number
+ constexpr uint64_t RCD_NUM = 9;
+ // Delay taken from the above delays
+ constexpr uint64_t RCD_DELAY = 12;
+ uint64_t l_rcd_data = 0;
+ uint64_t l_rcd_array[MAX_PORTS_PER_MBA][MAX_DIMM_PER_PORT]; //[port][dimm]
+ fapi2::buffer<uint64_t> l_rcd_cntl_wrd_64;
+
+ // Enable the CKE's for this DIMM
+ // 2 CKE per DIMM, 4 CKE per port (2 per DIMM and two DIMM per port)
+ const uint64_t l_cke_start = (i_dimm * CKE_PER_DIMM) + (i_port_number * CKE_PER_PORT);
+ FAPI_TRY(io_cke.setBit(l_cke_start, CKE_PER_DIMM), "failed to setup CKE %s", mss::c_str(i_target));
+ FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CEN_EFF_DIMM_RCD_CNTL_WORD_0_15, i_target, l_rcd_array));
+ l_rcd_cntl_wrd_64 = l_rcd_array[i_port_number][i_dimm];
+
+ // Issue that command
+ l_rcd_cntl_wrd_64.extractToRight<RCD_NUM * 4, 4>(l_rcd_data);
+ FAPI_TRY(mss_rcd_load_ddr4_4bit( i_target,
+ i_port_number,
+ i_dimm,
+ io_cke,
+ RCD_NUM,
+ l_rcd_data,
+ RCD_DELAY,
+ io_ccs_inst_cnt), "mss_rcd_load: Failed to setup 4-bit CW %s", mss::c_str(i_target));
+ }
+
+ // Do the DRAM reset - toggle it on and toggle it off
+ {
+ constexpr uint64_t RESET_ON = 0x02;
+ constexpr uint64_t RESET_CLEAR = 0x03;
+ constexpr uint64_t RESET_RCW = 6;
+ // Taken emperically from Nimbus
+ constexpr uint64_t RCW_DELAY = 8000;
+
+ // Reset...
+ FAPI_TRY(mss_rcd_load_ddr4_4bit( i_target,
+ i_port_number,
+ i_dimm,
+ io_cke,
+ RESET_RCW,
+ RESET_ON,
+ RCW_DELAY,
+ io_ccs_inst_cnt), "mss_rcd_load: Failed to setup 4-bit CW %s", mss::c_str(i_target));
+ // ... Clear the reset
+ FAPI_TRY(mss_rcd_load_ddr4_4bit( i_target,
+ i_port_number,
+ i_dimm,
+ io_cke,
+ RESET_RCW,
+ RESET_CLEAR,
+ RCW_DELAY,
+ io_ccs_inst_cnt), "mss_rcd_load: Failed to setup 4-bit CW %s", mss::c_str(i_target));
+ }
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
/// @brief Writes RCD control words for DDR4 register.
/// @param[in] i_target Reference to MBA Target<fapi2::TARGET_TYPE_MBA>.
/// @param[in] i_port_number MBA port number
+/// @param[in, out] io_cke CKE bits to use
/// @param[in, out] io_ccs_inst_cnt CCS instruction count
/// @return ReturnCode
fapi2::ReturnCode mss_rcd_load_ddr4(
const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_target,
const uint32_t i_port_number,
- uint32_t& io_ccs_inst_cnt
-)
+ fapi2::variable_buffer& io_cke,
+ uint32_t& io_ccs_inst_cnt)
{
+ // Vector of RCD commands and their delays
+ // First in the pair is the RCD number
+ static const std::vector<std::pair<uint64_t, uint64_t>> RCD_NUM_AND_DELAY =
+ {
+ {0, 12},
+ {1, 12},
+ {2, 4000},
+ {3, 12},
+ {4, 12},
+ {5, 12},
+ {6, 12},
+ {7, 12},
+ {8, 12},
+ // Note: 9 is missing this is intentional
+ // Per a supplier workaround, we need to set this guy last to clear out any corruption that could happen
+ {10, 4000},
+ {11, 12},
+ {12, 12},
+ {13, 12},
+ {14, 12},
+ {15, 12},
+ };
+
uint32_t l_dimm_number = 0;
- uint32_t l_rcd_number = 0;
fapi2::variable_buffer l_rcd_cntl_wrd_4(8);
fapi2::variable_buffer l_rcd_cntl_wrd_8(8);
fapi2::variable_buffer l_rcd_cntl_wrd_64(64);
@@ -813,7 +1015,7 @@ fapi2::ReturnCode mss_rcd_load_ddr4(
fapi2::variable_buffer l_rasn_1(1);
fapi2::variable_buffer l_casn_1(1);
fapi2::variable_buffer l_wen_1(1);
- fapi2::variable_buffer l_cke_4(4);
+ fapi2::variable_buffer l_cke_8(8);
fapi2::variable_buffer l_csn_8(8);
fapi2::variable_buffer l_odt_4(4);
fapi2::variable_buffer l_ddr_cal_type_4(4);
@@ -829,9 +1031,9 @@ fapi2::ReturnCode mss_rcd_load_ddr4(
FAPI_TRY(l_rasn_1.setBit(0));
FAPI_TRY(l_casn_1.setBit(0));
FAPI_TRY(l_wen_1.setBit(0));
- FAPI_TRY(l_cke_4.setBit(0, 4));
FAPI_TRY(l_csn_8.setBit(0, 8));
FAPI_TRY(l_odt_4.clearBit(0, 4));
+ FAPI_TRY(l_activate_1.setBit(0));
FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CEN_EFF_DIMM_TYPE, i_target, l_dimm_type));
@@ -850,9 +1052,10 @@ fapi2::ReturnCode mss_rcd_load_ddr4(
FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_CEN_EFF_DIMM_DDR4_RC_Bx, i_target, l_rcd_cntl_word_Bx));
- // Raise CKE high with NOPS, waiting min Reset CKE exit time (tXPR) - 400 cycles
- FAPI_TRY(l_address_16.clearBit(0, 16), "mss_rcd_load: Error setting up buffers");
- FAPI_TRY(l_num_idles_16.insertFromRight((uint32_t) 400, 0, 16), "mss_rcd_load: Error setting up buffers");
+ // Keep CKE's at current levels, waiting min Reset CKE exit time (tXPR) - 400 cycles
+ FAPI_TRY(l_address_16.clearBit(0, 16), "mss_rcd_load: Error setting up buffers %s", mss::c_str(i_target));
+ FAPI_TRY(l_num_idles_16.insertFromRight((uint32_t) 400, 0, 16), "mss_rcd_load: Error setting up buffers %s",
+ mss::c_str(i_target));
FAPI_TRY(mss_ccs_inst_arry_0( i_target,
io_ccs_inst_cnt,
l_address_16,
@@ -861,11 +1064,11 @@ fapi2::ReturnCode mss_rcd_load_ddr4(
l_rasn_1,
l_casn_1,
l_wen_1,
- l_cke_4,
+ io_cke,
l_csn_8,
l_odt_4,
l_ddr_cal_type_4,
- i_port_number));
+ i_port_number), "mss_rcd_load: Error setting up CCS array0 %s", mss::c_str(i_target));
FAPI_TRY(mss_ccs_inst_arry_1( i_target,
io_ccs_inst_cnt,
@@ -875,7 +1078,7 @@ fapi2::ReturnCode mss_rcd_load_ddr4(
l_read_compare_1,
l_rank_cal_4,
l_ddr_cal_enable_1,
- l_ccs_end_1));
+ l_ccs_end_1), "mss_rcd_load: Error setting up CCS array1 %s", mss::c_str(i_target));
io_ccs_inst_cnt++;
@@ -888,165 +1091,137 @@ fapi2::ReturnCode mss_rcd_load_ddr4(
if (l_num_ranks == 0)
{
- FAPI_INF( "PORT%d DIMM%d not configured. Num_ranks: %d", i_port_number, l_dimm_number, l_num_ranks);
+ FAPI_INF( "%s PORT%d DIMM%d not configured. Num_ranks: %d", mss::c_str(i_target), i_port_number, l_dimm_number,
+ l_num_ranks);
}
else
{
FAPI_INF( "RCD SETTINGS FOR %s PORT%d DIMM%d ", mss::c_str(i_target), i_port_number, l_dimm_number);
- FAPI_INF( "RCD Control Word: 0x%016llX", l_rcd_array[i_port_number][l_dimm_number]);
- FAPI_INF( "RCD Control Word X: 0x%016llX", l_rcdx_array);
+ FAPI_INF( "RCD %s Control Word: 0x%016llX", mss::c_str(i_target), l_rcd_array[i_port_number][l_dimm_number]);
+ FAPI_INF( "RCD %s Control Word X: 0x%016llX", mss::c_str(i_target), l_rcdx_array);
// ALL active CS lines at a time.
- FAPI_TRY(generate_rcd_cs(i_target, l_dimm_number, l_csn_8, l_cke_4));
+ FAPI_TRY(generate_rcd_cs(i_target, l_dimm_number, l_csn_8, io_cke));
// DBG1, DBG0, DBA1, DBA0 = 4`b0111
- FAPI_TRY(l_bank_3.setBit(0, 3), "mss_rcd_load: Error setting up buffers");
+ FAPI_TRY(l_bank_3.setBit(0, 3), "mss_rcd_load: Error setting up buffers %s", mss::c_str(i_target));
// DACT_n is HIGH
- FAPI_TRY(l_activate_1.setBit(0), "mss_rcd_load: Error setting up buffers");
+ FAPI_TRY(l_activate_1.setBit(0), "mss_rcd_load: Error setting up buffers %s", mss::c_str(i_target));
// RAS_n/CAS_n/WE_n are LOW
- FAPI_TRY(l_rasn_1.clearBit(0), "mss_rcd_load: Error setting up buffers");
- FAPI_TRY(l_casn_1.clearBit(0), "mss_rcd_load: Error setting up buffers");
- FAPI_TRY(l_wen_1.clearBit(0), "mss_rcd_load: Error setting up buffers");
+ FAPI_TRY(l_rasn_1.clearBit(0), "mss_rcd_load: Error setting up buffers %s", mss::c_str(i_target));
+ FAPI_TRY(l_casn_1.clearBit(0), "mss_rcd_load: Error setting up buffers %s", mss::c_str(i_target));
+ FAPI_TRY(l_wen_1.clearBit(0), "mss_rcd_load: Error setting up buffers %s", mss::c_str(i_target));
// Propogate through the 16, 4-bit control words
- for ( l_rcd_number = 0; l_rcd_number <= 15; l_rcd_number ++)
- {
- //FAPI_TRY(l_bank_3.clearBit(0, 3);
- FAPI_TRY(l_address_16.clearBit(0, 16), "mss_rcd_load: Error setting up buffers");
-
- FAPI_TRY(l_rcd_cntl_wrd_64.insert(l_rcd_array[i_port_number][l_dimm_number]), "mss_rcd_load: Error setting up buffers");
- FAPI_TRY(l_rcd_cntl_wrd_64.extract(l_rcd_cntl_wrd_4, 4 * l_rcd_number, 4), "mss_rcd_load: Error setting up buffers");
-
- //control word number code bits A[7:4]
- FAPI_TRY(l_address_16.insert(l_rcd_number, 7, 1, 28), "mss_rcd_load: Error setting up buffers");
- FAPI_TRY(l_address_16.insert(l_rcd_number, 6, 1, 29), "mss_rcd_load: Error setting up buffers");
- FAPI_TRY(l_address_16.insert(l_rcd_number, 5, 1, 30), "mss_rcd_load: Error setting up buffers");
- FAPI_TRY(l_address_16.insert(l_rcd_number, 4, 1, 31), "mss_rcd_load: Error setting up buffers");
-
- //control word values RCD0 = A0, RCD1 = A1, RCD2 = A2, RCD3 = A3
- FAPI_TRY(l_address_16.insert(l_rcd_cntl_wrd_4, 0, 1, 3), "mss_rcd_load: Error setting up buffers");
- FAPI_TRY(l_address_16.insert(l_rcd_cntl_wrd_4, 1, 1, 2), "mss_rcd_load: Error setting up buffers");
- FAPI_TRY(l_address_16.insert(l_rcd_cntl_wrd_4, 2, 1, 1), "mss_rcd_load: Error setting up buffers");
- FAPI_TRY(l_address_16.insert(l_rcd_cntl_wrd_4, 3, 1, 0), "mss_rcd_load: Error setting up buffers");
-
- // Send out to the CCS array
- //if ( dimm_type == ENUM_ATTR_CEN_EFF_DIMM_TYPE_LRDIMM && (rcd_number == 2 || rcd_number == 10) )
- if ( l_rcd_number == 2 || l_rcd_number == 10 )
- {
- FAPI_TRY(l_num_idles_16.insertFromRight((uint32_t) 4000, 0 , 16 ),
- "mss_rcd_load: Error setting up buffers"); // wait tStab for clock timing rcd words
- }
- else
- {
- FAPI_TRY(l_num_idles_16.insertFromRight((uint32_t) 12, 0, 16), "mss_rcd_load: Error setting up buffers");
- }
-
-
-
- FAPI_TRY(mss_ccs_inst_arry_0( i_target,
- io_ccs_inst_cnt,
- l_address_16,
- l_bank_3,
- l_activate_1,
- l_rasn_1,
- l_casn_1,
- l_wen_1,
- l_cke_4,
- l_csn_8,
- l_odt_4,
- l_ddr_cal_type_4,
- i_port_number));
-
- FAPI_TRY(mss_ccs_inst_arry_1( i_target,
- io_ccs_inst_cnt,
- l_num_idles_16,
- l_num_repeat_16,
- l_data_20,
- l_read_compare_1,
- l_rank_cal_4,
- l_ddr_cal_enable_1,
- l_ccs_end_1));
-
- io_ccs_inst_cnt++;
-
+ FAPI_TRY(l_rcd_cntl_wrd_64.insert(l_rcd_array[i_port_number][l_dimm_number]),
+ "mss_rcd_load: Error setting up buffers %s", mss::c_str(i_target));
+
+ for ( const auto& l_rcd_pair : RCD_NUM_AND_DELAY )
+ {
+ const auto l_rcd_number = l_rcd_pair.first;
+ const auto l_rcd_delay = l_rcd_pair.second;
+ uint64_t l_rcd_data = 0;
+ FAPI_TRY(l_rcd_cntl_wrd_64.extractToRight(l_rcd_data, 4 * l_rcd_number, 4), "mss_rcd_load: Error setting up buffers %s",
+ mss::c_str(i_target));
+ FAPI_TRY(mss_rcd_load_ddr4_4bit( i_target,
+ i_port_number,
+ l_dimm_number,
+ io_cke,
+ l_rcd_number,
+ l_rcd_data,
+ l_rcd_delay,
+ io_ccs_inst_cnt), "mss_rcd_load: Failed to setup 4-bit CW %s", mss::c_str(i_target));
}
// 8-bit Control words
- for ( l_rcd_number = 0; l_rcd_number <= 7; l_rcd_number ++)
+ for ( uint8_t l_rcd_number = 0; l_rcd_number <= 7; l_rcd_number ++)
{
//FAPI_TRY(l_bank_3.clearBit(0, 3);
- FAPI_TRY(l_address_16.clearBit(0, 16), "mss_rcd_load: Error setting up buffers");
+ FAPI_TRY(l_address_16.clearBit(0, 16), "mss_rcd_load: Error setting up buffers %s", mss::c_str(i_target));
switch(l_cntlx_offset[l_rcd_number])
{
case 0x01:
FAPI_TRY(l_rcd_cntl_wrd_8.insert(l_rcd_cntl_word_1x[i_port_number][l_dimm_number], 0, 8, 0),
- "mss_rcd_load: Error setting up buffers");
+ "mss_rcd_load: Error setting up buffers %s", mss::c_str(i_target));
break;
case 0x02:
FAPI_TRY(l_rcd_cntl_wrd_8.insert(l_rcd_cntl_word_2x[i_port_number][l_dimm_number], 0, 8, 0),
- "mss_rcd_load: Error setting up buffers");
+ "mss_rcd_load: Error setting up buffers %s", mss::c_str(i_target));
break;
case 0x03:
FAPI_TRY(l_rcd_cntl_wrd_8.insert(l_rcd_cntl_word_3x[i_port_number][l_dimm_number], 0, 8, 0),
- "mss_rcd_load: Error setting up buffers");
+ "mss_rcd_load: Error setting up buffers %s", mss::c_str(i_target));
break;
case 0x07:
FAPI_TRY(l_rcd_cntl_wrd_8.insert(l_rcd_cntl_word_7x[i_port_number][l_dimm_number], 0, 8, 0),
- "mss_rcd_load: Error setting up buffers");
+ "mss_rcd_load: Error setting up buffers %s", mss::c_str(i_target));
break;
case 0x08:
FAPI_TRY(l_rcd_cntl_wrd_8.insert(l_rcd_cntl_word_8x[i_port_number][l_dimm_number], 0, 8, 0),
- "mss_rcd_load: Error setting up buffers");
+ "mss_rcd_load: Error setting up buffers %s", mss::c_str(i_target));
break;
case 0x09:
FAPI_TRY(l_rcd_cntl_wrd_8.insert(l_rcd_cntl_word_9x[i_port_number][l_dimm_number], 0, 8, 0),
- "mss_rcd_load: Error setting up buffers");
+ "mss_rcd_load: Error setting up buffers %s", mss::c_str(i_target));
break;
case 0x0a:
FAPI_TRY(l_rcd_cntl_wrd_8.insert(l_rcd_cntl_word_Ax[i_port_number][l_dimm_number], 0, 8, 0),
- "mss_rcd_load: Error setting up buffers");
+ "mss_rcd_load: Error setting up buffers %s", mss::c_str(i_target));
break;
case 0x0b:
default:
FAPI_TRY(l_rcd_cntl_wrd_8.insert(l_rcd_cntl_word_Bx[i_port_number][l_dimm_number], 0, 8, 0),
- "mss_rcd_load: Error setting up buffers");
+ "mss_rcd_load: Error setting up buffers %s", mss::c_str(i_target));
break;
}
//control word number code bits A[11:8]
- FAPI_TRY(l_address_16.insert(l_cntlx_offset[l_rcd_number], 11, 1, 28), "mss_rcd_load: Error setting up buffers");
- FAPI_TRY(l_address_16.insert(l_cntlx_offset[l_rcd_number], 10, 1, 29), "mss_rcd_load: Error setting up buffers");
- FAPI_TRY(l_address_16.insert(l_cntlx_offset[l_rcd_number], 9, 1, 30), "mss_rcd_load: Error setting up buffers");
- FAPI_TRY(l_address_16.insert(l_cntlx_offset[l_rcd_number], 8, 1, 31), "mss_rcd_load: Error setting up buffers");
+ FAPI_TRY(l_address_16.insert(l_cntlx_offset[l_rcd_number], 11, 1, 28), "mss_rcd_load: Error setting up buffers %s",
+ mss::c_str(i_target));
+ FAPI_TRY(l_address_16.insert(l_cntlx_offset[l_rcd_number], 10, 1, 29), "mss_rcd_load: Error setting up buffers %s",
+ mss::c_str(i_target));
+ FAPI_TRY(l_address_16.insert(l_cntlx_offset[l_rcd_number], 9, 1, 30), "mss_rcd_load: Error setting up buffers %s",
+ mss::c_str(i_target));
+ FAPI_TRY(l_address_16.insert(l_cntlx_offset[l_rcd_number], 8, 1, 31), "mss_rcd_load: Error setting up buffers %s",
+ mss::c_str(i_target));
//control word values RCD0 = A0, RCD1 = A1, RCD2 = A2, RCD3 = A3, RCD4=A4, RCD5=A5, RCD6=A6, RCD7=A7
//
- FAPI_TRY(l_address_16.insert(l_rcd_cntl_wrd_8, 0, 1, 7), "mss_rcd_load: Error setting up buffers");
- FAPI_TRY(l_address_16.insert(l_rcd_cntl_wrd_8, 1, 1, 6), "mss_rcd_load: Error setting up buffers");
- FAPI_TRY(l_address_16.insert(l_rcd_cntl_wrd_8, 2, 1, 5), "mss_rcd_load: Error setting up buffers");
- FAPI_TRY(l_address_16.insert(l_rcd_cntl_wrd_8, 3, 1, 4), "mss_rcd_load: Error setting up buffers");
- FAPI_TRY(l_address_16.insert(l_rcd_cntl_wrd_8, 4, 1, 3), "mss_rcd_load: Error setting up buffers");
- FAPI_TRY(l_address_16.insert(l_rcd_cntl_wrd_8, 5, 1, 2), "mss_rcd_load: Error setting up buffers");
- FAPI_TRY(l_address_16.insert(l_rcd_cntl_wrd_8, 6, 1, 1), "mss_rcd_load: Error setting up buffers");
- FAPI_TRY(l_address_16.insert(l_rcd_cntl_wrd_8, 7, 1, 0), "mss_rcd_load: Error setting up buffers");
+ FAPI_TRY(l_address_16.insert(l_rcd_cntl_wrd_8, 0, 1, 7), "mss_rcd_load: Error setting up buffers %s",
+ mss::c_str(i_target));
+ FAPI_TRY(l_address_16.insert(l_rcd_cntl_wrd_8, 1, 1, 6), "mss_rcd_load: Error setting up buffers %s",
+ mss::c_str(i_target));
+ FAPI_TRY(l_address_16.insert(l_rcd_cntl_wrd_8, 2, 1, 5), "mss_rcd_load: Error setting up buffers %s",
+ mss::c_str(i_target));
+ FAPI_TRY(l_address_16.insert(l_rcd_cntl_wrd_8, 3, 1, 4), "mss_rcd_load: Error setting up buffers %s",
+ mss::c_str(i_target));
+ FAPI_TRY(l_address_16.insert(l_rcd_cntl_wrd_8, 4, 1, 3), "mss_rcd_load: Error setting up buffers %s",
+ mss::c_str(i_target));
+ FAPI_TRY(l_address_16.insert(l_rcd_cntl_wrd_8, 5, 1, 2), "mss_rcd_load: Error setting up buffers %s",
+ mss::c_str(i_target));
+ FAPI_TRY(l_address_16.insert(l_rcd_cntl_wrd_8, 6, 1, 1), "mss_rcd_load: Error setting up buffers %s",
+ mss::c_str(i_target));
+ FAPI_TRY(l_address_16.insert(l_rcd_cntl_wrd_8, 7, 1, 0), "mss_rcd_load: Error setting up buffers %s",
+ mss::c_str(i_target));
// Send out to the CCS array
if ( l_rcd_number == 2 ) // CW RC3x
{
FAPI_TRY(l_num_idles_16.insertFromRight((uint32_t) 4000, 0 , 16 ),
- "mss_rcd_load: Error setting up buffers"); // wait tStab for clock timing rcd words
+ "mss_rcd_load: Error setting up buffers %s", mss::c_str(i_target)); // wait tStab for clock timing rcd words
}
else
{
- FAPI_TRY(l_num_idles_16.insertFromRight((uint32_t) 12, 0, 16), "mss_rcd_load: Error setting up buffers");
+ FAPI_TRY(l_num_idles_16.insertFromRight((uint32_t) 12, 0, 16), "mss_rcd_load: Error setting up buffers %s",
+ mss::c_str(i_target));
}
@@ -1058,7 +1233,7 @@ fapi2::ReturnCode mss_rcd_load_ddr4(
l_rasn_1,
l_casn_1,
l_wen_1,
- l_cke_4,
+ io_cke,
l_csn_8,
l_odt_4,
l_ddr_cal_type_4,
@@ -1077,13 +1252,23 @@ fapi2::ReturnCode mss_rcd_load_ddr4(
io_ccs_inst_cnt++;
}
+
+ // Does the RCD load workaround here
+ FAPI_TRY(mss_rcd_load_workaround( i_target,
+ i_port_number,
+ l_dimm_number,
+ io_cke,
+ io_ccs_inst_cnt), "mss_rcd_load: failed RCD workaround %s", mss::c_str(i_target));
}
}
- FAPI_TRY(mss_ccs_set_end_bit( i_target, io_ccs_inst_cnt - 1), "CCS_SET_END_BIT FAILED FAPI_TRY");
+ // Note: preserving CKE's here - it's important to avoid DRAM corruption
+ FAPI_TRY(mss_ccs_set_end_bit( i_target, io_ccs_inst_cnt - 1, io_cke), "CCS_SET_END_BIT FAILED FAPI_TRY %s",
+ mss::c_str(i_target));
io_ccs_inst_cnt = 0;
- FAPI_TRY(mss_execute_ccs_inst_array(i_target, 10, 10), " EXECUTE_CCS_INST_ARRAY FAILED FAPI_TRY");
+ FAPI_TRY(mss_execute_ccs_inst_array(i_target, 10, 10), " EXECUTE_CCS_INST_ARRAY FAILED FAPI_TRY %s",
+ mss::c_str(i_target));
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 01858e9c7..fa373ad3c 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
@@ -69,13 +69,48 @@ fapi2::ReturnCode generate_rcd_cs( const fapi2::Target<fapi2::TARGET_TYPE_MBA>&
/// @brief Writes RCD control words for DDR4 register.
/// @param[in] i_target Reference to MBA Target<fapi2::TARGET_TYPE_MBA>.
/// @param[in] i_port_number MBA port number
+/// @param[in, out] io_cke CKE bits to use
/// @param[in, out] io_ccs_inst_cnt CCS instruction count
/// @return ReturnCode
fapi2::ReturnCode mss_rcd_load_ddr4(
const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_target,
const uint32_t i_port_number,
+ fapi2::variable_buffer& io_cke,
uint32_t& io_ccs_inst_cnt);
+/// @brief Writes the 4-bit RCD control words for DDR4 register.
+/// @param[in] i_target Reference to MBA Target<fapi2::TARGET_TYPE_MBA>.
+/// @param[in] i_port_number MBA port number
+/// @param[in] i_dimm the DIMM number to issue the RCW to
+/// @param[in] i_cke CKE bits to use
+/// @param[in] i_rcd_num RCD control word number
+/// @param[in] i_rcd_data RCD control word data
+/// @param[in] i_delay number of idles
+/// @param[in, out] io_ccs_inst_cnt CCS instruction count
+/// @return ReturnCode
+fapi2::ReturnCode mss_rcd_load_ddr4_4bit(
+ const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_target,
+ const uint32_t i_port_number,
+ const uint32_t i_dimm,
+ const fapi2::variable_buffer& i_cke,
+ const uint64_t i_rcd_num,
+ const uint64_t i_rcd_data,
+ const uint64_t i_delay,
+ uint32_t& io_ccs_inst_cnt);
+
+/// @brief Sends out RC09 and resets the DRAM
+/// @param[in] i_target Reference to MBA Target<fapi2::TARGET_TYPE_MBA>.
+/// @param[in] i_port_number MBA port number
+/// @param[in] i_dimm - DIMM on which to operate
+/// @param[in, out] io_cke CKE bits to use
+/// @param[in, out] io_ccs_inst_cnt CCS instruction count
+/// @return ReturnCode
+fapi2::ReturnCode mss_rcd_load_workaround( const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_target,
+ const uint32_t i_port_number,
+ const uint32_t i_dimm,
+ fapi2::variable_buffer& io_cke,
+ uint32_t& io_ccs_inst_cnt);
+
/// @brief Creates RCD_CNTRL_WORD attribute for DDR4 register
/// @param[in] i_target_mba Reference to MBA Target<fapi2::TARGET_TYPE_MBA>.
/// @return ReturnCode
diff --git a/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_draminit.C b/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_draminit.C
index 48b288435..f95d3b979 100755
--- a/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_draminit.C
+++ b/src/import/chips/centaur/procedures/hwp/memory/p9c_mss_draminit.C
@@ -70,6 +70,10 @@ extern "C" {
fapi2::variable_buffer mrs4(16);
fapi2::variable_buffer mrs5(16);
fapi2::variable_buffer mrs6(16);
+
+ // CKE need to be on or off by port and then maintained for the RCD load
+ fapi2::variable_buffer l_cke(8);
+
uint8_t l_num_drops_per_port = 0;
uint8_t l_primary_ranks_array[NUM_RANK_GROUPS][MAX_PORTS_PER_MBA] = {}; //primary_ranks_array[group][port]
uint8_t l_secondary_ranks_array[NUM_RANK_GROUPS][MAX_PORTS_PER_MBA] = {}; //secondary_ranks_array[group][port]
@@ -290,6 +294,8 @@ extern "C" {
FAPI_TRY(fapi2::delay(DELAY_100US, DELAY_2000SIMCYCLES)); // wait 2000 simcycles (in sim mode) OR 100 uS (in hw mode)
FAPI_TRY(mss_assert_resetn(i_target, 1 ), " assert_resetn Failed "); // de-assert a reset
+ FAPI_TRY(l_cke.clearBit(0, 8));
+
// Cycle through Ports...
// Ports 0-1
for ( l_port_number = 0; l_port_number < MAX_PORTS_PER_MBA; l_port_number++)
@@ -300,7 +306,7 @@ extern "C" {
// Step three: Load RCD Control Words
if(l_dram_gen == fapi2::ENUM_ATTR_CEN_EFF_DRAM_GEN_DDR4)
{
- FAPI_TRY(mss_rcd_load_ddr4(i_target, l_port_number, l_ccs_inst_cnt), " rcd_load Failed");
+ FAPI_TRY(mss_rcd_load_ddr4(i_target, l_port_number, l_cke, l_ccs_inst_cnt), " rcd_load Failed");
}
else if(l_dram_gen == fapi2::ENUM_ATTR_CEN_EFF_DRAM_GEN_DDR3)
{
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 083a6496b..6e483d81f 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
@@ -65,6 +65,9 @@ fapi2::ReturnCode mss_disable_cid( const fapi2::Target<fapi2::TARGET_TYPE_MBA>&
// CID 0/1 on DIMM1
FAPI_TRY(io_csn.clearBit(6, 2));
+ // Currently, CID2 is not needed. If it is needed, we'll need to uncomment the below code
+ // We'll also need to fake out CCS to think that it has 16Gb memory so we can use CKE3/7 independently of other signals
+#if CID2_IS_NEEDED
// CID2 hangs out in CKE1
FAPI_TRY(io_cke.clearBit(1));
@@ -73,6 +76,8 @@ fapi2::ReturnCode mss_disable_cid( const fapi2::Target<fapi2::TARGET_TYPE_MBA>&
{
FAPI_TRY(io_cke.clearBit(5));
}
+
+#endif
}
fapi_try_exit:
@@ -91,13 +96,33 @@ fapi2::ReturnCode mss_ccs_set_end_bit(
uint32_t i_instruction_number
)
{
+ fapi2::variable_buffer l_cke_4(4);
+ FAPI_TRY(l_cke_4.setBit(0, 4), "Error setting up buffers");
+ FAPI_TRY(mss_ccs_set_end_bit( i_target,
+ i_instruction_number,
+ l_cke_4 ));
+
+fapi_try_exit:
+ return fapi2::current_err;
+}
+
+///
+/// @brief Setting the End location of the CCS array
+/// @param[in] i_target - Target<fapi2::TARGET_TYPE_MBA> = centaur.mba
+/// @param[in] i_instruction_number - CCS instruction number
+/// @param[in] i_cke - CKE to pass into the NOP
+/// @return FAPI2_RC_SUCCESS iff successful
+///
+fapi2::ReturnCode mss_ccs_set_end_bit( const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_target,
+ uint32_t i_instruction_number,
+ const fapi2::variable_buffer& i_cke)
+{
fapi2::variable_buffer l_address_16(16);
fapi2::variable_buffer l_bank_3(3);
fapi2::variable_buffer l_activate_1(1);
fapi2::variable_buffer l_rasn_1(1);
fapi2::variable_buffer l_casn_1(1);
fapi2::variable_buffer l_wen_1(1);
- fapi2::variable_buffer l_cke_4(4);
fapi2::variable_buffer l_csn_8(8);
fapi2::variable_buffer l_odt_4(4);
fapi2::variable_buffer l_ddr_cal_type_4(4);
@@ -121,7 +146,6 @@ fapi2::ReturnCode mss_ccs_set_end_bit(
FAPI_TRY(l_num_idles_16.clearBit(0, 16));
FAPI_TRY(l_odt_4.clearBit(0, 4), "Error setting up buffers");
FAPI_TRY(l_csn_8.setBit(0, 8), "Error setting up buffers");
- FAPI_TRY(l_cke_4.setBit(0, 4), "Error setting up buffers");
FAPI_TRY(l_wen_1.clearBit(0), "Error setting up buffers");
FAPI_TRY(l_casn_1.clearBit(0), "Error setting up buffers");
FAPI_TRY(l_rasn_1.clearBit(0), "Error setting up buffers");
@@ -136,7 +160,7 @@ fapi2::ReturnCode mss_ccs_set_end_bit(
l_rasn_1,
l_casn_1,
l_wen_1,
- l_cke_4,
+ i_cke,
l_csn_8,
l_odt_4,
l_ddr_cal_type_4,
@@ -291,7 +315,7 @@ fapi2::ReturnCode mss_ccs_inst_arry_0(
l_num_retry = 20;
l_timer = DELAY_100US;
FAPI_DBG("CCS: Set end bit.\n");
- FAPI_TRY(mss_ccs_set_end_bit( i_target, 29));
+ FAPI_TRY(mss_ccs_set_end_bit( i_target, 29, i_cke ));
FAPI_TRY(mss_execute_ccs_inst_array( i_target, l_num_retry, l_timer));
io_instruction_number = 0;
}
@@ -305,8 +329,20 @@ fapi2::ReturnCode mss_ccs_inst_arry_0(
l_reg_address = io_instruction_number + CEN_MBA_CCS_INST_ARR0_0;
l_data_buffer.flush<0>();
- FAPI_TRY(l_data_buffer.insert(i_cke, 24, 4, 0), "insert failed");
- FAPI_TRY(l_data_buffer.insert(i_cke, 28, 4, 0), "insert failed");
+
+ // If we have 8 CKE bits, then we want to control the CKE's individually on each port
+ // Just copy the CKE information directly
+ // Why 8 CKE bits? We have a total of 8 CKE bits in each CCS register
+ if(i_cke.getBitLength() == 8)
+ {
+ FAPI_TRY(l_data_buffer.insert(i_cke, 24, 8, 0), "insert failed");
+ }
+ // Otherwise, copy the CKE from one port to the other
+ else
+ {
+ FAPI_TRY(l_data_buffer.insert(i_cke, 24, 4, 0), "insert failed");
+ FAPI_TRY(l_data_buffer.insert(i_cke, 28, 4, 0), "insert failed");
+ }
if (i_port == 0)
{
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 a79b9f954..1ff845aa9 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
@@ -200,12 +200,22 @@ fapi2::ReturnCode mss_execute_ccs_inst_array( const fapi2::Target<fapi2::TARGET_
///
/// @brief Setting the End location of the CCS array
-/// @param[in] Target<fapi2::TARGET_TYPE_MBA> = centaur.mba
-/// @param[in] CCS instruction number
+/// @param[in] i_target - Target<fapi2::TARGET_TYPE_MBA> = centaur.mba
+/// @param[in] i_instruction_number - CCS instruction number
/// @return FAPI2_RC_SUCCESS iff successful
///
fapi2::ReturnCode mss_ccs_set_end_bit( const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_target,
uint32_t i_instruction_number);
+///
+/// @brief Setting the End location of the CCS array
+/// @param[in] i_target - Target<fapi2::TARGET_TYPE_MBA> = centaur.mba
+/// @param[in] i_instruction_number - CCS instruction number
+/// @param[in] i_cke - CKE to pass into the NOP
+/// @return FAPI2_RC_SUCCESS iff successful
+///
+fapi2::ReturnCode mss_ccs_set_end_bit( const fapi2::Target<fapi2::TARGET_TYPE_MBA>& i_target,
+ uint32_t i_instruction_number,
+ const fapi2::variable_buffer& i_cke);
///
OpenPOWER on IntegriCloud