8 #define CxRECy_MCHBAR(x, y) (0x14a0 + ((x) * 0x0100) + ((3 - (y)) * 4))
9 #define CxRECy_SHIFT_L 0
10 #define CxRECy_MASK_L (3 << CxRECy_SHIFT_L)
11 #define CxRECy_SHIFT_H 16
12 #define CxRECy_MASK_H (3 << CxRECy_SHIFT_H)
13 #define CxRECy_T_SHIFT 28
14 #define CxRECy_T_MASK (0xf << CxRECy_T_SHIFT)
15 #define CxRECy_T(t) (((t) << CxRECy_T_SHIFT) & CxRECy_T_MASK)
16 #define CxRECy_P_SHIFT 24
17 #define CxRECy_P_MASK (0x7 << CxRECy_P_SHIFT)
18 #define CxRECy_P(p) (((p) << CxRECy_P_SHIFT) & CxRECy_P_MASK)
19 #define CxRECy_PH_SHIFT 22
20 #define CxRECy_PH_MASK (0x3 << CxRECy_PH_SHIFT)
21 #define CxRECy_PH(p) (((p) << CxRECy_PH_SHIFT) & CxRECy_PH_MASK)
22 #define CxRECy_PM_SHIFT 20
23 #define CxRECy_PM_MASK (0x3 << CxRECy_PM_SHIFT)
24 #define CxRECy_PM(p) (((p) << CxRECy_PM_SHIFT) & CxRECy_PM_MASK)
25 #define CxRECy_TIMING_MASK (CxRECy_T_MASK | CxRECy_P_MASK | \
26 CxRECy_PH_MASK | CxRECy_PM_MASK)
28 #define CxDRT3_C_SHIFT 7
29 #define CxDRT3_C_MASK (0xf << CxDRT3_C_SHIFT)
30 #define CxDRT3_C(c) (((c) << CxDRT3_C_SHIFT) & CxDRT3_C_MASK)
33 { { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 } },
34 { { 0, 2 }, { 1, 3 }, { 4, 6 }, { 5, 7 } },
52 while (timing->
p >= timing->
p_bound) {
56 while (timing->
p < 0) {
60 while (timing->
t >= timing->
t_bound) {
64 while (timing->
t < 0) {
72 while (timing->
ph < 0) {
76 if (timing->
c < 0 || timing->
c >=
C_BOUND)
77 die(
"Timing under-/overflow during "
78 "receive-enable calibration.\n");
126 unsigned int mchbar = 0x14f0 + (channel * 0x0100);
133 mchbar = 0x14b0 + (channel * 0x0100) + ((7 - lane) * 4);
159 const char lane_map[][2])
162 timings[channel][group].t += 2;
192 static const char over_bytelane_map[2][4][2] = {
193 { { 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 } },
194 { { 0, 0 }, { 3, 3 }, { 6, 6 }, { 5, 5 } },
197 const int cardF[] = {
202 const unsigned int t_bound =
204 const unsigned int p_bound =
209 {
timings->
CAS + 1, 0, 0, 0, t_bound, 0, p_bound },
210 {
timings->
CAS + 1, 0, 0, 0, t_bound, 0, p_bound },
211 {
timings->
CAS + 1, 0, 0, 0, t_bound, 0, p_bound },
212 {
timings->
CAS + 1, 0, 0, 0, t_bound, 0, p_bound }
214 {
timings->
CAS + 1, 0, 0, 0, t_bound, 0, p_bound },
215 {
timings->
CAS + 1, 0, 0, 0, t_bound, 0, p_bound },
216 {
timings->
CAS + 1, 0, 0, 0, t_bound, 0, p_bound },
217 {
timings->
CAS + 1, 0, 0, 0, t_bound, 0, p_bound }
223 const char (*
const map)[2] = over_bytelane_map[cardF[
ch]];
224 for (group = 0; group < 4; ++group) {
236 rec_timings[
ch][group].
t++;
241 for (group = 0; group < 4; ++group) {
242 if (rec_timings[
ch][group].
c < c_min)
243 c_min = rec_timings[
ch][group].
c;
245 for (group = 0; group < 4; ++group) {
246 rec_timings[
ch][group].
pre =
247 rec_timings[
ch][group].
c - c_min;
248 rec_timings[
ch][group].
c = c_min;
253 rec_timings[
ch][group].
c,
254 rec_timings[
ch][group].pre,
255 rec_timings[
ch][group].ph,
256 rec_timings[
ch][group].t,
257 rec_timings[
ch][group].p);
269 const char (*
const map)[2] =
272 for (group = 0; group < 4; ++group) {
275 reg &= ~((3 << 16) | (1 << 8) | 3);
276 reg |= (map[group][0] - group);
277 reg |= (map[group][1] - group - 1) << 16;
static uint32_t read32(const void *addr)
#define printk(level,...)
void __noreturn die(const char *fmt,...)
#define mchbar_setbits32(addr, set)
static __always_inline void mchbar_write32(const uintptr_t offset, const uint32_t value)
static __always_inline void mchbar_clrsetbits32(uintptr_t offset, uint32_t clear, uint32_t set)
static __always_inline uint32_t mchbar_read32(const uintptr_t offset)
#define mchbar_clrbits32(addr, clear)
#define FOR_EACH_POPULATED_CHANNEL(dimms, idx)
void raminit_reset_readwrite_pointers(void)
u32 raminit_get_rank_addr(unsigned int channel, unsigned int rank)
#define BIOS_DEBUG
BIOS_DEBUG - Verbose output.
static struct dramc_channel const ch[2]
static const char bytelane_map[2][4][2]
static void rec_quarter_backstep(rec_timing_t *const timing)
static void rec_quarter_step(rec_timing_t *const timing)
void raminit_receive_enable_calibration(const timings_t *const timings, const dimminfo_t *const dimms)
static void find_dqs_high(const int channel, const int group, rec_timing_t timings[][4], const char lane_map[][2])
#define CxRECy_MCHBAR(x, y)
static int read_dqs_level(const int channel, const int lane)
static void normalize_rec_timing(rec_timing_t *const timing)
static void find_preamble(const int channel, const int group, rec_timing_t timings[][4], const char lane_map[][2])
static void program_timing(int channel, int group, rec_timing_t timings[][4])
static void receive_enable_calibration(const timings_t *const timings, const dimminfo_t *const dimms)
#define CxRECy_TIMING_MASK
static void find_dqs_low(const int channel, const int group, rec_timing_t timings[][4], const char lane_map[][2])
static void find_dqs_edge_lowhigh(const int channel, const int group, rec_timing_t timings[][4], const char lane_map[][2])
static void rec_full_backstep(rec_timing_t *const timing)
static void rec_half_backstep(rec_timing_t *const timing)
static void rec_smallest_step(rec_timing_t *const timing)
#define c(value, pmcreg, dst_bits)