Skip to content

Commit 48715fb

Browse files
JacobHarveydcrowell77
authored andcommitted
Turn off A17 if not needed
Change-Id: I3b4b31e537586339f90ffd48b60ed93bfb531fea Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/41848 Dev-Ready: JACOB L. HARVEY <jlharvey@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: STEPHEN GLANCY <sglancy@us.ibm.com> Reviewed-by: Louis Stermole <stermole@us.ibm.com> Reviewed-by: Jennifer A. Stofer <stofer@us.ibm.com> Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/41944 Reviewed-by: Hostboot Team <hostboot@us.ibm.com> Tested-by: Jenkins OP Build CI <op-jenkins+hostboot@us.ibm.com> Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com>
1 parent 5fd4a6a commit 48715fb

File tree

8 files changed

+132
-25
lines changed

8 files changed

+132
-25
lines changed

src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs_load_ddr4.C

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,65 @@ fapi_try_exit:
7070
return fapi2::current_err;
7171
}
7272

73+
///
74+
/// @brief Helper function to determine whether the A17 is needed
75+
/// @param[in] i_target the DIMM target
76+
/// @param[out] o_is_needed boolean whether A17 should be turned on or off
77+
/// @return fapi2::FAPI2_RC_SUCCESS if okay
78+
/// @note Based off of Table 2.8 Proposed DDR4 Full spec update(79-4B) page 28
79+
///
80+
template<>
81+
fapi2::ReturnCode is_a17_needed(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
82+
bool& o_is_needed)
83+
{
84+
uint8_t l_dram_density = 0;
85+
uint8_t l_dram_width = 0;
86+
87+
FAPI_TRY( eff_dram_density( i_target, l_dram_density) );
88+
FAPI_TRY( eff_dram_width( i_target, l_dram_width) );
89+
90+
o_is_needed = (l_dram_density == fapi2::ENUM_ATTR_EFF_DRAM_DENSITY_16G
91+
&& l_dram_width == fapi2::ENUM_ATTR_EFF_DRAM_WIDTH_X4) ?
92+
true : false;
93+
FAPI_INF("%s Turning A17 %s", mss::c_str(i_target), o_is_needed ? "on" : "off" );
94+
95+
fapi_try_exit:
96+
return fapi2::current_err;
97+
}
98+
99+
///
100+
/// @brief Helper function to determine whether the A17 is needed
101+
/// @param[in] i_target the MCA target
102+
/// @param[out] o_is_needed boolean whether A17 should be turned on or off
103+
/// @return fapi2::FAPI2_RC_SUCCESS if okay
104+
/// @note Based off of Table 2.8 Proposed DDR4 Full spec update(79-4B) page 28
105+
///
106+
template<>
107+
fapi2::ReturnCode is_a17_needed(const fapi2::Target<fapi2::TARGET_TYPE_MCA>& i_target,
108+
bool& o_is_needed)
109+
{
110+
// Set this to good in case no dimms and we're running unit tests
111+
fapi2::current_err = fapi2::FAPI2_RC_SUCCESS;
112+
113+
// Loop over the DIMMs and see if A17 is needed for one of them
114+
// If so, we enable the parity bit in the PHY
115+
for (const auto& l_dimm : mss::find_targets<TARGET_TYPE_DIMM>(i_target) )
116+
{
117+
// Default to not used
118+
// Using temp because we want to OR the two results together. Don't want the false to overwrite
119+
bool l_temp = false;
120+
FAPI_TRY( is_a17_needed( l_dimm, l_temp), "%s Failed to get a17 boolean", mss::c_str(l_dimm) );
121+
122+
if (l_temp == true)
123+
{
124+
o_is_needed = true;
125+
}
126+
}
127+
128+
fapi_try_exit:
129+
return fapi2::current_err;
130+
}
131+
73132
namespace ddr4
74133
{
75134

src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs_load_ddr4.H

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -147,11 +147,16 @@ fapi_try_exit:
147147

148148
///
149149
/// @brief Invert (side to side) the ADR bits of a CCS instruction
150+
/// @tparam T the target type of the ccs instruction
151+
/// @param[in] i_target the DIMM target of the ccs command
150152
/// @param[in] i_inst const reference to a CCS instruction.
151-
/// @return[out] ccs instruction with the ADR bits inverted (side-to-side)
153+
/// @param[in] l_is_a17 Boolean for whether A17 bit is enabled or not
154+
/// @return ccs instruction with the ADR bits inverted (side-to-side)
152155
///
153156
template<fapi2::TargetType T>
154-
ccs::instruction_t<T> address_invert(const ccs::instruction_t<T>& i_inst)
157+
ccs::instruction_t<T> address_invert(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
158+
const ccs::instruction_t<T>& i_inst,
159+
const bool i_is_a17 = false)
155160
{
156161
// Copy the input as the output doesn't all change.
157162
ccs::instruction_t<T> i_out(i_inst);
@@ -167,7 +172,12 @@ ccs::instruction_t<T> address_invert(const ccs::instruction_t<T>& i_inst)
167172

168173
mss::template negate<A11>(i_out.arr0);
169174
mss::template negate<A13>(i_out.arr0);
170-
mss::template negate<A17>(i_out.arr0);
175+
176+
if (i_is_a17)
177+
{
178+
FAPI_INF("%s A17 is turned on, negating CCS bit A17", mss::c_str(i_target) );
179+
mss::template negate<A17>(i_out.arr0);
180+
}
171181

172182
mss::template negate<BA0>(i_out.arr0);
173183
mss::template negate<BA1>(i_out.arr0);
@@ -245,6 +255,18 @@ fapi_try_exit:
245255
return fapi2::current_err;
246256
}
247257

258+
///
259+
/// @brief Helper function to determine whether the A17 is needed
260+
/// @tparam T fapi2::TargetType DIMM or MCA
261+
/// @param[in] i_target the target to check
262+
/// @param[out] o_is_needed boolean whether A17 should be turned on or off
263+
/// @return fapi2::FAPI2_RC_SUCCESS if okay
264+
/// @note Based off of Table 2.8 Proposed DDR4 Full spec update(79-4B) page 28
265+
///
266+
template< fapi2::TargetType T>
267+
fapi2::ReturnCode is_a17_needed(const fapi2::Target<T>& i_target,
268+
bool& o_is_needed);
269+
248270
///
249271
/// @brief Helper function to decode MRS and trace CCS instructions
250272
/// @param[in] i_data the completed MRS data to send
@@ -287,6 +309,7 @@ fapi2::ReturnCode mrs_engine( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_ta
287309
{
288310
ccs::instruction_t<T> l_inst_a_side = ccs::mrs_command<T>(i_target, i_rank, i_data.iv_mrs);
289311
ccs::instruction_t<T> l_inst_b_side;
312+
bool l_is_a17 = false;
290313

291314
// Thou shalt send 2 MRS, one for the a-side and the other inverted for the b-side.
292315
// If we're on an odd-rank then we need to mirror
@@ -299,7 +322,9 @@ fapi2::ReturnCode mrs_engine( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_ta
299322
"Failed mirroring MR%d rank %d on %s",
300323
i_data.iv_mrs, i_rank, mss::c_str(i_target) );
301324

302-
l_inst_b_side = mss::address_invert(l_inst_a_side);
325+
// So we need to see if the A17 bit is enabled. If it is we need to invert it for the CCS parity
326+
FAPI_TRY( is_a17_needed( i_target, l_is_a17) );
327+
l_inst_b_side = mss::address_invert(i_target, l_inst_a_side, l_is_a17);
303328

304329
// Not sure if we can get tricky here and only delay after the b-side MR. The question is whether the delay
305330
// is needed/assumed by the register or is purely a DRAM mandated delay. We know we can't go wrong having

src/import/chips/p9/procedures/hwp/memory/lib/dimm/eff_dimm.C

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
#include <generic/memory/lib/spd/common/ddr4/spd_decoder_ddr4.H>
4242
#include <generic/memory/lib/spd/common/rcw_settings.H>
4343
#include <lib/eff_config/timing.H>
44+
#include <lib/dimm/ddr4/mrs_load_ddr4.H>
4445
#include <lib/dimm/rank.H>
4546
#include <lib/utils/conversions.H>
4647
#include <generic/memory/lib/utils/find.H>
@@ -56,6 +57,18 @@ using fapi2::TARGET_TYPE_DIMM;
5657
using fapi2::TARGET_TYPE_MCS;
5758
using fapi2::TARGET_TYPE_MCA;
5859
using fapi2::TARGET_TYPE_MCBIST;
60+
61+
///
62+
/// @brief bit encodings for RC02
63+
/// From DDR4 Register v1.0
64+
///
65+
enum rc02_encode
66+
{
67+
A17_POS = 7,
68+
A17_ENABLE = 0,
69+
A17_DISABLE = 1
70+
};
71+
5972
///
6073
/// @brief bit encodings for Frequencies RC08
6174
/// @note valid frequency values for Nimbus systems
@@ -1062,10 +1075,15 @@ fapi2::ReturnCode eff_dimm::dimm_rc02()
10621075
{
10631076
// Retrieve MCS attribute data
10641077
uint8_t l_attrs_dimm_rc02[PORTS_PER_MCS][MAX_DIMM_PER_PORT] = {};
1078+
fapi2::buffer<uint8_t> l_temp;
1079+
1080+
bool is_a17 = false;
1081+
FAPI_TRY( is_a17_needed( iv_dimm, is_a17), "%s Failed to get a17 boolean", mss::c_str(iv_dimm) );
1082+
1083+
l_temp.writeBit<rc02_encode::A17_POS>(is_a17 ? rc02_encode::A17_ENABLE : rc02_encode::A17_DISABLE);
10651084
FAPI_TRY( eff_dimm_ddr4_rc02(iv_mcs, &l_attrs_dimm_rc02[0][0]) );
10661085

1067-
// Update MCS attribute
1068-
l_attrs_dimm_rc02[iv_port_index][iv_dimm_index] = iv_pDecoder->iv_raw_card.iv_rc02;
1086+
l_attrs_dimm_rc02[iv_port_index][iv_dimm_index] = l_temp;
10691087

10701088
FAPI_INF("%s: RC02 settting: %d", mss::c_str(iv_dimm), l_attrs_dimm_rc02[iv_port_index][iv_dimm_index] );
10711089
FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_EFF_DIMM_DDR4_RC02, iv_mcs, l_attrs_dimm_rc02) );
@@ -1359,7 +1377,15 @@ fapi2::ReturnCode eff_dimm::dimm_rc08()
13591377
// Let's set the other bits
13601378
l_buffer.writeBit<QXPAR_LOCATION>(RC08_PARITY_ENABLE);
13611379

1362-
l_buffer.writeBit<DA17_QA17_LOCATION>(DA17_QA17_ENABLE);
1380+
// Now for A17 bit
1381+
{
1382+
bool l_is_a17 = false;
1383+
1384+
FAPI_TRY( is_a17_needed( iv_dimm, l_is_a17), "%s Failed to get a17 boolean", mss::c_str(iv_dimm) );
1385+
l_buffer.writeBit<DA17_QA17_LOCATION>(l_is_a17 ? DA17_QA17_ENABLE : DA17_QA17_DISABLE);
1386+
1387+
FAPI_INF("%s Turning %s DA17", mss::c_str(iv_dimm), (l_is_a17 ? "on" : "off"));
1388+
}
13631389

13641390
FAPI_TRY( eff_dimm_ddr4_rc08(iv_mcs, &l_attrs_dimm_rc08[0][0]) );
13651391
l_attrs_dimm_rc08[iv_port_index][iv_dimm_index] = l_buffer;
@@ -4727,5 +4753,4 @@ fapi2::ReturnCode eff_dimm::phy_seq_refresh()
47274753
iv_mcs,
47284754
UINT8_VECTOR_TO_1D_ARRAY(l_phy_seq_ref_enable, PORTS_PER_MCS));
47294755
}
4730-
47314756
}//mss

src/import/chips/p9/procedures/hwp/memory/lib/phy/seq.C

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,6 @@ uint64_t exp_helper( const uint64_t i_value )
8383
return l_first_bit + (uint64_t(1 << l_first_bit) < i_value ? 1 : 0);
8484
}
8585

86-
8786
///
8887
/// @brief reset SEQ_TIMING0
8988
/// @param[in] i_target fapi2 target of the port

src/import/chips/p9/procedures/hwp/memory/lib/phy/seq.H

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
#include <p9_mc_scom_addresses_fld.H>
4242
#include <mss_attribute_accessors_manual.H>
4343
#include <generic/memory/lib/utils/scom.H>
44+
#include <lib/dimm/ddr4/mrs_load_ddr4.H>
4445

4546
namespace mss
4647
{
@@ -107,10 +108,13 @@ class seqTraits<fapi2::TARGET_TYPE_MCA>
107108
TODTLON_OFF_CYCLES = MCA_DDRPHY_SEQ_MEM_TIMING_PARAM2_P0_TODTLON_OFF_CYCLES,
108109
TODTLON_OFF_CYCLES_LEN = MCA_DDRPHY_SEQ_MEM_TIMING_PARAM2_P0_TODTLON_OFF_CYCLES_LEN,
109110

111+
PAR_A17 = MCA_DDRPHY_SEQ_CONFIG0_P0_PAR_17_MASK,
110112
DELAYED_PARITY = MCA_DDRPHY_SEQ_CONFIG0_P0_DELAYED_PAR,
111113
TWO_N_MODE = MCA_DDRPHY_SEQ_CONFIG0_P0_TWO_CYCLE_ADDR_EN,
112-
};
113114

115+
A17_IS_USED = 0b0,
116+
A17_IS_NOT_USED = 0b1,
117+
};
114118
};
115119

116120
namespace seq
@@ -400,12 +404,20 @@ fapi_try_exit:
400404
/// @return fapi2::ReturnCode FAPI2_RC_SUCCESS if ok
401405
///
402406
template< fapi2::TargetType T, typename TT = seqTraits<T> >
403-
inline fapi2::ReturnCode reset_config0( const fapi2::Target<T>& i_target )
407+
fapi2::ReturnCode reset_config0( const fapi2::Target<T>& i_target )
404408
{
405409
fapi2::buffer<uint64_t> l_data;
406410

407-
l_data.writeBit<TT::TWO_N_MODE>(mss::two_n_mode_helper(i_target));
411+
// Let's figure out if the A17 bit is on/ needed for parity calculations
412+
bool l_a17 = false;
413+
FAPI_TRY( is_a17_needed( i_target, l_a17) );
414+
415+
{
416+
const auto l_encoding = l_a17 ? TT::A17_IS_USED : TT::A17_IS_NOT_USED;
417+
l_data.writeBit<TT::PAR_A17>( l_encoding );
418+
}
408419

420+
l_data.writeBit<TT::TWO_N_MODE>(mss::two_n_mode_helper(i_target));
409421
// DDR4 needs delayed partiy TK for DDR5/DDR3 ...
410422
l_data.setBit<TT::DELAYED_PARITY>();
411423
FAPI_TRY( write_config0(i_target, l_data), "%s failed to reset seq_config0 register via write", mss::c_str(i_target) );
@@ -424,7 +436,6 @@ fapi_try_exit:
424436
template< fapi2::TargetType T, typename TT = seqTraits<T> >
425437
fapi2::ReturnCode reset_timing0( const fapi2::Target<T>& i_target );
426438

427-
428439
///
429440
/// @brief reset SEQ_TIMING1
430441
/// @tparam T fapi2 Target Type - derived

src/import/generic/memory/lib/spd/common/rcw_settings.H

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@ struct rcw_settings
5252
{
5353
uint64_t iv_rc00;
5454
uint64_t iv_rc01;
55-
uint64_t iv_rc02;
5655
uint64_t iv_rc06_07;
5756
uint64_t iv_rc09;
5857
uint64_t iv_rc0b;
@@ -98,7 +97,6 @@ struct rcw_settings
9897
/// @brief ctor
9998
/// @param[in] i_rc00 setting for register control word (RC00)
10099
/// @param[in] i_rc01 setting for register control word (RC01)
101-
/// @param[in] i_rc02 setting for register control word (RC02)
102100
/// @param[in] i_rc06_07 setting for register control word (RCO6 & RC07)
103101
/// @param[in] i_rc09 setting for register control word (RC09)
104102
/// @param[in] i_rc0b setting for register control word (RC0B)
@@ -115,7 +113,6 @@ struct rcw_settings
115113
///
116114
constexpr rcw_settings( const uint64_t i_rc00,
117115
const uint64_t i_rc01,
118-
const uint64_t i_rc02,
119116
const uint64_t i_rc06_07,
120117
const uint64_t i_rc09,
121118
const uint64_t i_rc0b,
@@ -131,7 +128,6 @@ struct rcw_settings
131128
const uint64_t i_rcax)
132129
: iv_rc00(i_rc00),
133130
iv_rc01(i_rc01),
134-
iv_rc02(i_rc02),
135131
iv_rc06_07(i_rc06_07),
136132
iv_rc09(i_rc09),
137133
iv_rc0b(i_rc0b),

src/import/generic/memory/lib/spd/lrdimm/ddr4/lrdimm_raw_cards.C

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@ namespace mss
5252
// TODO RTC:160116 Fill in valid RCD data for LRDIMM
5353
rcw_settings lrdimm_rc_b0( 0x00, // RC00
5454
0x00, // RC01 (C might be the right answer)
55-
0x00, // RC02
5655
0x1F, // RC06_7
5756
0x00, // RC09
5857
0x0E, // RC0B

src/import/generic/memory/lib/spd/rdimm/ddr4/rdimm_raw_cards.C

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ namespace mss
5151
///
5252
rcw_settings rdimm_rc_c1( 0x02, // RC00
5353
0x0C, // RC01
54-
0x00, // RC02
5554
0x0F, // RC06_07
5655
0x0C, // RC09
5756
0x0E, // RC0B
@@ -72,7 +71,6 @@ rcw_settings rdimm_rc_c1( 0x02, // RC00
7271
///
7372
rcw_settings rdimm_rc_c2( 0x02, // RC00
7473
0x0C, // RC01
75-
0x00, // RC02
7674
0x0F, // RC06_07
7775
0x0C, // RC09
7876
0x0E, // RC0B
@@ -92,7 +90,6 @@ rcw_settings rdimm_rc_c2( 0x02, // RC00
9290
///
9391
rcw_settings rdimm_rc_a1( 0x02, // RC00
9492
0x00, // RC01
95-
0x00, // RC02
9693
0x0F, // RC06_07
9794
0x0C, // RC09
9895
0x0E, // RC0B
@@ -113,7 +110,6 @@ rcw_settings rdimm_rc_a1( 0x02, // RC00
113110
///
114111
rcw_settings rdimm_rc_b1( 0x02, // RC00
115112
0x00, // RC01
116-
0x00, // RC02
117113
0x0F, // RC06_07
118114
0x0C, // RC09 Could be set in eff_config for CKE power DOWN mode
119115
0x0E, // RC0B
@@ -134,7 +130,6 @@ rcw_settings rdimm_rc_b1( 0x02, // RC00
134130
///
135131
rcw_settings rdimm_rc_b2( 0x02, // RC00
136132
0x00, // RC01
137-
0x00, // RC02
138133
0x0F, // RC06_07
139134
0x0C, // RC09
140135
0x0E, // RC0B
@@ -155,7 +150,6 @@ rcw_settings rdimm_rc_b2( 0x02, // RC00
155150
///
156151
rcw_settings rdimm_rc_custom ( 0x02, // RC00
157152
0x00, // RC01
158-
0x00, // RC02
159153
0x0F, // RC06_07
160154
0x0C, // RC09
161155
0x0E, // RC0B
@@ -176,7 +170,6 @@ rcw_settings rdimm_rc_custom ( 0x02, // RC00
176170
///
177171
rcw_settings rdimm_rc_vbu( 0x02, // RC00
178172
0x00, // RC01
179-
0x00, // RC02
180173
0x0F, // RC06_07
181174
0x0C, // RC09
182175
0x0E, // RC0B

0 commit comments

Comments
 (0)