35
35
36
36
#include <fapi2.H>
37
37
#include <lib/phy/adr32s.H>
38
+ #include <lib/workarounds/adr32s_workarounds.H>
38
39
#include <lib/utils/find.H>
39
40
40
41
using fapi2 ::TARGET_TYPE_MCA ;
@@ -63,16 +64,6 @@ const std::vector<uint64_t> adr32sTraits<fapi2::TARGET_TYPE_MCA>::DUTY_CYCLE_DIS
63
64
{
64
65
MCA_DDRPHY_ADR_DCD_CONTROL_P0_ADR32S0 ,
65
66
MCA_DDRPHY_ADR_DCD_CONTROL_P0_ADR32S1 ,
66
- MCA_DDRPHY_DP16_DCD_CONTROL0_P0_0 ,
67
- MCA_DDRPHY_DP16_DCD_CONTROL1_P0_0 ,
68
- MCA_DDRPHY_DP16_DCD_CONTROL0_P0_1 ,
69
- MCA_DDRPHY_DP16_DCD_CONTROL1_P0_1 ,
70
- MCA_DDRPHY_DP16_DCD_CONTROL0_P0_2 ,
71
- MCA_DDRPHY_DP16_DCD_CONTROL1_P0_2 ,
72
- MCA_DDRPHY_DP16_DCD_CONTROL0_P0_3 ,
73
- MCA_DDRPHY_DP16_DCD_CONTROL1_P0_3 ,
74
- MCA_DDRPHY_DP16_DCD_CONTROL0_P0_4 ,
75
- MCA_DDRPHY_DP16_DCD_CONTROL1_P0_4 ,
76
67
};
77
68
78
69
// Definition of the ADR32S write clock static offset registers
@@ -85,122 +76,6 @@ const std::vector<uint64_t> adr32sTraits<fapi2::TARGET_TYPE_MCA>::PR_STATIC_OFFS
85
76
namespace adr32s
86
77
{
87
78
88
- ///
89
- /// @brief Helper to iterate over ADR32S 'sides' when performing DCD cal
90
- /// @param[in] i_target the MCA to iterate for
91
- /// @param[in] i_reg the register (ADR0 or ADR1's register)
92
- /// @param[in] i_seed the seed value for the adjuster
93
- /// @param[in] i_side bool; true if this is side a, false for side b
94
- /// @param[out] o_value the value of the adjuster when the compare bit changes state
95
- /// @return FAPI2_RC_SUCCESS iff ok
96
- ///
97
- fapi2 ::ReturnCode dcd_cal_helper ( const fapi2 ::Target < TARGET_TYPE_MCA > & i_target ,
98
- const uint64_t i_reg ,
99
- const uint64_t i_seed ,
100
- const bool i_side ,
101
- uint64_t & o_value )
102
- {
103
- typedef adr32sTraits < TARGET_TYPE_MCA > TT ;
104
-
105
- constexpr uint64_t l_dcd_adjust_overflow = 0b1111111 ;
106
- constexpr uint64_t l_dcd_adjust_underflow = 0b0000000 ;
107
-
108
- // If compare out is 0, we tick up ...
109
- // Signed value which helps us increment or decrement the adjustment
110
- int64_t l_tick = 1 ;
111
- // ... and we expect a transition to 1
112
- bool l_expected = 1 ;
113
- // ... and we don't expect to overflow
114
- uint64_t l_overrun = l_dcd_adjust_overflow ;
115
-
116
- fapi2 ::buffer < uint64_t > l_read ;
117
- uint64_t l_current_adjust = i_seed ;
118
- size_t l_iter = 0 ;
119
-
120
- // More or less mirror's Bialas's logic for DD2 so we can kind of try out the algorithm on DD1.
121
-
122
- FAPI_INF ("enter dcd_cal_helper %s 0x%016lx seed: 0x%016lx side: %d" ,
123
- mss ::c_str (i_target ), i_reg , i_seed , i_side );
124
-
125
- // Prime the system with the starting values. We don't need to read/modify/write here as we're resetting
126
- // the world and saving a scom here is likely benificial. Clear the compare out bit as writing it set
127
- // will cause the PHY to throw a parity error
128
- l_read .insertFromRight < TT ::DCD_CONTROL_DLL_ADJUST , TT ::DCD_CONTROL_DLL_ADJUST_LEN > (l_current_adjust );
129
- l_read .writeBit < TT ::DCD_CONTROL_DLL_ITER_A > (i_side );
130
- l_read .clearBit < TT ::DCD_CONTROL_DLL_COMPARE_OUT > ( );
131
- FAPI_TRY ( mss ::putScom (i_target , i_reg , l_read ) );
132
-
133
- // Algorithm waits 128ck (~100ns) between steps. However, scom takes so long (and rippling up thru
134
- // the platforms takes time too) that there's no need to actually delay - plenty of time has elapsed.
135
-
136
- // Read. Note the register is volatile in that l_read which we just wrote isn't what we'll read
137
- // as the distortion logic will take the seeded adjustment value and give us information on the next
138
- // read (so don't get cute and remove this getScom.)
139
- FAPI_TRY ( mss ::getScom (i_target , i_reg , l_read ) );
140
-
141
- // Based on the 'direction' we're going, we have some values to setup. We setup the bit == 0 case
142
- // when we initialized these variables above.
143
- if (l_read .getBit < TT ::DCD_CONTROL_DLL_COMPARE_OUT > ( ) != 0 )
144
- {
145
- // If compare out is 1, we tick down ...
146
- l_tick = -1 ;
147
-
148
- // ... and we expect a transition to 0
149
- l_expected = 0 ;
150
-
151
- // ... and we don't expect to underflow
152
- l_overrun = l_dcd_adjust_underflow ;
153
- }
154
-
155
- do
156
- {
157
- l_iter += 1 ;
158
- bool l_current_compare = l_read .getBit < TT ::DCD_CONTROL_DLL_COMPARE_OUT > ( );
159
-
160
- FAPI_INF ("dcd_cal_helper: iter %d tick: %d expected: %d overrun: 0x%x out: %d adj: 0x%x" ,
161
- l_iter , l_tick , l_expected , l_overrun , l_current_compare , l_current_adjust );
162
-
163
- if (l_current_compare == l_expected )
164
- {
165
- break ;
166
- }
167
-
168
- // If we're here we're not done, so just adjust and try again. Clear the compare out bit, it must
169
- // always be 0 or the PHY will parity error
170
- l_read .insertFromRight < TT ::DCD_CONTROL_DLL_ADJUST , TT ::DCD_CONTROL_DLL_ADJUST_LEN > (l_current_adjust + l_tick );
171
- l_read .clearBit < TT ::DCD_CONTROL_DLL_COMPARE_OUT > ( );
172
- FAPI_TRY ( mss ::putScom (i_target , i_reg , l_read ) );
173
-
174
- // Wait 128ck (~100ns) ...
175
-
176
- FAPI_TRY ( mss ::getScom (i_target , i_reg , l_read ) );
177
-
178
- l_read .extractToRight < TT ::DCD_CONTROL_DLL_ADJUST , TT ::DCD_CONTROL_DLL_ADJUST_LEN > (l_current_adjust );
179
-
180
- }
181
- while (l_current_adjust != l_overrun );
182
-
183
- FAPI_ASSERT ( l_current_adjust != l_overrun ,
184
- fapi2 ::MSS_DUTY_CLOCK_DISTORTION_CAL_FAILED ()
185
- .set_TARGET (i_target )
186
- .set_CURRENT_ADJUST (l_current_adjust )
187
- .set_SIDE (i_side )
188
- .set_REGISTER (i_reg )
189
- .set_REGISTER_VALUE (l_read ),
190
- "Failed ADR DCD for %s 0x%016lx" , mss ::c_str (i_target ), i_reg );
191
-
192
- // If we're here, we were done and there were no errors. So we can return back the current adjust value
193
- // as the output/result of our operation
194
- o_value = l_current_adjust ;
195
- FAPI_INF ("side: %d final adjust value: 0x%x (0x%x)" , i_side , o_value , l_current_adjust );
196
-
197
- return FAPI2_RC_SUCCESS ;
198
-
199
- fapi_try_exit :
200
- return fapi2 ::current_err ;
201
- }
202
-
203
-
204
79
///
205
80
/// @brief Perform ADR DCD calibration - Nimbus Only
206
81
/// @param[in] i_target the MCBIST (controler) to perform calibration on
@@ -240,34 +115,9 @@ fapi2::ReturnCode duty_cycle_distortion_calibration( const fapi2::Target<fapi2::
240
115
fapi2 ::Assert (false);
241
116
}
242
117
243
- // We must calibrate each of our ports. Each has 2 ADR units and each unit needs it's A-side and B-side calibrated.
244
- for (const auto& p : mss ::find_targets < TARGET_TYPE_MCA > (i_target ))
245
- {
246
- uint64_t l_seed = TT ::DCD_ADJUST_DEFAULT ;
247
-
248
- for (const auto & r : TT ::DUTY_CYCLE_DISTORTION_REG )
249
- {
250
- uint64_t l_a_side_value = 0 ;
251
- uint64_t l_b_side_value = 0 ;
252
-
253
- FAPI_TRY ( dcd_cal_helper (p , r , l_seed , true, l_a_side_value ) );
254
-
255
- // We want to seed the other side (and each subsequent port) with the
256
- // value found in the pervious iteration as that will likely reduce the number
257
- // of iterations to find the transition. We back up one so that if we're on
258
- // a transition, we don't 'bounce' from a 1 to a 0. This will give us a good
259
- // transition if the a-side value is really to be the b-side value too.
260
- FAPI_TRY ( dcd_cal_helper (p , r , l_a_side_value - 1 , false, l_b_side_value ) );
261
-
262
- // The final value is the average of the a-side and b-side values.
263
- l_seed = (l_a_side_value + l_b_side_value ) / 2 ;
264
-
265
- FAPI_INF ("average for both sides 0x%02x" , l_seed );
266
-
267
- // Note this writes all the other values to 0's which is OK for DD1
268
- FAPI_TRY ( mss ::putScom (p , r , l_seed ) );
269
- }
270
- }
118
+ // Runs the DD1 algorithm for now. The below TODO is to add in a switch to the DD2 algorithm
119
+ // TODO RTC:159687 For DD2 all we need to do is kick off the h/w cal and wait. We can check any ADR_DCD
120
+ FAPI_TRY (mss ::workarounds ::adr32s ::duty_cycle_distortion_calibration (i_target ));
271
121
272
122
fapi_try_exit :
273
123
return fapi2 ::current_err ;
0 commit comments