2 * This file is part of the coreboot project.
4 * Copyright (C) 2013 Vladimir Serbinenko.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
17 /* Please don't remove this. It's needed it to do debugging
18 and reverse engineering to support in futur more nehalem variants. */
25 #include <console/console.h>
28 #include <cpu/x86/msr.h>
30 #include <arch/cbfs.h>
32 #include <ip_checksum.h>
33 #include <pc80/mc146818rtc.h>
34 #include <device/pci_def.h>
39 #include <timestamp.h>
40 #include <cpu/x86/mtrr.h>
41 #include <cpu/intel/speedstep.h>
42 #include <cpu/intel/turbo.h>
46 typedef unsigned char u8
;
47 typedef unsigned short u16
;
48 typedef unsigned int u32
;
54 #include "southbridge/intel/ibexpeak/me.h"
60 #define NORTHBRIDGE PCI_DEV(0, 0, 0)
61 #define SOUTHBRIDGE PCI_DEV(0, 0x1f, 0)
62 #define GMA PCI_DEV (0, 0x2, 0x0)
63 #define HECIDEV PCI_DEV(0, 0x16, 0)
66 #define FOR_ALL_RANKS \
67 for (channel = 0; channel < NUM_CHANNELS; channel++) \
68 for (slot = 0; slot < NUM_SLOTS; slot++) \
69 for (rank = 0; rank < NUM_RANKS; rank++)
71 #define FOR_POPULATED_RANKS \
72 for (channel = 0; channel < NUM_CHANNELS; channel++) \
73 for (slot = 0; slot < NUM_SLOTS; slot++) \
74 for (rank = 0; rank < NUM_RANKS; rank++) \
75 if (info->populated_ranks[channel][slot][rank])
77 #define FOR_POPULATED_RANKS_BACKWARDS \
78 for (channel = NUM_CHANNELS - 1; channel >= 0; channel--) \
79 for (slot = 0; slot < NUM_SLOTS; slot++) \
80 for (rank = 0; rank < NUM_RANKS; rank++) \
81 if (info->populated_ranks[channel][slot][rank])
83 /* [REG_178][CHANNEL][2 * SLOT + RANK][LANE] */
87 } timing_bounds_t
[2][2][2][9];
90 /* [TM][CHANNEL][SLOT][RANK][LANE] */
91 u16 lane_timings
[4][2][2][2][9];
98 timing_bounds_t timing_bounds
[2];
99 u16 timing_offset
[2][2][2][9];
100 u16 timing2_offset
[2][2][2][9];
101 u16 timing2_bounds
[2][2][2][9][2];
102 u8 reg274265
[2][3]; /* [CHANNEL][REGISTER] */
109 #include "raminit_fake.c"
112 #include <lib.h> /* Prototypes */
114 static inline void write_mchbar32(u32 addr
, u32 val
)
116 MCHBAR32(addr
) = val
;
119 static inline void write_mchbar16(u32 addr
, u16 val
)
121 MCHBAR16(addr
) = val
;
124 static inline void write_mchbar8(u32 addr
, u8 val
)
130 static inline u32
read_mchbar32(u32 addr
)
132 return MCHBAR32(addr
);
135 static inline u16
read_mchbar16(u32 addr
)
137 return MCHBAR16(addr
);
140 static inline u8
read_mchbar8(u32 addr
)
142 return MCHBAR8(addr
);
145 static void clflush(u32 addr
)
147 asm volatile ("clflush (%0)"::"r" (addr
));
150 typedef struct _u128
{
155 static void read128(u32 addr
, u64
* out
)
159 asm volatile ("movdqu %%xmm0, %0\n"
160 "movdqa (%2), %%xmm0\n"
161 "movdqu %%xmm0, %1\n"
162 "movdqu %0, %%xmm0":"+m" (stor
), "=m"(ret
):"r"(addr
));
170 static void write_1d0(u32 val
, u16 addr
, int bits
, int flag
)
172 write_mchbar32(0x1d0, 0);
173 while (read_mchbar32(0x1d0) & 0x800000) ;
174 write_mchbar32(0x1d4,
175 (val
& ((1 << bits
) - 1)) | (2 << bits
) | (flag
<<
177 write_mchbar32(0x1d0, 0x40000000 | addr
);
178 while (read_mchbar32(0x1d0) & 0x800000) ;
182 static u16
read_1d0(u16 addr
, int split
)
185 write_mchbar32(0x1d0, 0);
186 while (read_mchbar32(0x1d0) & 0x800000) ;
187 write_mchbar32(0x1d0,
188 0x80000000 | (((read_mchbar8(0x246) >> 2) & 3) +
190 while (read_mchbar32(0x1d0) & 0x800000) ;
191 val
= read_mchbar32(0x1d8);
192 write_1d0(0, 0x33d, 0, 0);
193 write_1d0(0, 0x33d, 0, 0);
194 val
&= ((1 << split
) - 1);
195 // printk (BIOS_ERR, "R1D0C [%x] => %x\n", addr, val);
199 static void write32p(uintptr_t addr
, uint32_t val
)
201 write32((void *)addr
, val
);
204 static uint32_t read32p(uintptr_t addr
)
206 return read32((void *)addr
);
209 static void sfence(void)
212 asm volatile ("sfence");
216 static inline u16
get_lane_offset(int slot
, int rank
, int lane
)
218 return 0x124 * lane
+ ((lane
& 4) ? 0x23e : 0) + 11 * rank
+ 22 * slot
-
222 static inline u16
get_timing_register_addr(int lane
, int tm
, int slot
, int rank
)
224 const u16 offs
[] = { 0x1d, 0xa8, 0xe6, 0x5c };
225 return get_lane_offset(slot
, rank
, lane
) + offs
[(tm
+ 3) % 4];
229 static u32
gav_real(int line
, u32 in
)
231 // printk (BIOS_DEBUG, "%d: GAV: %x\n", line, in);
235 #define gav(x) gav_real (__LINE__, (x))
238 u16 clock_speed_index
; /* clock_speed (REAL, not DDR) / 133.(3) - 3 */
239 u16 fsb_frequency
; /* in 1.(1)/2 MHz. */
240 u8 is_x16_module
[2][2]; /* [CHANNEL][SLOT] */
241 u8 density
[2][2]; /* [CHANNEL][SLOT] */
242 u8 populated_ranks
[2][2][2]; /* [CHANNEL][SLOT][RANK] */
243 int rank_start
[2][2][2];
245 u8 board_lane_delay
[9];
248 u8 max_supported_clock_speed_index
;
250 u8 spd
[2][2][151]; /* [CHANNEL][SLOT][BYTE] */
252 u8 populated_ranks_mask
[2];
253 u8 max_slots_used_in_channel
;
257 unsigned total_memory_mb
;
258 unsigned interleaved_part_mb
;
259 unsigned non_interleaved_part_mb
;
263 unsigned memory_reserved_for_heci_mb
;
265 struct ram_training training
;
266 u32 last_500_command
[2];
271 u8 some_delay_1_cycle_floor
;
272 u8 some_delay_2_halfcycles_ceil
;
273 u8 some_delay_3_ps_rounded
;
275 const struct ram_training
*cached_training
;
279 write_500(struct raminfo
*info
, int channel
, u32 val
, u16 addr
, int bits
,
284 read_500(struct raminfo
*info
, int channel
, u16 addr
, int split
)
287 info
->last_500_command
[channel
] = 0x80000000;
288 write_mchbar32(0x500 + (channel
<< 10), 0);
289 while (read_mchbar32(0x500 + (channel
<< 10)) & 0x800000) ;
290 write_mchbar32(0x500 + (channel
<< 10),
292 (((read_mchbar8(0x246 + (channel
<< 10)) >> 2) &
294 while (read_mchbar32(0x500 + (channel
<< 10)) & 0x800000) ;
295 val
= read_mchbar32(0x508 + (channel
<< 10));
296 return val
& ((1 << split
) - 1);
301 write_500(struct raminfo
*info
, int channel
, u32 val
, u16 addr
, int bits
,
304 if (info
->last_500_command
[channel
] == 0x80000000) {
305 info
->last_500_command
[channel
] = 0x40000000;
306 write_500(info
, channel
, 0, 0xb61, 0, 0);
308 write_mchbar32(0x500 + (channel
<< 10), 0);
309 while (read_mchbar32(0x500 + (channel
<< 10)) & 0x800000) ;
310 write_mchbar32(0x504 + (channel
<< 10),
311 (val
& ((1 << bits
) - 1)) | (2 << bits
) | (flag
<<
313 write_mchbar32(0x500 + (channel
<< 10), 0x40000000 | addr
);
314 while (read_mchbar32(0x500 + (channel
<< 10)) & 0x800000) ;
317 static int rw_test(int rank
)
319 const u32 mask
= 0xf00fc33c;
322 for (i
= 0; i
< 64; i
++)
323 write32p((rank
<< 28) | (i
<< 2), 0);
325 for (i
= 0; i
< 64; i
++)
326 gav(read32p((rank
<< 28) | (i
<< 2)));
328 for (i
= 0; i
< 32; i
++) {
329 u32 pat
= (((mask
>> i
) & 1) ? 0xffffffff : 0);
330 write32p((rank
<< 28) | (i
<< 3), pat
);
331 write32p((rank
<< 28) | (i
<< 3) | 4, pat
);
334 for (i
= 0; i
< 32; i
++) {
335 u8 pat
= (((mask
>> i
) & 1) ? 0xff : 0);
338 gav(val
= read32p((rank
<< 28) | (i
<< 3)));
339 for (j
= 0; j
< 4; j
++)
340 if (((val
>> (j
* 8)) & 0xff) != pat
)
342 gav(val
= read32p((rank
<< 28) | (i
<< 3) | 4));
343 for (j
= 0; j
< 4; j
++)
344 if (((val
>> (j
* 8)) & 0xff) != pat
)
348 for (i
= 0; i
< 64; i
++)
349 write32p((rank
<< 28) | (i
<< 2), 0);
351 for (i
= 0; i
< 64; i
++)
352 gav(read32p((rank
<< 28) | (i
<< 2)));
358 program_timings(struct raminfo
*info
, u16 base
, int channel
, int slot
, int rank
)
361 for (lane
= 0; lane
< 8; lane
++) {
362 write_500(info
, channel
,
365 lane_timings
[2][channel
][slot
][rank
][lane
],
366 get_timing_register_addr(lane
, 2, slot
, rank
), 9, 0);
367 write_500(info
, channel
,
370 lane_timings
[3][channel
][slot
][rank
][lane
],
371 get_timing_register_addr(lane
, 3, slot
, rank
), 9, 0);
375 static void write_26c(int channel
, u16 si
)
377 write_mchbar32(0x26c + (channel
<< 10), 0x03243f35);
378 write_mchbar32(0x268 + (channel
<< 10), 0xcfc00000 | (si
<< 9));
379 write_mchbar16(0x2b9 + (channel
<< 10), si
);
382 static u32
get_580(int channel
, u8 addr
)
385 gav(read_1d0(0x142, 3));
386 write_mchbar8(0x5ff, 0x0); /* OK */
387 write_mchbar8(0x5ff, 0x80); /* OK */
388 write_mchbar32(0x580 + (channel
<< 10), 0x8493c012 | addr
);
389 write_mchbar8(0x580 + (channel
<< 10),
390 read_mchbar8(0x580 + (channel
<< 10)) | 1);
391 while (!((ret
= read_mchbar32(0x580 + (channel
<< 10))) & 0x10000)) ;
392 write_mchbar8(0x580 + (channel
<< 10),
393 read_mchbar8(0x580 + (channel
<< 10)) & ~1);
397 const int cached_config
= 0;
399 #define NUM_CHANNELS 2
402 #define RANK_SHIFT 28
403 #define CHANNEL_SHIFT 10
405 #include "raminit_tables.c"
407 static void seq9(struct raminfo
*info
, int channel
, int slot
, int rank
)
411 for (i
= 0; i
< 2; i
++)
412 for (lane
= 0; lane
< 8; lane
++)
413 write_500(info
, channel
,
414 info
->training
.lane_timings
[i
+
416 [rank
][lane
], get_timing_register_addr(lane
,
422 write_1d0(1, 0x103, 6, 1);
423 for (lane
= 0; lane
< 8; lane
++)
424 write_500(info
, channel
,
426 lane_timings
[0][channel
][slot
][rank
][lane
],
427 get_timing_register_addr(lane
, 0, slot
, rank
), 9, 0);
429 for (i
= 0; i
< 2; i
++) {
430 for (lane
= 0; lane
< 8; lane
++)
431 write_500(info
, channel
,
432 info
->training
.lane_timings
[i
+
434 [rank
][lane
], get_timing_register_addr(lane
,
439 gav(get_580(channel
, ((i
+ 1) << 2) | (rank
<< 5)));
442 gav(read_1d0(0x142, 3)); // = 0x10408118
443 write_mchbar8(0x5ff, 0x0); /* OK */
444 write_mchbar8(0x5ff, 0x80); /* OK */
445 write_1d0(0x2, 0x142, 3, 1);
446 for (lane
= 0; lane
< 8; lane
++) {
447 // printk (BIOS_ERR, "before: %x\n", info->training.lane_timings[2][channel][slot][rank][lane]);
448 info
->training
.lane_timings
[2][channel
][slot
][rank
][lane
] =
449 read_500(info
, channel
,
450 get_timing_register_addr(lane
, 2, slot
, rank
), 9);
451 //printk (BIOS_ERR, "after: %x\n", info->training.lane_timings[2][channel][slot][rank][lane]);
452 info
->training
.lane_timings
[3][channel
][slot
][rank
][lane
] =
453 info
->training
.lane_timings
[2][channel
][slot
][rank
][lane
] +
458 static int count_ranks_in_channel(struct raminfo
*info
, int channel
)
462 for (slot
= 0; slot
< NUM_SLOTS
; slot
++)
463 for (rank
= 0; rank
< NUM_SLOTS
; rank
++)
464 res
+= info
->populated_ranks
[channel
][slot
][rank
];
469 config_rank(struct raminfo
*info
, int s3resume
, int channel
, int slot
, int rank
)
473 write_1d0(0, 0x178, 7, 1);
474 seq9(info
, channel
, slot
, rank
);
475 program_timings(info
, 0x80, channel
, slot
, rank
);
478 add
= count_ranks_in_channel(info
, 1);
482 gav(rw_test(rank
+ add
));
483 program_timings(info
, 0x00, channel
, slot
, rank
);
485 gav(rw_test(rank
+ add
));
487 gav(rw_test(rank
+ add
));
488 write_1d0(0, 0x142, 3, 1);
489 write_1d0(0, 0x103, 6, 1);
491 gav(get_580(channel
, 0xc | (rank
<< 5)));
492 gav(read_1d0(0x142, 3));
494 write_mchbar8(0x5ff, 0x0); /* OK */
495 write_mchbar8(0x5ff, 0x80); /* OK */
498 static void set_4cf(struct raminfo
*info
, int channel
, u8 val
)
500 gav(read_500(info
, channel
, 0x4cf, 4)); // = 0xc2300cf9
501 write_500(info
, channel
, val
, 0x4cf, 4, 1);
502 gav(read_500(info
, channel
, 0x659, 4)); // = 0x80300839
503 write_500(info
, channel
, val
, 0x659, 4, 1);
504 gav(read_500(info
, channel
, 0x697, 4)); // = 0x80300839
505 write_500(info
, channel
, val
, 0x697, 4, 1);
508 static void set_334(int zero
)
511 const u32 val3
[] = { 0x2a2b2a2b, 0x26272627, 0x2e2f2e2f, 0x2a2b };
514 for (channel
= 0; channel
< NUM_CHANNELS
; channel
++) {
515 for (j
= 0; j
< 4; j
++) {
516 u32 a
= (j
== 1) ? 0x29292929 : 0x31313131;
517 u32 lmask
= (j
== 3) ? 0xffff : 0xffffffff;
519 if ((j
== 0 || j
== 3) && zero
)
526 for (k
= 0; k
< 2; k
++) {
527 write_mchbar32(0x138 + 8 * k
,
528 (channel
<< 26) | (j
<< 24));
529 gav(vd8
[1][(channel
<< 3) | (j
<< 1) | k
] =
530 read_mchbar32(0x138 + 8 * k
));
531 gav(vd8
[0][(channel
<< 3) | (j
<< 1) | k
] =
532 read_mchbar32(0x13c + 8 * k
));
535 write_mchbar32(0x334 + (channel
<< 10) + (j
* 0x44),
537 write_mchbar32(0x32c + (channel
<< 10) + (j
* 0x44),
538 zero
? 0 : (0x18191819 & lmask
));
539 write_mchbar16(0x34a + (channel
<< 10) + (j
* 0x44), c
);
540 write_mchbar32(0x33c + (channel
<< 10) + (j
* 0x44),
541 zero
? 0 : (a
& lmask
));
542 write_mchbar32(0x344 + (channel
<< 10) + (j
* 0x44),
543 zero
? 0 : (a
& lmask
));
547 write_mchbar32(0x130, read_mchbar32(0x130) | 1); /* OK */
548 while (read_mchbar8(0x130) & 1) ; /* OK */
551 static void rmw_1d0(u16 addr
, u32
and, u32
or, int split
, int flag
)
554 v
= read_1d0(addr
, split
);
555 write_1d0((v
& and) | or, addr
, split
, flag
);
558 static int find_highest_bit_set(u16 val
)
561 for (i
= 15; i
>= 0; i
--)
567 static int find_lowest_bit_set32(u32 val
)
570 for (i
= 0; i
< 32; i
++)
581 MEMORY_BUS_WIDTH
= 8,
582 TIMEBASE_DIVIDEND
= 10,
583 TIMEBASE_DIVISOR
= 11,
586 CAS_LATENCIES_LSB
= 14,
587 CAS_LATENCIES_MSB
= 15,
588 CAS_LATENCY_TIME
= 16,
589 THERMAL_AND_REFRESH
= 31,
590 REFERENCE_RAW_CARD_USED
= 62,
591 RANK1_ADDRESS_MAPPING
= 63
594 static void calculate_timings(struct raminfo
*info
)
597 unsigned cas_latency_time
;
598 unsigned supported_cas_latencies
;
599 unsigned channel
, slot
;
600 unsigned clock_speed_index
;
601 unsigned min_cas_latency
;
602 unsigned cas_latency
;
603 unsigned max_clock_index
;
605 /* Find common CAS latency */
606 supported_cas_latencies
= 0x3fe;
607 for (channel
= 0; channel
< NUM_CHANNELS
; channel
++)
608 for (slot
= 0; slot
< NUM_SLOTS
; slot
++)
609 if (info
->populated_ranks
[channel
][slot
][0])
610 supported_cas_latencies
&=
613 spd
[channel
][slot
][CAS_LATENCIES_LSB
] |
615 spd
[channel
][slot
][CAS_LATENCIES_MSB
] <<
618 max_clock_index
= min(3, info
->max_supported_clock_speed_index
);
620 cycletime
= min_cycletime
[max_clock_index
];
621 cas_latency_time
= min_cas_latency_time
[max_clock_index
];
623 for (channel
= 0; channel
< NUM_CHANNELS
; channel
++)
624 for (slot
= 0; slot
< NUM_SLOTS
; slot
++)
625 if (info
->populated_ranks
[channel
][slot
][0]) {
630 spd
[channel
][slot
][TIMEBASE_DIVIDEND
] /
631 info
->spd
[channel
][slot
][TIMEBASE_DIVISOR
];
635 info
->spd
[channel
][slot
][CYCLETIME
]);
637 max(cas_latency_time
,
640 spd
[channel
][slot
][CAS_LATENCY_TIME
]);
642 for (clock_speed_index
= 0; clock_speed_index
< 3; clock_speed_index
++) {
643 if (cycletime
== min_cycletime
[clock_speed_index
])
645 if (cycletime
> min_cycletime
[clock_speed_index
]) {
647 cycletime
= min_cycletime
[clock_speed_index
];
651 min_cas_latency
= CEIL_DIV(cas_latency_time
, cycletime
);
653 while (supported_cas_latencies
) {
654 cas_latency
= find_highest_bit_set(supported_cas_latencies
) + 3;
655 if (cas_latency
<= min_cas_latency
)
657 supported_cas_latencies
&=
658 ~(1 << find_highest_bit_set(supported_cas_latencies
));
661 if (cas_latency
!= min_cas_latency
&& clock_speed_index
)
664 if (cas_latency
* min_cycletime
[clock_speed_index
] > 20000)
665 die("Couldn't configure DRAM");
666 info
->clock_speed_index
= clock_speed_index
;
667 info
->cas_latency
= cas_latency
;
670 static void program_base_timings(struct raminfo
*info
)
673 unsigned slot
, rank
, lane
;
674 unsigned extended_silicon_revision
;
677 extended_silicon_revision
= info
->silicon_revision
;
678 if (info
->silicon_revision
== 0)
679 for (channel
= 0; channel
< NUM_CHANNELS
; channel
++)
680 for (slot
= 0; slot
< NUM_SLOTS
; slot
++)
682 spd
[channel
][slot
][MODULE_TYPE
] & 0xF) ==
684 extended_silicon_revision
= 4;
686 for (channel
= 0; channel
< NUM_CHANNELS
; channel
++) {
687 for (slot
= 0; slot
< NUM_SLOTS
; slot
++)
688 for (rank
= 0; rank
< NUM_SLOTS
; rank
++) {
690 if (!info
->populated_ranks
[channel
][slot
][rank
])
693 for (lane
= 0; lane
< 9; lane
++) {
699 spd
[channel
][slot
][MODULE_TYPE
] &
705 [REFERENCE_RAW_CARD_USED
] &
707 if (reference_card
== 3)
712 if (reference_card
== 5)
720 lane_timings
[0][channel
][slot
][rank
]
725 lane_timings
[1][channel
][slot
][rank
]
728 for (tm_reg
= 2; tm_reg
< 4; tm_reg
++)
731 [channel
][slot
][rank
][lane
]
734 [extended_silicon_revision
]
738 + info
->max4048
[channel
]
741 [extended_silicon_revision
]
743 mode4030
[channel
]][slot
]
747 for (tm_reg
= 0; tm_reg
< 4; tm_reg
++)
748 write_500(info
, channel
,
751 [channel
][slot
][rank
]
753 get_timing_register_addr
759 if (!(extended_silicon_revision
!= 4
761 populated_ranks_mask
[channel
] & 5) ==
765 [REFERENCE_RAW_CARD_USED
] & 0x1F)
768 u16_FFFE0EB8
[0][info
->
772 [REFERENCE_RAW_CARD_USED
] & 0x1F)
775 u16_FFFE0EB8
[1][info
->
779 for (i
= 0; i
< 3; i
++)
780 write_500(info
, channel
,
782 info
->max4048
[channel
]
785 [extended_silicon_revision
]
787 mode4030
[channel
]][info
->
789 u16_fffd0c50
[i
][slot
][rank
],
791 write_500(info
, channel
,
792 (info
->max4048
[channel
] +
794 [extended_silicon_revision
][info
->
799 u16_fffd0c70
[slot
][rank
], 7, 1);
801 if (!info
->populated_ranks_mask
[channel
])
803 for (i
= 0; i
< 3; i
++)
804 write_500(info
, channel
,
805 (info
->max4048
[channel
] +
806 info
->avg4044
[channel
]
809 [extended_silicon_revision
][info
->
813 u16_fffd0c68
[i
], 8, 1);
817 static unsigned int fsbcycle_ps(struct raminfo
*info
)
819 return 900000 / info
->fsb_frequency
;
822 /* The time of DDR transfer in ps. */
823 static unsigned int halfcycle_ps(struct raminfo
*info
)
825 return 3750 / (info
->clock_speed_index
+ 3);
828 /* The time of clock cycle in ps. */
829 static unsigned int cycle_ps(struct raminfo
*info
)
831 return 2 * halfcycle_ps(info
);
834 /* Frequency in 1.(1)=10/9 MHz units. */
835 static unsigned frequency_11(struct raminfo
*info
)
837 return (info
->clock_speed_index
+ 3) * 120;
840 /* Frequency in 0.1 MHz units. */
841 static unsigned frequency_01(struct raminfo
*info
)
843 return 100 * frequency_11(info
) / 9;
846 static unsigned ps_to_halfcycles(struct raminfo
*info
, unsigned int ps
)
848 return (frequency_11(info
) * 2) * ps
/ 900000;
851 static unsigned ns_to_cycles(struct raminfo
*info
, unsigned int ns
)
853 return (frequency_11(info
)) * ns
/ 900;
856 static void compute_derived_timings(struct raminfo
*info
)
858 unsigned channel
, slot
, rank
;
859 int extended_silicon_revision
;
862 int some_delay_2_halfcycles_ceil
;
863 int some_delay_2_halfcycles_floor
;
865 int some_delay_3_halfcycles
;
866 int some_delay_3_ps_rounded
;
867 int some_delay_1_cycle_ceil
;
868 int some_delay_1_cycle_floor
;
870 some_delay_3_halfcycles
= 0;
871 some_delay_3_ps_rounded
= 0;
872 extended_silicon_revision
= info
->silicon_revision
;
873 if (!info
->silicon_revision
)
874 for (channel
= 0; channel
< NUM_CHANNELS
; channel
++)
875 for (slot
= 0; slot
< NUM_SLOTS
; slot
++)
877 spd
[channel
][slot
][MODULE_TYPE
] & 0xF) ==
879 extended_silicon_revision
= 4;
880 if (info
->board_lane_delay
[7] < 5)
881 info
->board_lane_delay
[7] = 5;
882 info
->revision_flag_1
= 2;
883 if (info
->silicon_revision
== 2 || info
->silicon_revision
== 3)
884 info
->revision_flag_1
= 0;
885 if (info
->revision
< 16)
886 info
->revision_flag_1
= 0;
888 if (info
->revision
< 8)
889 info
->revision_flag_1
= 0;
890 if (info
->revision
>= 8 && (info
->silicon_revision
== 0
891 || info
->silicon_revision
== 1))
892 some_delay_2_ps
= 735;
894 some_delay_2_ps
= 750;
896 if (info
->revision
>= 0x10 && (info
->silicon_revision
== 0
897 || info
->silicon_revision
== 1))
898 some_delay_1_ps
= 3929;
900 some_delay_1_ps
= 3490;
902 some_delay_1_cycle_floor
= some_delay_1_ps
/ cycle_ps(info
);
903 some_delay_1_cycle_ceil
= some_delay_1_ps
/ cycle_ps(info
);
904 if (some_delay_1_ps
% cycle_ps(info
))
905 some_delay_1_cycle_ceil
++;
907 some_delay_1_cycle_floor
--;
908 info
->some_delay_1_cycle_floor
= some_delay_1_cycle_floor
;
909 if (info
->revision_flag_1
)
910 some_delay_2_ps
= halfcycle_ps(info
) >> 6;
912 max(some_delay_1_ps
- 30,
913 2 * halfcycle_ps(info
) * (some_delay_1_cycle_ceil
- 1) + 1000) +
916 halfcycle_ps(info
) - some_delay_2_ps
% halfcycle_ps(info
);
917 if (info
->revision_flag_1
) {
918 if (some_delay_3_ps
< 150)
919 some_delay_3_halfcycles
= 0;
921 some_delay_3_halfcycles
=
922 (some_delay_3_ps
<< 6) / halfcycle_ps(info
);
923 some_delay_3_ps_rounded
=
924 halfcycle_ps(info
) * some_delay_3_halfcycles
>> 6;
926 some_delay_2_halfcycles_ceil
=
927 (some_delay_2_ps
+ halfcycle_ps(info
) - 1) / halfcycle_ps(info
) -
928 2 * (some_delay_1_cycle_ceil
- 1);
929 if (info
->revision_flag_1
&& some_delay_3_ps
< 150)
930 some_delay_2_halfcycles_ceil
++;
931 some_delay_2_halfcycles_floor
= some_delay_2_halfcycles_ceil
;
932 if (info
->revision
< 0x10)
933 some_delay_2_halfcycles_floor
=
934 some_delay_2_halfcycles_ceil
- 1;
935 if (!info
->revision_flag_1
)
936 some_delay_2_halfcycles_floor
++;
937 info
->some_delay_2_halfcycles_ceil
= some_delay_2_halfcycles_ceil
;
938 info
->some_delay_3_ps_rounded
= some_delay_3_ps_rounded
;
939 if ((info
->populated_ranks
[0][0][0] && info
->populated_ranks
[0][1][0])
940 || (info
->populated_ranks
[1][0][0]
941 && info
->populated_ranks
[1][1][0]))
942 info
->max_slots_used_in_channel
= 2;
944 info
->max_slots_used_in_channel
= 1;
945 for (channel
= 0; channel
< 2; channel
++)
946 write_mchbar32(0x244 + (channel
<< 10),
947 ((info
->revision
< 8) ? 1 : 0x200)
948 | ((2 - info
->max_slots_used_in_channel
) << 17) |
949 (channel
<< 21) | (info
->
950 some_delay_1_cycle_floor
<<
952 if (info
->max_slots_used_in_channel
== 1) {
953 info
->mode4030
[0] = (count_ranks_in_channel(info
, 0) == 2);
954 info
->mode4030
[1] = (count_ranks_in_channel(info
, 1) == 2);
956 info
->mode4030
[0] = ((count_ranks_in_channel(info
, 0) == 1) || (count_ranks_in_channel(info
, 0) == 2)) ? 2 : 3; /* 2 if 1 or 2 ranks */
957 info
->mode4030
[1] = ((count_ranks_in_channel(info
, 1) == 1)
958 || (count_ranks_in_channel(info
, 1) ==
961 for (channel
= 0; channel
< NUM_CHANNELS
; channel
++) {
968 if (!info
->populated_ranks_mask
[channel
])
972 min_of_unk_2
= 32767;
976 for (i
= 0; i
< 3; i
++) {
978 if (info
->revision
< 8)
980 u8_FFFD1891
[0][channel
][info
->
984 (info
->revision
>= 0x10
985 || info
->revision_flag_1
))
987 u8_FFFD1891
[1][channel
][info
->
992 for (slot
= 0; slot
< NUM_SLOTS
; slot
++)
993 for (rank
= 0; rank
< NUM_RANKS
; rank
++) {
998 populated_ranks
[channel
][slot
]
1001 if (extended_silicon_revision
== 4
1003 populated_ranks_mask
[channel
] &
1007 [REFERENCE_RAW_CARD_USED
] &
1012 b
= u16_fe0eb8
[0][info
->
1017 [REFERENCE_RAW_CARD_USED
]
1022 b
= u16_fe0eb8
[1][info
->
1026 min_of_unk_2
= min(min_of_unk_2
, a
);
1027 min_of_unk_2
= min(min_of_unk_2
, b
);
1035 u8_FFFD0EF8
[channel
]
1036 [extended_silicon_revision
]
1038 mode4030
[channel
]][info
->
1048 u8_FFFD17E0
[channel
]
1049 [extended_silicon_revision
][info
->
1052 [info
->clock_speed_index
] + min_of_unk_2
;
1054 max_of_unk
= max(max_of_unk
, unk1
- t
);
1058 info
->avg4044
[channel
] = sum
/ count
;
1059 info
->max4048
[channel
] = max_of_unk
;
1063 static void jedec_read(struct raminfo
*info
,
1064 int channel
, int slot
, int rank
,
1065 int total_rank
, u8 addr3
, unsigned int value
)
1067 /* Handle mirrored mapping. */
1068 if ((rank
& 1) && (info
->spd
[channel
][slot
][RANK1_ADDRESS_MAPPING
] & 1))
1070 (addr3
& 0xCF) | ((addr3
& 0x10) << 1) | ((addr3
>> 1) &
1072 write_mchbar8(0x271, addr3
| (read_mchbar8(0x271) & 0xC1));
1073 write_mchbar8(0x671, addr3
| (read_mchbar8(0x671) & 0xC1));
1075 /* Handle mirrored mapping. */
1076 if ((rank
& 1) && (info
->spd
[channel
][slot
][RANK1_ADDRESS_MAPPING
] & 1))
1078 (value
& ~0x1f8) | ((value
>> 1) & 0xa8) | ((value
& 0xa8)
1081 read32p((value
<< 3) | (total_rank
<< 28));
1083 write_mchbar8(0x271, (read_mchbar8(0x271) & 0xC3) | 2);
1084 write_mchbar8(0x671, (read_mchbar8(0x671) & 0xC3) | 2);
1086 read32p(total_rank
<< 28);
1097 MR0_BT_INTERLEAVED
= 8,
1098 MR0_DLL_RESET_ON
= 256
1102 MR2_RTT_WR_DISABLED
= 0,
1106 static void jedec_init(struct raminfo
*info
)
1109 int channel
, slot
, rank
;
1112 int self_refresh_temperature
;
1113 int auto_self_refresh
;
1115 auto_self_refresh
= 1;
1116 self_refresh_temperature
= 1;
1117 if (info
->board_lane_delay
[3] <= 10) {
1118 if (info
->board_lane_delay
[3] <= 8)
1119 write_recovery
= info
->board_lane_delay
[3] - 4;
1125 FOR_POPULATED_RANKS
{
1126 auto_self_refresh
&=
1127 (info
->spd
[channel
][slot
][THERMAL_AND_REFRESH
] >> 2) & 1;
1128 self_refresh_temperature
&=
1129 info
->spd
[channel
][slot
][THERMAL_AND_REFRESH
] & 1;
1131 if (auto_self_refresh
== 1)
1132 self_refresh_temperature
= 0;
1134 dll_on
= ((info
->silicon_revision
!= 2 && info
->silicon_revision
!= 3)
1135 || (info
->populated_ranks
[0][0][0]
1136 && info
->populated_ranks
[0][1][0])
1137 || (info
->populated_ranks
[1][0][0]
1138 && info
->populated_ranks
[1][1][0]));
1142 for (channel
= NUM_CHANNELS
- 1; channel
>= 0; channel
--) {
1143 int rtt
, rtt_wr
= MR2_RTT_WR_DISABLED
;
1146 if (info
->silicon_revision
== 2 || info
->silicon_revision
== 3) {
1149 if (info
->clock_speed_index
!= 0) {
1151 if (info
->populated_ranks_mask
[channel
] == 3)
1155 if ((info
->populated_ranks_mask
[channel
] & 5) == 5) {
1165 write_mchbar16(0x588 + (channel
<< 10), 0x0);
1166 write_mchbar16(0x58a + (channel
<< 10), 0x4);
1167 write_mchbar16(0x58c + (channel
<< 10), rtt
| MR1_ODS34OHM
);
1168 write_mchbar16(0x58e + (channel
<< 10), rzq_reg58e
| 0x82);
1169 write_mchbar16(0x590 + (channel
<< 10), 0x1282);
1171 for (slot
= 0; slot
< NUM_SLOTS
; slot
++)
1172 for (rank
= 0; rank
< NUM_RANKS
; rank
++)
1173 if (info
->populated_ranks
[channel
][slot
][rank
]) {
1174 jedec_read(info
, channel
, slot
, rank
,
1179 | (auto_self_refresh
<< 6) |
1180 (self_refresh_temperature
<<
1182 jedec_read(info
, channel
, slot
, rank
,
1183 total_rank
, 0x38, 0);
1184 jedec_read(info
, channel
, slot
, rank
,
1186 rtt
| MR1_ODS34OHM
);
1187 jedec_read(info
, channel
, slot
, rank
,
1190 (write_recovery
<< 9)
1191 | ((info
->cas_latency
- 4) <<
1192 4) | MR0_BT_INTERLEAVED
|
1199 static void program_modules_memory_map(struct raminfo
*info
, int pre_jedec
)
1201 unsigned channel
, slot
, rank
;
1202 unsigned int total_mb
[2] = { 0, 0 }; /* total memory per channel in MB */
1203 unsigned int channel_0_non_interleaved
;
1206 if (info
->populated_ranks
[channel
][slot
][rank
]) {
1207 total_mb
[channel
] +=
1208 pre_jedec
? 256 : (256 << info
->
1209 density
[channel
][slot
] >> info
->
1210 is_x16_module
[channel
][slot
]);
1211 write_mchbar8(0x208 + rank
+ 2 * slot
+ (channel
<< 10),
1212 (pre_jedec
? (1 | ((1 + 1) << 1))
1214 is_x16_module
[channel
][slot
] |
1215 ((info
->density
[channel
][slot
] +
1218 write_mchbar16(0x200 + (channel
<< 10) + 4 * slot
+ 2 * rank
,
1219 total_mb
[channel
] >> 6);
1222 info
->total_memory_mb
= total_mb
[0] + total_mb
[1];
1224 info
->interleaved_part_mb
=
1225 pre_jedec
? 0 : 2 * min(total_mb
[0], total_mb
[1]);
1226 info
->non_interleaved_part_mb
=
1227 total_mb
[0] + total_mb
[1] - info
->interleaved_part_mb
;
1228 channel_0_non_interleaved
= total_mb
[0] - info
->interleaved_part_mb
/ 2;
1229 write_mchbar32(0x100,
1230 channel_0_non_interleaved
| (info
->
1231 non_interleaved_part_mb
<<
1234 write_mchbar16(0x104, info
->interleaved_part_mb
);
1237 static void program_board_delay(struct raminfo
*info
)
1239 int cas_latency_shift
;
1241 int some_delay_3_half_cycles
;
1243 unsigned channel
, i
;
1244 int high_multiplier
;
1246 int cas_latency_derived
;
1248 high_multiplier
= 0;
1249 some_delay_ns
= 200;
1250 some_delay_3_half_cycles
= 4;
1251 cas_latency_shift
= info
->silicon_revision
== 0
1252 || info
->silicon_revision
== 1 ? 1 : 0;
1253 if (info
->revision
< 8) {
1254 some_delay_ns
= 600;
1255 cas_latency_shift
= 0;
1260 ((info
->clock_speed_index
> 1
1261 || (info
->silicon_revision
!= 2
1262 && info
->silicon_revision
!= 3))) ^ (info
->revision
>=
1264 write_500(info
, 0, speed_bit
| ((!info
->use_ecc
) << 1), 0x60e,
1266 write_500(info
, 1, speed_bit
| ((!info
->use_ecc
) << 1), 0x60e,
1268 if (info
->revision
>= 0x10 && info
->clock_speed_index
<= 1
1269 && (info
->silicon_revision
== 2
1270 || info
->silicon_revision
== 3))
1271 rmw_1d0(0x116, 5, 2, 4, 1);
1273 write_mchbar32(0x120,
1274 (1 << (info
->max_slots_used_in_channel
+ 28)) |
1277 write_mchbar8(0x124,
1278 info
->board_lane_delay
[4] +
1279 ((frequency_01(info
) + 999) / 1000));
1280 write_mchbar16(0x125, 0x1360);
1281 write_mchbar8(0x127, 0x40);
1282 if (info
->fsb_frequency
< frequency_11(info
) / 2) {
1283 unsigned some_delay_2_half_cycles
;
1284 high_multiplier
= 1;
1285 some_delay_2_half_cycles
= ps_to_halfcycles(info
,
1298 some_delay_3_half_cycles
=
1299 min((some_delay_2_half_cycles
+
1300 (frequency_11(info
) * 2) * (28 -
1301 some_delay_2_half_cycles
) /
1302 (frequency_11(info
) * 2 -
1303 4 * (info
->fsb_frequency
))) >> 3, 7);
1305 if (read_mchbar8(0x2ca9) & 1)
1306 some_delay_3_half_cycles
= 3;
1307 for (channel
= 0; channel
< NUM_CHANNELS
; channel
++) {
1308 write_mchbar32(0x220 + (channel
<< 10),
1309 read_mchbar32(0x220 +
1310 (channel
<< 10)) | 0x18001117);
1311 write_mchbar32(0x224 + (channel
<< 10),
1312 (info
->max_slots_used_in_channel
- 1)
1314 ((info
->cas_latency
- 5 -
1315 info
->clock_speed_index
) << 21)
1317 ((info
->max_slots_used_in_channel
+
1318 info
->cas_latency
- cas_latency_shift
-
1320 | ((info
->cas_latency
- cas_latency_shift
- 4) <<
1323 ((info
->cas_latency
- info
->clock_speed_index
+
1324 info
->max_slots_used_in_channel
- 6) << 8));
1325 write_mchbar32(0x228 + (channel
<< 10),
1326 info
->max_slots_used_in_channel
);
1327 write_mchbar8(0x239 + (channel
<< 10), 32);
1328 write_mchbar32(0x248 + (channel
<< 10),
1329 (high_multiplier
<< 24) |
1330 (some_delay_3_half_cycles
<< 25) | 0x840000);
1331 write_mchbar32(0x278 + (channel
<< 10), 0xc362042);
1332 write_mchbar32(0x27c + (channel
<< 10), 0x8b000062);
1333 write_mchbar32(0x24c + (channel
<< 10),
1335 clock_speed_index
) << 17) | (((2 +
1340 clock_speed_index
)))
1343 write_mchbar8(0x267 + (channel
<< 10), 0x4);
1344 write_mchbar16(0x272 + (channel
<< 10), 0x155);
1345 write_mchbar32(0x2bc + (channel
<< 10),
1346 (read_mchbar32(0x2bc + (channel
<< 10)) &
1350 write_500(info
, channel
,
1351 ((!info
->populated_ranks
[channel
][1][1])
1352 | (!info
->populated_ranks
[channel
][1][0] << 1)
1353 | (!info
->populated_ranks
[channel
][0][1] << 2)
1354 | (!info
->populated_ranks
[channel
][0][0] << 3)),
1358 write_mchbar8(0x2c4, ((1 + (info
->clock_speed_index
!= 0)) << 6) | 0xC);
1360 u8 freq_divisor
= 2;
1361 if (info
->fsb_frequency
== frequency_11(info
))
1363 else if (2 * info
->fsb_frequency
< 3 * (frequency_11(info
) / 2))
1367 write_mchbar32(0x2c0, (freq_divisor
<< 11) | 0x6009c400);
1370 if (info
->board_lane_delay
[3] <= 10) {
1371 if (info
->board_lane_delay
[3] <= 8)
1372 lane_3_delay
= info
->board_lane_delay
[3];
1378 cas_latency_derived
= info
->cas_latency
- info
->clock_speed_index
+ 2;
1379 if (info
->clock_speed_index
> 1)
1380 cas_latency_derived
++;
1381 for (channel
= 0; channel
< NUM_CHANNELS
; channel
++) {
1382 write_mchbar32(0x240 + (channel
<< 10),
1383 ((info
->clock_speed_index
==
1384 0) * 0x11000) | 0x1002100 | ((2 +
1390 write_500(info
, channel
, (info
->clock_speed_index
<< 1) | 1,
1392 write_500(info
, channel
,
1393 info
->clock_speed_index
+ 2 * info
->cas_latency
- 7,
1396 write_mchbar32(0x250 + (channel
<< 10),
1397 ((lane_3_delay
+ info
->clock_speed_index
+
1399 | (info
->board_lane_delay
[7] << 2) | (info
->
1402 | (info
->board_lane_delay
[1] << 25) | (info
->
1406 write_mchbar32(0x254 + (channel
<< 10),
1408 board_lane_delay
[1] >> 3) | ((info
->
1414 0x80 | (info
->board_lane_delay
[6] << 1) | (info
->
1418 (cas_latency_derived
<< 16) | 0x4700000);
1419 write_mchbar32(0x258 + (channel
<< 10),
1420 ((info
->board_lane_delay
[5] +
1421 info
->clock_speed_index
+
1422 9) << 12) | ((info
->clock_speed_index
-
1423 info
->cas_latency
+ 12) << 8)
1424 | (info
->board_lane_delay
[2] << 17) | (info
->
1428 write_mchbar32(0x25c + (channel
<< 10),
1429 (info
->board_lane_delay
[1] << 1) | (info
->
1433 write_mchbar8(0x264 + (channel
<< 10), 0xff);
1434 write_mchbar8(0x5f8 + (channel
<< 10),
1435 (cas_latency_shift
<< 3) | info
->use_ecc
);
1438 program_modules_memory_map(info
, 1);
1440 write_mchbar16(0x610,
1441 (min(ns_to_cycles(info
, some_delay_ns
) / 2, 127) << 9)
1442 | (read_mchbar16(0x610) & 0x1C3) | 0x3C);
1443 write_mchbar16(0x612, read_mchbar16(0x612) | 0x100);
1444 write_mchbar16(0x214, read_mchbar16(0x214) | 0x3E00);
1445 for (i
= 0; i
< 8; i
++) {
1446 pcie_write_config32(PCI_DEV (QUICKPATH_BUS
, 0, 1), 0x80 + 4 * i
,
1447 (info
->total_memory_mb
- 64) | !i
| 2);
1448 pcie_write_config32(PCI_DEV (QUICKPATH_BUS
, 0, 1), 0xc0 + 4 * i
, 0);
1452 #define BETTER_MEMORY_MAP 0
1454 static void program_total_memory_map(struct raminfo
*info
)
1456 unsigned int TOM
, TOLUD
, TOUUD
;
1457 unsigned int quickpath_reserved
;
1458 unsigned int REMAPbase
;
1459 unsigned int uma_base_igd
;
1460 unsigned int uma_base_gtt
;
1462 unsigned int memory_map
[8];
1464 unsigned int current_limit
;
1465 unsigned int tseg_base
;
1466 int uma_size_igd
= 0, uma_size_gtt
= 0;
1468 memset(memory_map
, 0, sizeof(memory_map
));
1471 if (info
->uma_enabled
) {
1472 u16 t
= pcie_read_config16(NORTHBRIDGE
, D0F0_GGC
);
1474 const int uma_sizes_gtt
[16] =
1475 { 0, 1, 0, 2, 0, 0, 0, 0, 0, 2, 3, 4, 42, 42, 42, 42 };
1477 const int uma_sizes_igd
[16] = {
1478 0, 0, 0, 0, 0, 32, 48, 64, 128, 256, 96, 160, 224, 352,
1482 uma_size_igd
= uma_sizes_igd
[(t
>> 4) & 0xF];
1483 uma_size_gtt
= uma_sizes_gtt
[(t
>> 8) & 0xF];
1487 TOM
= info
->total_memory_mb
;
1490 TOUUD
= ALIGN_DOWN(TOM
- info
->memory_reserved_for_heci_mb
, 64);
1491 TOLUD
= ALIGN_DOWN(min(3072 + ALIGN_UP(uma_size_igd
+ uma_size_gtt
, 64)
1494 if (TOUUD
- TOLUD
> 64) {
1496 REMAPbase
= max(4096, TOUUD
);
1497 TOUUD
= TOUUD
- TOLUD
+ 4096;
1500 memory_map
[2] = TOUUD
| 1;
1501 quickpath_reserved
= 0;
1506 gav(t
= pcie_read_config32(PCI_DEV(QUICKPATH_BUS
, 0, 1), 0x68));
1508 quickpath_reserved
=
1509 (1 << find_lowest_bit_set32(t
>> 20));
1512 TOUUD
-= quickpath_reserved
;
1515 if (info
->uma_enabled
) {
1516 u16 t
= pcie_read_config16(NORTHBRIDGE
, D0F0_GGC
);
1518 const int uma_sizes_gtt
[16] =
1519 { 0, 1, 0, 2, 0, 0, 0, 0, 0, 2, 3, 4, 42, 42, 42, 42 };
1521 const int uma_sizes_igd
[16] = {
1522 0, 0, 0, 0, 0, 32, 48, 64, 128, 256, 96, 160, 224, 352,
1526 uma_size_igd
= uma_sizes_igd
[(t
>> 4) & 0xF];
1527 uma_size_gtt
= uma_sizes_gtt
[(t
>> 8) & 0xF];
1531 uma_base_igd
= TOLUD
- uma_size_igd
;
1532 uma_base_gtt
= uma_base_igd
- uma_size_gtt
;
1533 tseg_base
= ALIGN_DOWN(uma_base_gtt
, 64) - (CONFIG_SMM_TSEG_SIZE
>> 20);
1535 tseg_base
-= quickpath_reserved
;
1536 tseg_base
= ALIGN_DOWN(tseg_base
, 8);
1538 pcie_write_config16(NORTHBRIDGE
, D0F0_TOLUD
, TOLUD
<< 4);
1539 pcie_write_config16(NORTHBRIDGE
, D0F0_TOM
, TOM
>> 6);
1541 pcie_write_config16(NORTHBRIDGE
, D0F0_REMAPBASE
, REMAPbase
>> 6);
1542 pcie_write_config16(NORTHBRIDGE
, D0F0_REMAPLIMIT
, (TOUUD
- 64) >> 6);
1544 pcie_write_config16(NORTHBRIDGE
, D0F0_TOUUD
, TOUUD
);
1546 if (info
->uma_enabled
) {
1547 pcie_write_config32(NORTHBRIDGE
, D0F0_IGD_BASE
, uma_base_igd
<< 20);
1548 pcie_write_config32(NORTHBRIDGE
, D0F0_GTT_BASE
, uma_base_gtt
<< 20);
1550 pcie_write_config32(NORTHBRIDGE
, TSEG
, tseg_base
<< 20);
1553 memory_map
[0] = ALIGN_DOWN(uma_base_gtt
, 64) | 1;
1554 memory_map
[1] = 4096;
1555 for (i
= 0; i
< ARRAY_SIZE(memory_map
); i
++) {
1556 current_limit
= max(current_limit
, memory_map
[i
] & ~1);
1557 pcie_write_config32(PCI_DEV(QUICKPATH_BUS
, 0, 1), 4 * i
+ 0x80,
1558 (memory_map
[i
] & 1) | ALIGN_DOWN(current_limit
-
1560 pcie_write_config32(PCI_DEV(QUICKPATH_BUS
, 0, 1), 4 * i
+ 0xc0, 0);
1564 static void collect_system_info(struct raminfo
*info
)
1570 /* Wait for some bit, maybe TXT clear. */
1571 while (!(read8((u8
*)0xfed40000) & (1 << 7))) ;
1573 if (!info
->heci_bar
)
1574 gav(info
->heci_bar
=
1575 pcie_read_config32(HECIDEV
, HECIBAR
) & 0xFFFFFFF8);
1576 if (!info
->memory_reserved_for_heci_mb
) {
1577 /* Wait for ME to be ready */
1578 intel_early_me_init();
1579 info
->memory_reserved_for_heci_mb
= intel_early_me_uma_size();
1582 for (i
= 0; i
< 3; i
++)
1584 pcie_read_config32(NORTHBRIDGE
, D0F0_CAPID0
| (i
<< 2)));
1585 gav(info
->revision
= pcie_read_config8(NORTHBRIDGE
, PCI_REVISION_ID
));
1586 info
->max_supported_clock_speed_index
= (~capid0
[1] & 7);
1588 if ((capid0
[1] >> 11) & 1)
1589 info
->uma_enabled
= 0;
1591 gav(info
->uma_enabled
=
1592 pcie_read_config8(NORTHBRIDGE
, D0F0_DEVEN
) & 8);
1593 /* Unrecognised: [0000:fffd3d2d] 37f81.37f82 ! CPUID: eax: 00000001; ecx: 00000e00 => 00020655.00010800.029ae3ff.bfebfbff */
1594 info
->silicon_revision
= 0;
1596 if (capid0
[2] & 2) {
1597 info
->silicon_revision
= 0;
1598 info
->max_supported_clock_speed_index
= 2;
1599 for (channel
= 0; channel
< NUM_CHANNELS
; channel
++)
1600 if (info
->populated_ranks
[channel
][0][0]
1601 && (info
->spd
[channel
][0][MODULE_TYPE
] & 0xf) ==
1603 info
->silicon_revision
= 2;
1604 info
->max_supported_clock_speed_index
= 1;
1607 switch (((capid0
[2] >> 18) & 1) + 2 * ((capid0
[1] >> 3) & 1)) {
1610 info
->silicon_revision
= 3;
1613 info
->silicon_revision
= 0;
1616 info
->silicon_revision
= 2;
1619 switch (pcie_read_config16(NORTHBRIDGE
, PCI_DEVICE_ID
)) {
1621 info
->silicon_revision
= 0;
1624 info
->silicon_revision
= 1;
1630 static void write_training_data(struct raminfo
*info
)
1632 int tm
, channel
, slot
, rank
, lane
;
1633 if (info
->revision
< 8)
1636 for (tm
= 0; tm
< 4; tm
++)
1637 for (channel
= 0; channel
< NUM_CHANNELS
; channel
++)
1638 for (slot
= 0; slot
< NUM_SLOTS
; slot
++)
1639 for (rank
= 0; rank
< NUM_RANKS
; rank
++)
1640 for (lane
= 0; lane
< 9; lane
++)
1641 write_500(info
, channel
,
1645 [channel
][slot
][rank
]
1647 get_timing_register_addr
1650 write_1d0(info
->cached_training
->reg_178
, 0x178, 7, 1);
1651 write_1d0(info
->cached_training
->reg_10b
, 0x10b, 6, 1);
1654 static void dump_timings(struct raminfo
*info
)
1657 int channel
, slot
, rank
, lane
, i
;
1658 printk(BIOS_DEBUG
, "Timings:\n");
1659 FOR_POPULATED_RANKS
{
1660 printk(BIOS_DEBUG
, "channel %d, slot %d, rank %d\n", channel
,
1662 for (lane
= 0; lane
< 9; lane
++) {
1663 printk(BIOS_DEBUG
, "lane %d: ", lane
);
1664 for (i
= 0; i
< 4; i
++) {
1665 printk(BIOS_DEBUG
, "%x (%x) ",
1666 read_500(info
, channel
,
1667 get_timing_register_addr
1668 (lane
, i
, slot
, rank
),
1671 lane_timings
[i
][channel
][slot
][rank
]
1674 printk(BIOS_DEBUG
, "\n");
1677 printk(BIOS_DEBUG
, "[178] = %x (%x)\n", read_1d0(0x178, 7),
1678 info
->training
.reg_178
);
1679 printk(BIOS_DEBUG
, "[10b] = %x (%x)\n", read_1d0(0x10b, 6),
1680 info
->training
.reg_10b
);
1684 /* Read timings and other registers that need to be restored verbatim and
1687 static void save_timings(struct raminfo
*info
)
1689 struct ram_training train
;
1690 struct mrc_data_container
*mrcdata
;
1691 int output_len
= ALIGN(sizeof(train
), 16);
1692 int channel
, slot
, rank
, lane
, i
;
1694 train
= info
->training
;
1695 FOR_POPULATED_RANKS
for (lane
= 0; lane
< 9; lane
++)
1696 for (i
= 0; i
< 4; i
++)
1697 train
.lane_timings
[i
][channel
][slot
][rank
][lane
] =
1698 read_500(info
, channel
,
1699 get_timing_register_addr(lane
, i
, slot
,
1701 train
.reg_178
= read_1d0(0x178, 7);
1702 train
.reg_10b
= read_1d0(0x10b, 6);
1704 for (channel
= 0; channel
< NUM_CHANNELS
; channel
++) {
1706 reg32
= read_mchbar32 ((channel
<< 10) + 0x274);
1707 train
.reg274265
[channel
][0] = reg32
>> 16;
1708 train
.reg274265
[channel
][1] = reg32
& 0xffff;
1709 train
.reg274265
[channel
][2] = read_mchbar16 ((channel
<< 10) + 0x265) >> 8;
1711 train
.reg2ca9_bit0
= read_mchbar8(0x2ca9) & 1;
1712 train
.reg_6dc
= read_mchbar32 (0x6dc);
1713 train
.reg_6e8
= read_mchbar32 (0x6e8);
1715 printk (BIOS_SPEW
, "[6dc] = %x\n", train
.reg_6dc
);
1716 printk (BIOS_SPEW
, "[6e8] = %x\n", train
.reg_6e8
);
1718 /* Save the MRC S3 restore data to cbmem */
1720 (CBMEM_ID_MRCDATA
, output_len
+ sizeof(struct mrc_data_container
));
1722 if (mrcdata
!= NULL
) {
1723 printk(BIOS_DEBUG
, "Relocate MRC DATA from %p to %p (%u bytes)\n",
1724 &train
, mrcdata
, output_len
);
1726 mrcdata
->mrc_signature
= MRC_DATA_SIGNATURE
;
1727 mrcdata
->mrc_data_size
= output_len
;
1728 mrcdata
->reserved
= 0;
1729 memcpy(mrcdata
->mrc_data
, &train
, sizeof(train
));
1731 /* Zero the unused space in aligned buffer. */
1732 if (output_len
> sizeof(train
))
1733 memset(mrcdata
->mrc_data
+ sizeof(train
), 0,
1734 output_len
- sizeof(train
));
1736 mrcdata
->mrc_checksum
= compute_ip_checksum(mrcdata
->mrc_data
,
1737 mrcdata
->mrc_data_size
);
1742 static const struct ram_training
*get_cached_training(void)
1744 struct mrc_data_container
*cont
;
1745 cont
= find_current_mrc_cache();
1748 return (void *)cont
->mrc_data
;
1752 /* FIXME: add timeout. */
1753 static void wait_heci_ready(void)
1755 while (!(read32(DEFAULT_HECIBAR
+ 0xc) & 8)) ; // = 0x8000000c
1756 write32((DEFAULT_HECIBAR
+ 0x4),
1757 (read32(DEFAULT_HECIBAR
+ 0x4) & ~0x10) | 0xc);
1760 /* FIXME: add timeout. */
1761 static void wait_heci_cb_avail(int len
)
1768 while (!(read32(DEFAULT_HECIBAR
+ 0xc) & 8)) ;
1771 csr
.raw
= read32(DEFAULT_HECIBAR
+ 0x4);
1773 csr
.csr
.buffer_depth
- (csr
.csr
.buffer_write_ptr
-
1774 csr
.csr
.buffer_read_ptr
));
1777 static void send_heci_packet(struct mei_header
*head
, u32
* payload
)
1779 int len
= (head
->length
+ 3) / 4;
1782 wait_heci_cb_avail(len
+ 1);
1784 /* FIXME: handle leftovers correctly. */
1785 write32(DEFAULT_HECIBAR
+ 0, *(u32
*) head
);
1786 for (i
= 0; i
< len
- 1; i
++)
1787 write32(DEFAULT_HECIBAR
+ 0, payload
[i
]);
1789 write32(DEFAULT_HECIBAR
+ 0, payload
[i
] & ((1 << (8 * len
)) - 1));
1790 write32(DEFAULT_HECIBAR
+ 0x4, read32(DEFAULT_HECIBAR
+ 0x4) | 0x4);
1794 send_heci_message(u8
* msg
, int len
, u8 hostaddress
, u8 clientaddress
)
1796 struct mei_header head
;
1800 maxlen
= (read32(DEFAULT_HECIBAR
+ 0x4) >> 24) * 4 - 4;
1806 head
.is_complete
= 0;
1808 head
.is_complete
= 1;
1811 head
.client_address
= clientaddress
;
1812 head
.host_address
= hostaddress
;
1813 send_heci_packet(&head
, (u32
*) msg
);
1819 /* FIXME: Add timeout. */
1821 recv_heci_packet(struct raminfo
*info
, struct mei_header
*head
, u32
* packet
,
1830 write32(DEFAULT_HECIBAR
+ 0x4, read32(DEFAULT_HECIBAR
+ 0x4) | 2);
1832 csr
.raw
= read32(DEFAULT_HECIBAR
+ 0xc);
1838 while (csr
.csr
.buffer_write_ptr
== csr
.csr
.buffer_read_ptr
);
1839 *(u32
*) head
= read32(DEFAULT_HECIBAR
+ 0x8);
1840 if (!head
->length
) {
1841 write32(DEFAULT_HECIBAR
+ 0x4,
1842 read32(DEFAULT_HECIBAR
+ 0x4) | 2);
1846 if (head
->length
+ 4 > 4 * csr
.csr
.buffer_depth
1847 || head
->length
> *packet_size
) {
1853 csr
.raw
= read32(DEFAULT_HECIBAR
+ 0xc);
1854 while ((head
->length
+ 3) >> 2 >
1855 csr
.csr
.buffer_write_ptr
- csr
.csr
.buffer_read_ptr
);
1857 for (i
= 0; i
< (head
->length
+ 3) >> 2; i
++)
1858 packet
[i
++] = read32(DEFAULT_HECIBAR
+ 0x8);
1859 *packet_size
= head
->length
;
1862 write32(DEFAULT_HECIBAR
+ 0x4, read32(DEFAULT_HECIBAR
+ 0x4) | 4);
1866 /* FIXME: Add timeout. */
1868 recv_heci_message(struct raminfo
*info
, u32
* message
, u32
* message_size
)
1870 struct mei_header head
;
1871 int current_position
;
1873 current_position
= 0;
1876 current_size
= *message_size
- current_position
;
1877 if (recv_heci_packet
1878 (info
, &head
, message
+ (current_position
>> 2),
1879 ¤t_size
) == -1)
1883 current_position
+= current_size
;
1884 if (head
.is_complete
) {
1885 *message_size
= current_position
;
1889 if (current_position
>= *message_size
)
1896 static void send_heci_uma_message(struct raminfo
*info
)
1904 u8 unk3
[0x48 - 4 - 1];
1905 } __attribute__ ((packed
)) reply
;
1906 struct uma_message
{
1913 u32 memory_reserved_for_heci_mb
;
1915 } __attribute__ ((packed
)) msg
= {
1916 0, MKHI_SET_UMA
, 0, 0,
1918 info
->heci_uma_addr
, info
->memory_reserved_for_heci_mb
, 0};
1921 send_heci_message((u8
*) & msg
, sizeof(msg
), 0, 7);
1923 reply_size
= sizeof(reply
);
1924 if (recv_heci_message(info
, (u32
*) & reply
, &reply_size
) == -1)
1927 if (reply
.command
!= (MKHI_SET_UMA
| (1 << 7)))
1928 die("HECI init failed\n");
1931 static void setup_heci_uma(struct raminfo
*info
)
1935 reg44
= pcie_read_config32(HECIDEV
, 0x44); // = 0x80010020
1936 info
->memory_reserved_for_heci_mb
= 0;
1937 info
->heci_uma_addr
= 0;
1938 if (!((reg44
& 0x10000) && !(pcie_read_config32(HECIDEV
, 0x40) & 0x20)))
1941 info
->heci_bar
= pcie_read_config32(HECIDEV
, 0x10) & 0xFFFFFFF0;
1942 info
->memory_reserved_for_heci_mb
= reg44
& 0x3f;
1943 info
->heci_uma_addr
=
1945 ((((u64
) pcie_read_config16(NORTHBRIDGE
, D0F0_TOM
)) << 6) -
1946 info
->memory_reserved_for_heci_mb
)) << 20;
1948 pcie_read_config32(NORTHBRIDGE
, DMIBAR
);
1949 if (info
->memory_reserved_for_heci_mb
) {
1950 write32(DEFAULT_DMIBAR
+ 0x14,
1951 read32(DEFAULT_DMIBAR
+ 0x14) & ~0x80);
1952 write32(DEFAULT_RCBA
+ 0x14,
1953 read32(DEFAULT_RCBA
+ 0x14) & ~0x80);
1954 write32(DEFAULT_DMIBAR
+ 0x20,
1955 read32(DEFAULT_DMIBAR
+ 0x20) & ~0x80);
1956 write32(DEFAULT_RCBA
+ 0x20,
1957 read32(DEFAULT_RCBA
+ 0x20) & ~0x80);
1958 write32(DEFAULT_DMIBAR
+ 0x2c,
1959 read32(DEFAULT_DMIBAR
+ 0x2c) & ~0x80);
1960 write32(DEFAULT_RCBA
+ 0x30,
1961 read32(DEFAULT_RCBA
+ 0x30) & ~0x80);
1962 write32(DEFAULT_DMIBAR
+ 0x38,
1963 read32(DEFAULT_DMIBAR
+ 0x38) & ~0x80);
1964 write32(DEFAULT_RCBA
+ 0x40,
1965 read32(DEFAULT_RCBA
+ 0x40) & ~0x80);
1967 write32(DEFAULT_RCBA
+ 0x40, 0x87000080); // OK
1968 write32(DEFAULT_DMIBAR
+ 0x38, 0x87000080); // OK
1969 while (read16(DEFAULT_RCBA
+ 0x46) & 2
1970 && read16(DEFAULT_DMIBAR
+ 0x3e) & 2) ;
1973 write_mchbar32(0x24, 0x10000 + info
->memory_reserved_for_heci_mb
);
1975 send_heci_uma_message(info
);
1977 pcie_write_config32(HECIDEV
, 0x10, 0x0);
1978 pcie_write_config8(HECIDEV
, 0x4, 0x0);
1982 static int have_match_ranks(struct raminfo
*info
, int channel
, int ranks
)
1984 int ranks_in_channel
;
1985 ranks_in_channel
= info
->populated_ranks
[channel
][0][0]
1986 + info
->populated_ranks
[channel
][0][1]
1987 + info
->populated_ranks
[channel
][1][0]
1988 + info
->populated_ranks
[channel
][1][1];
1991 if (ranks_in_channel
== 0)
1994 if (ranks_in_channel
!= ranks
)
1997 if (info
->populated_ranks
[channel
][0][0] !=
1998 info
->populated_ranks
[channel
][1][0])
2000 if (info
->populated_ranks
[channel
][0][1] !=
2001 info
->populated_ranks
[channel
][1][1])
2003 if (info
->is_x16_module
[channel
][0] != info
->is_x16_module
[channel
][1])
2005 if (info
->density
[channel
][0] != info
->density
[channel
][1])
2010 static void read_4090(struct raminfo
*info
)
2012 int i
, channel
, slot
, rank
, lane
;
2013 for (i
= 0; i
< 2; i
++)
2014 for (slot
= 0; slot
< NUM_SLOTS
; slot
++)
2015 for (rank
= 0; rank
< NUM_RANKS
; rank
++)
2016 for (lane
= 0; lane
< 9; lane
++)
2018 lane_timings
[0][i
][slot
][rank
][lane
]
2021 for (i
= 1; i
< 4; i
++)
2022 for (channel
= 0; channel
< NUM_CHANNELS
; channel
++)
2023 for (slot
= 0; slot
< NUM_SLOTS
; slot
++)
2024 for (rank
= 0; rank
< NUM_RANKS
; rank
++)
2025 for (lane
= 0; lane
< 9; lane
++) {
2027 lane_timings
[i
][channel
]
2028 [slot
][rank
][lane
] =
2029 read_500(info
, channel
,
2030 get_timing_register_addr
2033 + (i
== 1) * 11; // !!!!
2038 static u32
get_etalon2(int flip
, u32 addr
)
2040 const u16 invmask
[] = {
2041 0xaaaa, 0x6db6, 0x4924, 0xeeee, 0xcccc, 0x8888, 0x7bde, 0x739c,
2042 0x6318, 0x4210, 0xefbe, 0xcf3c, 0x8e38, 0x0c30, 0x0820
2045 u32 comp4
= addr
/ 480;
2047 u32 comp1
= addr
& 0xf;
2048 u32 comp2
= (addr
>> 4) & 1;
2049 u32 comp3
= addr
>> 5;
2052 ret
= 0x1010101 << (comp4
- 1);
2055 if (flip
^ (((invmask
[comp3
] >> comp1
) ^ comp2
) & 1))
2061 static void disable_cache(void)
2063 msr_t msr
= {.lo
= 0, .hi
= 0 };
2065 wrmsr(MTRR_PHYS_BASE(3), msr
);
2066 wrmsr(MTRR_PHYS_MASK(3), msr
);
2069 static void enable_cache(unsigned int base
, unsigned int size
)
2072 msr
.lo
= base
| MTRR_TYPE_WRPROT
;
2074 wrmsr(MTRR_PHYS_BASE(3), msr
);
2075 msr
.lo
= ((~(ALIGN_DOWN(size
+ 4096, 4096) - 1) | MTRR_DEF_TYPE_EN
)
2077 msr
.hi
= 0x0000000f;
2078 wrmsr(MTRR_PHYS_MASK(3), msr
);
2081 static void flush_cache(u32 start
, u32 size
)
2086 end
= start
+ (ALIGN_DOWN(size
+ 4096, 4096));
2087 for (addr
= start
; addr
< end
; addr
+= 64)
2091 static void clear_errors(void)
2093 pcie_write_config8(NORTHBRIDGE
, 0xc0, 0x01);
2096 static void write_testing(struct raminfo
*info
, int totalrank
, int flip
)
2099 /* in 8-byte units. */
2103 base
= (u8
*)(totalrank
<< 28);
2104 for (offset
= 0; offset
< 9 * 480; offset
+= 2) {
2105 write32(base
+ offset
* 8, get_etalon2(flip
, offset
));
2106 write32(base
+ offset
* 8 + 4, get_etalon2(flip
, offset
));
2107 write32(base
+ offset
* 8 + 8, get_etalon2(flip
, offset
+ 1));
2108 write32(base
+ offset
* 8 + 12, get_etalon2(flip
, offset
+ 1));
2110 if (nwrites
>= 320) {
2117 static u8
check_testing(struct raminfo
*info
, u8 total_rank
, int flip
)
2121 int comp1
, comp2
, comp3
;
2122 u32 failxor
[2] = { 0, 0 };
2124 enable_cache((total_rank
<< 28), 1728 * 5 * 4);
2126 for (comp3
= 0; comp3
< 9 && failmask
!= 0xff; comp3
++) {
2127 for (comp1
= 0; comp1
< 4; comp1
++)
2128 for (comp2
= 0; comp2
< 60; comp2
++) {
2131 comp3
* 8 * 60 + 2 * comp1
+ 8 * comp2
;
2132 read128((total_rank
<< 28) | (curroffset
<< 3),
2135 get_etalon2(flip
, curroffset
) ^ re
[0];
2137 get_etalon2(flip
, curroffset
) ^ re
[1];
2139 get_etalon2(flip
, curroffset
| 1) ^ re
[2];
2141 get_etalon2(flip
, curroffset
| 1) ^ re
[3];
2143 for (i
= 0; i
< 8; i
++)
2144 if ((0xff << (8 * (i
% 4))) & failxor
[i
/ 4])
2148 flush_cache((total_rank
<< 28), 1728 * 5 * 4);
2152 const u32 seed1
[0x18] = {
2153 0x3a9d5ab5, 0x576cb65b, 0x555773b6, 0x2ab772ee,
2154 0x555556ee, 0x3a9d5ab5, 0x576cb65b, 0x555773b6,
2155 0x2ab772ee, 0x555556ee, 0x5155a555, 0x5155a555,
2156 0x5155a555, 0x5155a555, 0x3a9d5ab5, 0x576cb65b,
2157 0x555773b6, 0x2ab772ee, 0x555556ee, 0x55d6b4a5,
2158 0x366d6b3a, 0x2ae5ddbb, 0x3b9ddbb7, 0x55d6b4a5,
2161 static u32
get_seed2(int a
, int b
)
2163 const u32 seed2
[5] = {
2164 0x55555555, 0x33333333, 0x2e555a55, 0x55555555,
2168 r
= seed2
[(a
+ (a
>= 10)) / 5];
2172 static int make_shift(int comp2
, int comp5
, int x
)
2174 const u8 seed3
[32] = {
2175 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2176 0x00, 0x00, 0x38, 0x1c, 0x3c, 0x18, 0x38, 0x38,
2177 0x38, 0x38, 0x38, 0x38, 0x0f, 0x0f, 0x0f, 0x0f,
2178 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
2181 return (comp2
- ((seed3
[comp5
] >> (x
& 7)) & 1)) & 0x1f;
2184 static u32
get_etalon(int flip
, u32 addr
)
2187 int comp1
= (addr
>> 1) & 1;
2188 int comp2
= (addr
>> 3) & 0x1f;
2189 int comp3
= (addr
>> 8) & 0xf;
2190 int comp4
= (addr
>> 12) & 0xf;
2191 int comp5
= (addr
>> 16) & 0x1f;
2192 u32 mask_bit
= ~(0x10001 << comp3
);
2199 make_shift(comp2
, comp5
,
2200 (comp3
>> 3) | (comp1
<< 2) | 2)) & 1) ^ flip
;
2203 make_shift(comp2
, comp5
,
2204 (comp3
>> 3) | (comp1
<< 2) | 0)) & 1) ^ flip
;
2206 for (byte
= 0; byte
< 4; byte
++)
2207 if ((get_seed2(comp5
, comp4
) >>
2208 make_shift(comp2
, comp5
, (byte
| (comp1
<< 2)))) & 1)
2209 mask_byte
|= 0xff << (8 * byte
);
2211 return (mask_bit
& mask_byte
) | (part1
<< comp3
) | (part2
<<
2216 write_testing_type2(struct raminfo
*info
, u8 totalrank
, u8 region
, u8 block
,
2220 for (i
= 0; i
< 2048; i
++)
2221 write32p((totalrank
<< 28) | (region
<< 25) | (block
<< 16) |
2222 (i
<< 2), get_etalon(flip
, (block
<< 16) | (i
<< 2)));
2226 check_testing_type2(struct raminfo
*info
, u8 totalrank
, u8 region
, u8 block
,
2232 int comp1
, comp2
, comp3
;
2237 enable_cache(totalrank
<< 28, 134217728);
2238 for (comp3
= 0; comp3
< 2 && failmask
!= 0xff; comp3
++) {
2239 for (comp1
= 0; comp1
< 16; comp1
++)
2240 for (comp2
= 0; comp2
< 64; comp2
++) {
2242 (totalrank
<< 28) | (region
<< 25) | (block
2244 | (comp3
<< 12) | (comp2
<< 6) | (comp1
<<
2246 failxor
[comp1
& 1] |=
2247 read32p(addr
) ^ get_etalon(flip
, addr
);
2249 for (i
= 0; i
< 8; i
++)
2250 if ((0xff << (8 * (i
% 4))) & failxor
[i
/ 4])
2254 flush_cache((totalrank
<< 28) | (region
<< 25) | (block
<< 16), 16384);
2258 static int check_bounded(unsigned short *vals
, u16 bound
)
2262 for (i
= 0; i
< 8; i
++)
2263 if (vals
[i
] < bound
)
2269 BEFORE_USABLE
= 0, AT_USABLE
= 1, AT_MARGIN
= 2, COMPLETE
= 3
2272 static int validate_state(enum state
*in
)
2275 for (i
= 0; i
< 8; i
++)
2276 if (in
[i
] != COMPLETE
)
2282 do_fsm(enum state
*state
, u16
* counter
,
2283 u8 fail_mask
, int margin
, int uplimit
,
2284 u8
* res_low
, u8
* res_high
, u8 val
)
2288 for (lane
= 0; lane
< 8; lane
++) {
2289 int is_fail
= (fail_mask
>> lane
) & 1;
2290 switch (state
[lane
]) {
2294 state
[lane
] = AT_USABLE
;
2298 state
[lane
] = BEFORE_USABLE
;
2303 if (counter
[lane
] >= margin
) {
2304 state
[lane
] = AT_MARGIN
;
2305 res_low
[lane
] = val
- margin
+ 1;
2312 state
[lane
] = BEFORE_USABLE
;
2316 state
[lane
] = COMPLETE
;
2317 res_high
[lane
] = val
- 1;
2320 state
[lane
] = AT_MARGIN
;
2321 if (val
== uplimit
) {
2322 state
[lane
] = COMPLETE
;
2323 res_high
[lane
] = uplimit
;
2334 train_ram_at_178(struct raminfo
*info
, u8 channel
, int slot
, int rank
,
2335 u8 total_rank
, u8 reg_178
, int first_run
, int niter
,
2336 timing_bounds_t
* timings
)
2339 enum state state
[8];
2343 unsigned short num_sucessfully_checked
[8];
2344 u8 secondary_total_rank
;
2347 if (info
->populated_ranks_mask
[1]) {
2349 secondary_total_rank
=
2350 info
->populated_ranks
[1][0][0] +
2351 info
->populated_ranks
[1][0][1]
2352 + info
->populated_ranks
[1][1][0] +
2353 info
->populated_ranks
[1][1][1];
2355 secondary_total_rank
= 0;
2357 secondary_total_rank
= total_rank
;
2361 for (i
= 0; i
< 8; i
++)
2362 state
[i
] = BEFORE_USABLE
;
2367 for (lane
= 0; lane
< 8; lane
++)
2368 if (timings
[reg_178
][channel
][slot
][rank
][lane
].
2370 timings
[reg_178
][channel
][slot
][rank
][lane
].
2372 timings
[reg_178
][channel
][slot
][rank
][lane
].
2374 timings
[reg_178
][channel
][slot
][rank
][lane
].
2380 for (i
= 0; i
< 8; i
++)
2381 state
[i
] = COMPLETE
;
2385 for (reg1b3
= 0; reg1b3
< 0x30 && !validate_state(state
); reg1b3
++) {
2387 write_1d0(reg1b3
^ 32, 0x1b3, 6, 1);
2388 write_1d0(reg1b3
^ 32, 0x1a3, 6, 1);
2389 failmask
= check_testing(info
, total_rank
, 0);
2390 write_mchbar32(0xfb0, read_mchbar32(0xfb0) | 0x00030000);
2391 do_fsm(state
, count
, failmask
, 5, 47, lower_usable
,
2392 upper_usable
, reg1b3
);
2396 write_1d0(0, 0x1b3, 6, 1);
2397 write_1d0(0, 0x1a3, 6, 1);
2398 for (lane
= 0; lane
< 8; lane
++) {
2399 if (state
[lane
] == COMPLETE
) {
2400 timings
[reg_178
][channel
][slot
][rank
][lane
].
2402 lower_usable
[lane
] +
2404 lane_timings
[0][channel
][slot
][rank
][lane
]
2406 timings
[reg_178
][channel
][slot
][rank
][lane
].
2408 upper_usable
[lane
] +
2410 lane_timings
[0][channel
][slot
][rank
][lane
]
2417 for (lane
= 0; lane
< 8; lane
++)
2418 if (state
[lane
] == COMPLETE
) {
2419 write_500(info
, channel
,
2420 timings
[reg_178
][channel
][slot
][rank
]
2422 get_timing_register_addr(lane
, 0,
2425 write_500(info
, channel
,
2426 timings
[reg_178
][channel
][slot
][rank
]
2429 lane_timings
[1][channel
][slot
][rank
]
2433 lane_timings
[0][channel
][slot
][rank
]
2434 [lane
], get_timing_register_addr(lane
,
2439 num_sucessfully_checked
[lane
] = 0;
2441 num_sucessfully_checked
[lane
] = -1;
2446 for (i
= 0; i
< niter
; i
++) {
2447 if (failmask
== 0xFF)
2450 check_testing_type2(info
, total_rank
, 2, i
,
2453 check_testing_type2(info
, total_rank
, 3, i
,
2456 write_mchbar32(0xfb0,
2457 read_mchbar32(0xfb0) | 0x00030000);
2458 for (lane
= 0; lane
< 8; lane
++)
2459 if (num_sucessfully_checked
[lane
] != 0xffff) {
2460 if ((1 << lane
) & failmask
) {
2461 if (timings
[reg_178
][channel
]
2464 timings
[reg_178
][channel
]
2465 [slot
][rank
][lane
].smallest
)
2466 num_sucessfully_checked
2469 num_sucessfully_checked
2475 write_500(info
, channel
,
2482 get_timing_register_addr
2486 write_500(info
, channel
,
2506 get_timing_register_addr
2512 num_sucessfully_checked
[lane
]++;
2515 while (!check_bounded(num_sucessfully_checked
, 2));
2517 for (lane
= 0; lane
< 8; lane
++)
2518 if (state
[lane
] == COMPLETE
) {
2519 write_500(info
, channel
,
2520 timings
[reg_178
][channel
][slot
][rank
]
2522 get_timing_register_addr(lane
, 0,
2525 write_500(info
, channel
,
2526 timings
[reg_178
][channel
][slot
][rank
]
2529 lane_timings
[1][channel
][slot
][rank
]
2533 lane_timings
[0][channel
][slot
][rank
]
2534 [lane
], get_timing_register_addr(lane
,
2539 num_sucessfully_checked
[lane
] = 0;
2541 num_sucessfully_checked
[lane
] = -1;
2546 for (i
= 0; i
< niter
; i
++) {
2547 if (failmask
== 0xFF)
2550 check_testing_type2(info
, total_rank
, 2, i
,
2553 check_testing_type2(info
, total_rank
, 3, i
,
2557 write_mchbar32(0xfb0,
2558 read_mchbar32(0xfb0) | 0x00030000);
2559 for (lane
= 0; lane
< 8; lane
++) {
2560 if (num_sucessfully_checked
[lane
] != 0xffff) {
2561 if ((1 << lane
) & failmask
) {
2562 if (timings
[reg_178
][channel
]
2565 timings
[reg_178
][channel
]
2568 num_sucessfully_checked
2571 num_sucessfully_checked
2577 write_500(info
, channel
,
2584 get_timing_register_addr
2588 write_500(info
, channel
,
2608 get_timing_register_addr
2614 num_sucessfully_checked
[lane
]++;
2618 while (!check_bounded(num_sucessfully_checked
, 3));
2620 for (lane
= 0; lane
< 8; lane
++) {
2621 write_500(info
, channel
,
2623 lane_timings
[0][channel
][slot
][rank
][lane
],
2624 get_timing_register_addr(lane
, 0, slot
, rank
),
2626 write_500(info
, channel
,
2628 lane_timings
[1][channel
][slot
][rank
][lane
],
2629 get_timing_register_addr(lane
, 1, slot
, rank
),
2631 if (timings
[reg_178
][channel
][slot
][rank
][lane
].
2633 timings
[reg_178
][channel
][slot
][rank
][lane
].
2635 timings
[reg_178
][channel
][slot
][rank
][lane
].
2637 timings
[reg_178
][channel
][slot
][rank
][lane
].
2644 static void set_10b(struct raminfo
*info
, u8 val
)
2650 if (read_1d0(0x10b, 6) == val
)
2653 write_1d0(val
, 0x10b, 6, 1);
2655 FOR_POPULATED_RANKS_BACKWARDS
for (lane
= 0; lane
< 9; lane
++) {
2657 reg_500
= read_500(info
, channel
,
2658 get_timing_register_addr(lane
, 0, slot
,
2661 if (lut16
[info
->clock_speed_index
] <= reg_500
)
2662 reg_500
-= lut16
[info
->clock_speed_index
];
2666 reg_500
+= lut16
[info
->clock_speed_index
];
2668 write_500(info
, channel
, reg_500
,
2669 get_timing_register_addr(lane
, 0, slot
, rank
), 9, 1);
2673 static void set_ecc(int onoff
)
2676 for (channel
= 0; channel
< NUM_CHANNELS
; channel
++) {
2678 t
= read_mchbar8((channel
<< 10) + 0x5f8);
2683 write_mchbar8((channel
<< 10) + 0x5f8, t
);
2687 static void set_178(u8 val
)
2694 write_1d0(2 * val
, 0x178, 7, 1);
2698 write_500_timings_type(struct raminfo
*info
, int channel
, int slot
, int rank
,
2703 for (lane
= 0; lane
< 8; lane
++)
2704 write_500(info
, channel
,
2706 lane_timings
[type
][channel
][slot
][rank
][lane
],
2707 get_timing_register_addr(lane
, type
, slot
, rank
), 9,
2712 try_timing_offsets(struct raminfo
*info
, int channel
,
2713 int slot
, int rank
, int totalrank
)
2716 enum state state
[8];
2717 u8 lower_usable
[8], upper_usable
[8];
2723 for (i
= 0; i
< 8; i
++)
2724 state
[i
] = BEFORE_USABLE
;
2726 memset(count
, 0, sizeof(count
));
2728 for (lane
= 0; lane
< 8; lane
++)
2729 write_500(info
, channel
,
2731 lane_timings
[2][channel
][slot
][rank
][lane
] + 32,
2732 get_timing_register_addr(lane
, 3, slot
, rank
), 9, 1);
2734 for (timing_offset
= 0; !validate_state(state
) && timing_offset
< 64;
2737 write_1d0(timing_offset
^ 32, 0x1bb, 6, 1);
2739 for (i
= 0; i
< 2 && failmask
!= 0xff; i
++) {
2741 write_testing(info
, totalrank
, flip
);
2742 failmask
|= check_testing(info
, totalrank
, flip
);
2744 do_fsm(state
, count
, failmask
, 10, 63, lower_usable
,
2745 upper_usable
, timing_offset
);
2747 write_1d0(0, 0x1bb, 6, 1);
2749 if (!validate_state(state
))
2750 die("Couldn't discover DRAM timings (1)\n");
2752 for (lane
= 0; lane
< 8; lane
++) {
2755 if (info
->silicon_revision
) {
2758 usable_length
= upper_usable
[lane
] - lower_usable
[lane
];
2759 if (usable_length
>= 20) {
2760 bias
= usable_length
/ 2 - 10;
2765 write_500(info
, channel
,
2767 lane_timings
[2][channel
][slot
][rank
][lane
] +
2768 (upper_usable
[lane
] + lower_usable
[lane
]) / 2 - bias
,
2769 get_timing_register_addr(lane
, 3, slot
, rank
), 9, 1);
2770 info
->training
.timing2_bounds
[channel
][slot
][rank
][lane
][0] =
2771 info
->training
.lane_timings
[2][channel
][slot
][rank
][lane
] +
2773 info
->training
.timing2_bounds
[channel
][slot
][rank
][lane
][1] =
2774 info
->training
.lane_timings
[2][channel
][slot
][rank
][lane
] +
2776 info
->training
.timing2_offset
[channel
][slot
][rank
][lane
] =
2777 info
->training
.lane_timings
[2][channel
][slot
][rank
][lane
];
2782 choose_training(struct raminfo
*info
, int channel
, int slot
, int rank
,
2783 int lane
, timing_bounds_t
* timings
, u8 center_178
)
2787 unsigned int sum
= 0, count
= 0;
2789 u8 lower_margin
, upper_margin
;
2794 central_weight
= 20;
2796 if (info
->silicon_revision
== 1 && channel
== 1) {
2800 populated_ranks_mask
[1] ^ (info
->
2801 populated_ranks_mask
[1] >> 2)) &
2805 if ((info
->populated_ranks_mask
[0] & 5) == 5) {
2806 central_weight
= 20;
2809 if (info
->clock_speed_index
>= 2
2810 && (info
->populated_ranks_mask
[0] & 5) == 5 && slot
== 1) {
2811 if (info
->silicon_revision
== 1) {
2815 central_weight
= 10;
2822 central_weight
= 20;
2827 if (info
->silicon_revision
== 0 && channel
== 0 && lane
== 0) {
2829 central_weight
= 20;
2832 for (reg_178
= center_178
- span
; reg_178
<= center_178
+ span
;
2836 largest
= timings
[reg_178
][channel
][slot
][rank
][lane
].largest
;
2837 smallest
= timings
[reg_178
][channel
][slot
][rank
][lane
].smallest
;
2838 if (largest
- smallest
+ 1 >= 5) {
2839 unsigned int weight
;
2840 if (reg_178
== center_178
)
2841 weight
= central_weight
;
2843 weight
= side_weight
;
2844 sum
+= weight
* (largest
+ smallest
);
2850 die("Couldn't discover DRAM timings (2)\n");
2851 result
= sum
/ (2 * count
);
2853 result
- timings
[center_178
][channel
][slot
][rank
][lane
].smallest
;
2855 timings
[center_178
][channel
][slot
][rank
][lane
].largest
- result
;
2856 if (upper_margin
< 10 && lower_margin
> 10)
2857 result
-= min(lower_margin
- 10, 10 - upper_margin
);
2858 if (upper_margin
> 10 && lower_margin
< 10)
2859 result
+= min(upper_margin
- 10, 10 - lower_margin
);
2863 #define STANDARD_MIN_MARGIN 5
2865 static u8
choose_reg178(struct raminfo
*info
, timing_bounds_t
* timings
)
2868 int lane
, rank
, slot
, channel
;
2870 int count
= 0, sum
= 0;
2872 for (reg178
= reg178_min
[info
->clock_speed_index
];
2873 reg178
< reg178_max
[info
->clock_speed_index
];
2874 reg178
+= reg178_step
[info
->clock_speed_index
]) {
2875 margin
[reg178
] = -1;
2876 FOR_POPULATED_RANKS_BACKWARDS
for (lane
= 0; lane
< 8; lane
++) {
2878 timings
[reg178
][channel
][slot
][rank
][lane
].largest
-
2879 timings
[reg178
][channel
][slot
][rank
][lane
].
2881 if (curmargin
< margin
[reg178
])
2882 margin
[reg178
] = curmargin
;
2884 if (margin
[reg178
] >= STANDARD_MIN_MARGIN
) {
2886 weight
= margin
[reg178
] - STANDARD_MIN_MARGIN
;
2887 sum
+= weight
* reg178
;
2893 die("Couldn't discover DRAM timings (3)\n");
2897 for (threshold
= 30; threshold
>= 5; threshold
--) {
2898 int usable_length
= 0;
2899 int smallest_fount
= 0;
2900 for (reg178
= reg178_min
[info
->clock_speed_index
];
2901 reg178
< reg178_max
[info
->clock_speed_index
];
2902 reg178
+= reg178_step
[info
->clock_speed_index
])
2903 if (margin
[reg178
] >= threshold
) {
2905 reg178_step
[info
->clock_speed_index
];
2906 info
->training
.reg178_largest
=
2908 2 * reg178_step
[info
->clock_speed_index
];
2910 if (!smallest_fount
) {
2912 info
->training
.reg178_smallest
=
2918 if (usable_length
>= 0x21)
2925 static int check_cached_sanity(struct raminfo
*info
)
2931 if (!info
->cached_training
)
2934 for (channel
= 0; channel
< NUM_CHANNELS
; channel
++)
2935 for (slot
= 0; slot
< NUM_SLOTS
; slot
++)
2936 for (rank
= 0; rank
< NUM_RANKS
; rank
++)
2937 for (lane
= 0; lane
< 8 + info
->use_ecc
; lane
++) {
2938 u16 cached_value
, estimation_value
;
2940 info
->cached_training
->
2941 lane_timings
[1][channel
][slot
][rank
]
2943 if (cached_value
>= 0x18
2944 && cached_value
<= 0x1E7) {
2947 lane_timings
[1][channel
]
2949 if (estimation_value
<
2952 if (estimation_value
>
2960 static int try_cached_training(struct raminfo
*info
)
2965 int channel
, slot
, rank
, lane
;
2969 if (!check_cached_sanity(info
))
2972 info
->training
.reg178_center
= info
->cached_training
->reg178_center
;
2973 info
->training
.reg178_smallest
= info
->cached_training
->reg178_smallest
;
2974 info
->training
.reg178_largest
= info
->cached_training
->reg178_largest
;
2975 memcpy(&info
->training
.timing_bounds
,
2976 &info
->cached_training
->timing_bounds
,
2977 sizeof(info
->training
.timing_bounds
));
2978 memcpy(&info
->training
.timing_offset
,
2979 &info
->cached_training
->timing_offset
,
2980 sizeof(info
->training
.timing_offset
));
2982 write_1d0(2, 0x142, 3, 1);
2983 saved_243
[0] = read_mchbar8(0x243);
2984 saved_243
[1] = read_mchbar8(0x643);
2985 write_mchbar8(0x243, saved_243
[0] | 2);
2986 write_mchbar8(0x643, saved_243
[1] | 2);
2988 pcie_write_config16(NORTHBRIDGE
, 0xc8, 3);
2989 if (read_1d0(0x10b, 6) & 1)
2991 for (tm
= 0; tm
< 2; tm
++) {
2994 set_178(tm
? info
->cached_training
->reg178_largest
: info
->
2995 cached_training
->reg178_smallest
);
2998 /* Check timing ranges. With i == 0 we check smallest one and with
2999 i == 1 the largest bound. With j == 0 we check that on the bound
3000 it still works whereas with j == 1 we check that just outside of
3003 FOR_POPULATED_RANKS_BACKWARDS
{
3004 for (i
= 0; i
< 2; i
++) {
3005 for (lane
= 0; lane
< 8; lane
++) {
3006 write_500(info
, channel
,
3007 info
->cached_training
->
3008 timing2_bounds
[channel
][slot
]
3010 get_timing_register_addr(lane
,
3017 write_500(info
, channel
,
3021 [channel
][slot
][rank
]
3023 get_timing_register_addr
3024 (lane
, 2, slot
, rank
),
3026 write_500(info
, channel
,
3027 i
? info
->cached_training
->
3028 timing_bounds
[tm
][channel
]
3032 timing_bounds
[tm
][channel
]
3033 [slot
][rank
][lane
].smallest
,
3034 get_timing_register_addr(lane
,
3039 write_500(info
, channel
,
3040 info
->cached_training
->
3041 timing_offset
[channel
][slot
]
3043 (i
? info
->cached_training
->
3044 timing_bounds
[tm
][channel
]
3048 timing_bounds
[tm
][channel
]
3051 get_timing_register_addr(lane
,
3057 for (j
= 0; j
< 2; j
++) {
3059 u8 expected_failmask
;
3062 reg1b3
= (j
== 1) + 4;
3064 j
== i
? reg1b3
: (-reg1b3
) & 0x3f;
3065 write_1d0(reg1b3
, 0x1bb, 6, 1);
3066 write_1d0(reg1b3
, 0x1b3, 6, 1);
3067 write_1d0(reg1b3
, 0x1a3, 6, 1);
3070 write_testing(info
, totalrank
, flip
);
3072 check_testing(info
, totalrank
,
3075 j
== 0 ? 0x00 : 0xff;
3076 if (failmask
!= expected_failmask
)
3084 set_178(info
->cached_training
->reg178_center
);
3087 write_training_data(info
);
3088 write_1d0(0, 322, 3, 1);
3089 info
->training
= *info
->cached_training
;
3091 write_1d0(0, 0x1bb, 6, 1);
3092 write_1d0(0, 0x1b3, 6, 1);
3093 write_1d0(0, 0x1a3, 6, 1);
3094 write_mchbar8(0x243, saved_243
[0]);
3095 write_mchbar8(0x643, saved_243
[1]);
3100 FOR_POPULATED_RANKS
{
3101 write_500_timings_type(info
, channel
, slot
, rank
, 1);
3102 write_500_timings_type(info
, channel
, slot
, rank
, 2);
3103 write_500_timings_type(info
, channel
, slot
, rank
, 3);
3106 write_1d0(0, 0x1bb, 6, 1);
3107 write_1d0(0, 0x1b3, 6, 1);
3108 write_1d0(0, 0x1a3, 6, 1);
3109 write_mchbar8(0x243, saved_243
[0]);
3110 write_mchbar8(0x643, saved_243
[1]);
3115 static void do_ram_training(struct raminfo
*info
)
3122 timing_bounds_t timings
[64];
3123 int lane
, rank
, slot
, channel
;
3126 write_1d0(2, 0x142, 3, 1);
3127 saved_243
[0] = read_mchbar8(0x243);
3128 saved_243
[1] = read_mchbar8(0x643);
3129 write_mchbar8(0x243, saved_243
[0] | 2);
3130 write_mchbar8(0x643, saved_243
[1] | 2);
3131 switch (info
->clock_speed_index
) {
3144 FOR_POPULATED_RANKS_BACKWARDS
{
3147 write_500_timings_type(info
, channel
, slot
, rank
, 0);
3149 write_testing(info
, totalrank
, 0);
3150 for (i
= 0; i
< niter
; i
++) {
3151 write_testing_type2(info
, totalrank
, 2, i
, 0);
3152 write_testing_type2(info
, totalrank
, 3, i
, 1);
3154 pcie_write_config8(NORTHBRIDGE
, 0xc0, 0x01);
3158 if (reg178_min
[info
->clock_speed_index
] <
3159 reg178_max
[info
->clock_speed_index
])
3160 memset(timings
[reg178_min
[info
->clock_speed_index
]], 0,
3161 sizeof(timings
[0]) *
3162 (reg178_max
[info
->clock_speed_index
] -
3163 reg178_min
[info
->clock_speed_index
]));
3164 for (reg_178
= reg178_min
[info
->clock_speed_index
];
3165 reg_178
< reg178_max
[info
->clock_speed_index
];
3166 reg_178
+= reg178_step
[info
->clock_speed_index
]) {
3169 for (channel
= NUM_CHANNELS
- 1; channel
>= 0; channel
--)
3170 for (slot
= 0; slot
< NUM_SLOTS
; slot
++)
3171 for (rank
= 0; rank
< NUM_RANKS
; rank
++) {
3172 memset(&timings
[reg_178
][channel
][slot
]
3173 [rank
][0].smallest
, 0, 16);
3175 populated_ranks
[channel
][slot
]
3177 train_ram_at_178(info
, channel
,
3188 reg178_center
= choose_reg178(info
, timings
);
3190 FOR_POPULATED_RANKS_BACKWARDS
for (lane
= 0; lane
< 8; lane
++) {
3191 info
->training
.timing_bounds
[0][channel
][slot
][rank
][lane
].
3193 timings
[info
->training
.
3194 reg178_smallest
][channel
][slot
][rank
][lane
].
3196 info
->training
.timing_bounds
[0][channel
][slot
][rank
][lane
].
3198 timings
[info
->training
.
3199 reg178_smallest
][channel
][slot
][rank
][lane
].largest
;
3200 info
->training
.timing_bounds
[1][channel
][slot
][rank
][lane
].
3202 timings
[info
->training
.
3203 reg178_largest
][channel
][slot
][rank
][lane
].smallest
;
3204 info
->training
.timing_bounds
[1][channel
][slot
][rank
][lane
].
3206 timings
[info
->training
.
3207 reg178_largest
][channel
][slot
][rank
][lane
].largest
;
3208 info
->training
.timing_offset
[channel
][slot
][rank
][lane
] =
3209 info
->training
.lane_timings
[1][channel
][slot
][rank
][lane
]
3211 info
->training
.lane_timings
[0][channel
][slot
][rank
][lane
] +
3215 if (info
->silicon_revision
== 1
3217 populated_ranks_mask
[1] ^ (info
->
3218 populated_ranks_mask
[1] >> 2)) & 1) {
3219 int ranks_after_channel1
;
3222 for (reg_178
= reg178_center
- 18;
3223 reg_178
<= reg178_center
+ 18; reg_178
+= 18) {
3226 for (slot
= 0; slot
< NUM_SLOTS
; slot
++)
3227 for (rank
= 0; rank
< NUM_RANKS
; rank
++) {
3229 populated_ranks
[1][slot
][rank
]) {
3230 train_ram_at_178(info
, 1, slot
,
3240 ranks_after_channel1
= totalrank
;
3242 for (reg_178
= reg178_center
- 12;
3243 reg_178
<= reg178_center
+ 12; reg_178
+= 12) {
3244 totalrank
= ranks_after_channel1
;
3246 for (slot
= 0; slot
< NUM_SLOTS
; slot
++)
3247 for (rank
= 0; rank
< NUM_RANKS
; rank
++)
3249 populated_ranks
[0][slot
][rank
]) {
3250 train_ram_at_178(info
, 0, slot
,
3261 for (reg_178
= reg178_center
- 12;
3262 reg_178
<= reg178_center
+ 12; reg_178
+= 12) {
3265 FOR_POPULATED_RANKS_BACKWARDS
{
3266 train_ram_at_178(info
, channel
, slot
, rank
,
3267 totalrank
, reg_178
, 0, niter
,
3274 set_178(reg178_center
);
3275 FOR_POPULATED_RANKS_BACKWARDS
for (lane
= 0; lane
< 8; lane
++) {
3279 choose_training(info
, channel
, slot
, rank
, lane
, timings
,
3281 write_500(info
, channel
, tm0
,
3282 get_timing_register_addr(lane
, 0, slot
, rank
), 9, 1);
3283 write_500(info
, channel
,
3286 lane_timings
[1][channel
][slot
][rank
][lane
] -
3288 lane_timings
[0][channel
][slot
][rank
][lane
],
3289 get_timing_register_addr(lane
, 1, slot
, rank
), 9, 1);
3293 FOR_POPULATED_RANKS_BACKWARDS
{
3294 try_timing_offsets(info
, channel
, slot
, rank
, totalrank
);
3297 write_mchbar8(0x243, saved_243
[0]);
3298 write_mchbar8(0x643, saved_243
[1]);
3299 write_1d0(0, 0x142, 3, 1);
3300 info
->training
.reg178_center
= reg178_center
;
3303 static void ram_training(struct raminfo
*info
)
3307 saved_fc4
= read_mchbar16(0xfc4);
3308 write_mchbar16(0xfc4, 0xffff);
3310 if (info
->revision
>= 8)
3313 if (!try_cached_training(info
))
3314 do_ram_training(info
);
3315 if ((info
->silicon_revision
== 2 || info
->silicon_revision
== 3)
3316 && info
->clock_speed_index
< 2)
3318 write_mchbar16(0xfc4, saved_fc4
);
3321 static unsigned gcd(unsigned a
, unsigned b
)
3329 /* invariant a < b. */
3338 static inline int div_roundup(int a
, int b
)
3340 return CEIL_DIV(a
, b
);
3343 static unsigned lcm(unsigned a
, unsigned b
)
3345 return (a
* b
) / gcd(a
, b
);
3350 u8 freq_diff_reduced
;
3351 u8 freq_min_reduced
;
3352 u8 divisor_f4_to_fmax
;
3353 u8 divisor_f3_to_fmax
;
3354 u8 freq4_to_max_remainder
;
3355 u8 freq3_to_2_remainder
;
3356 u8 freq3_to_2_remaindera
;
3357 u8 freq4_to_2_remainder
;
3358 int divisor_f3_to_f1
, divisor_f4_to_f2
;
3359 int common_time_unit_ps
;
3360 int freq_max_reduced
;
3364 compute_frequence_ratios(struct raminfo
*info
, u16 freq1
, u16 freq2
,
3365 int num_cycles_2
, int num_cycles_1
, int round_it
,
3366 int add_freqs
, struct stru1
*result
)
3369 int common_time_unit_ps
;
3370 int freq1_reduced
, freq2_reduced
;
3371 int freq_min_reduced
;
3372 int freq_max_reduced
;
3375 g
= gcd(freq1
, freq2
);
3376 freq1_reduced
= freq1
/ g
;
3377 freq2_reduced
= freq2
/ g
;
3378 freq_min_reduced
= min(freq1_reduced
, freq2_reduced
);
3379 freq_max_reduced
= max(freq1_reduced
, freq2_reduced
);
3381 common_time_unit_ps
= div_roundup(900000, lcm(freq1
, freq2
));
3382 freq3
= div_roundup(num_cycles_2
, common_time_unit_ps
) - 1;
3383 freq4
= div_roundup(num_cycles_1
, common_time_unit_ps
) - 1;
3385 freq3
+= freq2_reduced
;
3386 freq4
+= freq1_reduced
;
3390 result
->freq3_to_2_remainder
= 0;
3391 result
->freq3_to_2_remaindera
= 0;
3392 result
->freq4_to_max_remainder
= 0;
3393 result
->divisor_f4_to_f2
= 0;
3394 result
->divisor_f3_to_f1
= 0;
3396 if (freq2_reduced
< freq1_reduced
) {
3397 result
->freq3_to_2_remainder
=
3398 result
->freq3_to_2_remaindera
=
3399 freq3
% freq1_reduced
- freq1_reduced
+ 1;
3400 result
->freq4_to_max_remainder
=
3401 -(freq4
% freq1_reduced
);
3402 result
->divisor_f3_to_f1
= freq3
/ freq1_reduced
;
3403 result
->divisor_f4_to_f2
=
3405 (freq1_reduced
- freq2_reduced
)) / freq2_reduced
;
3406 result
->freq4_to_2_remainder
=
3407 -(char)((freq1_reduced
- freq2_reduced
) +
3410 freq2_reduced
)) % (u8
) freq2_reduced
);
3412 if (freq2_reduced
> freq1_reduced
) {
3413 result
->freq4_to_max_remainder
=
3414 (freq4
% freq2_reduced
) - freq2_reduced
+ 1;
3415 result
->freq4_to_2_remainder
=
3416 freq4
% freq_max_reduced
-
3417 freq_max_reduced
+ 1;
3419 result
->freq4_to_max_remainder
=
3420 -(freq4
% freq2_reduced
);
3421 result
->freq4_to_2_remainder
=
3422 -(char)(freq4
% freq_max_reduced
);
3424 result
->divisor_f4_to_f2
= freq4
/ freq2_reduced
;
3425 result
->divisor_f3_to_f1
=
3427 (freq2_reduced
- freq1_reduced
)) / freq1_reduced
;
3428 result
->freq3_to_2_remainder
= -(freq3
% freq2_reduced
);
3429 result
->freq3_to_2_remaindera
=
3430 -(char)((freq_max_reduced
- freq_min_reduced
) +
3433 freq_min_reduced
)) % freq1_reduced
);
3436 result
->divisor_f3_to_fmax
= freq3
/ freq_max_reduced
;
3437 result
->divisor_f4_to_fmax
= freq4
/ freq_max_reduced
;
3439 if (freq2_reduced
> freq1_reduced
) {
3440 if (freq3
% freq_max_reduced
)
3441 result
->divisor_f3_to_fmax
++;
3443 if (freq2_reduced
< freq1_reduced
) {
3444 if (freq4
% freq_max_reduced
)
3445 result
->divisor_f4_to_fmax
++;
3448 result
->freqs_reversed
= (freq2_reduced
< freq1_reduced
);
3449 result
->freq_diff_reduced
= freq_max_reduced
- freq_min_reduced
;
3450 result
->freq_min_reduced
= freq_min_reduced
;
3451 result
->common_time_unit_ps
= common_time_unit_ps
;
3452 result
->freq_max_reduced
= freq_max_reduced
;
3456 set_2d5x_reg(struct raminfo
*info
, u16 reg
, u16 freq1
, u16 freq2
,
3457 int num_cycles_2
, int num_cycles_1
, int num_cycles_3
,
3458 int num_cycles_4
, int reverse
)
3463 compute_frequence_ratios(info
, freq1
, freq2
, num_cycles_2
, num_cycles_1
,
3468 (div_roundup(num_cycles_2
, vv
.common_time_unit_ps
) +
3469 div_roundup(num_cycles_3
, vv
.common_time_unit_ps
),
3470 div_roundup(num_cycles_1
,
3471 vv
.common_time_unit_ps
) +
3472 div_roundup(num_cycles_4
, vv
.common_time_unit_ps
))
3473 + vv
.freq_min_reduced
- 1, vv
.freq_max_reduced
) - 1;
3476 (u8
) ((vv
.freq_max_reduced
- vv
.freq_min_reduced
) +
3477 vv
.freq_max_reduced
* multiplier
)
3479 freqs_reversed
<< 8) | ((u8
) (vv
.freq_min_reduced
*
3480 multiplier
) << 16) | ((u8
) (vv
.
3486 vv
.freq3_to_2_remaindera
| (vv
.freq4_to_2_remainder
<< 8) | (vv
.
3489 | (vv
.divisor_f4_to_f2
<< 20) | (vv
.freq_min_reduced
<< 24);
3491 write_mchbar32(reg
, y
);
3492 write_mchbar32(reg
+ 4, x
);
3494 write_mchbar32(reg
+ 4, y
);
3495 write_mchbar32(reg
, x
);
3500 set_6d_reg(struct raminfo
*info
, u16 reg
, u16 freq1
, u16 freq2
,
3501 int num_cycles_1
, int num_cycles_2
, int num_cycles_3
,
3504 struct stru1 ratios1
;
3505 struct stru1 ratios2
;
3507 compute_frequence_ratios(info
, freq1
, freq2
, num_cycles_1
, num_cycles_2
,
3509 compute_frequence_ratios(info
, freq1
, freq2
, num_cycles_3
, num_cycles_4
,
3511 printk (BIOS_SPEW
, "[%x] <= %x\n", reg
,
3512 ratios1
.freq4_to_max_remainder
| (ratios2
.
3513 freq4_to_max_remainder
3515 | (ratios1
.divisor_f4_to_fmax
<< 16) | (ratios2
.
3519 ratios1
.freq4_to_max_remainder
| (ratios2
.
3520 freq4_to_max_remainder
3522 | (ratios1
.divisor_f4_to_fmax
<< 16) | (ratios2
.
3528 set_2dx8_reg(struct raminfo
*info
, u16 reg
, u8 mode
, u16 freq1
, u16 freq2
,
3529 int num_cycles_2
, int num_cycles_1
, int round_it
, int add_freqs
)
3531 struct stru1 ratios
;
3533 compute_frequence_ratios(info
, freq1
, freq2
, num_cycles_2
, num_cycles_1
,
3534 round_it
, add_freqs
, &ratios
);
3537 write_mchbar32(reg
+ 4,
3538 ratios
.freq_diff_reduced
| (ratios
.
3542 ratios
.freq3_to_2_remainder
| (ratios
.
3543 freq4_to_max_remainder
3545 | (ratios
.divisor_f3_to_fmax
<< 16) | (ratios
.
3548 (ratios
.freq_min_reduced
<< 24));
3553 ratios
.freq3_to_2_remainder
| (ratios
.
3560 ratios
.freq3_to_2_remainder
| (ratios
.
3561 freq4_to_max_remainder
3565 (ratios
.divisor_f4_to_fmax
<< 20));
3569 write_mchbar32(reg
, (ratios
.divisor_f3_to_fmax
<< 4)
3570 | (ratios
.divisor_f4_to_fmax
<< 8) | (ratios
.
3573 (ratios
.freq_min_reduced
<< 16) | (ratios
.
3580 static void set_2dxx_series(struct raminfo
*info
, int s3resume
)
3582 set_2dx8_reg(info
, 0x2d00, 0, 0x78, frequency_11(info
) / 2, 1359, 1005,
3584 set_2dx8_reg(info
, 0x2d08, 0, 0x78, 0x78, 3273, 5033, 1, 1);
3585 set_2dx8_reg(info
, 0x2d10, 0, 0x78, info
->fsb_frequency
, 1475, 1131, 0,
3587 set_2dx8_reg(info
, 0x2d18, 0, 2 * info
->fsb_frequency
,
3588 frequency_11(info
), 1231, 1524, 0, 1);
3589 set_2dx8_reg(info
, 0x2d20, 0, 2 * info
->fsb_frequency
,
3590 frequency_11(info
) / 2, 1278, 2008, 0, 1);
3591 set_2dx8_reg(info
, 0x2d28, 0, info
->fsb_frequency
, frequency_11(info
),
3593 set_2dx8_reg(info
, 0x2d30, 0, info
->fsb_frequency
,
3594 frequency_11(info
) / 2, 1403, 1318, 0, 1);
3595 set_2dx8_reg(info
, 0x2d38, 0, info
->fsb_frequency
, 0x78, 3460, 5363, 1,
3597 set_2dx8_reg(info
, 0x2d40, 0, info
->fsb_frequency
, 0x3c, 2792, 5178, 1,
3599 set_2dx8_reg(info
, 0x2d48, 0, 2 * info
->fsb_frequency
, 0x78, 2738, 4610,
3601 set_2dx8_reg(info
, 0x2d50, 0, info
->fsb_frequency
, 0x78, 2819, 5932, 1,
3603 set_2dx8_reg(info
, 0x6d4, 1, info
->fsb_frequency
,
3604 frequency_11(info
) / 2, 4000, 0, 0, 0);
3605 set_2dx8_reg(info
, 0x6d8, 2, info
->fsb_frequency
,
3606 frequency_11(info
) / 2, 4000, 4000, 0, 0);
3609 printk (BIOS_SPEW
, "[6dc] <= %x\n", info
->cached_training
->reg_6dc
);
3610 write_mchbar32(0x6dc, info
->cached_training
->reg_6dc
);
3612 set_6d_reg(info
, 0x6dc, 2 * info
->fsb_frequency
, frequency_11(info
), 0,
3613 info
->delay46_ps
[0], 0,
3614 info
->delay54_ps
[0]);
3615 set_2dx8_reg(info
, 0x6e0, 1, 2 * info
->fsb_frequency
,
3616 frequency_11(info
), 2500, 0, 0, 0);
3617 set_2dx8_reg(info
, 0x6e4, 1, 2 * info
->fsb_frequency
,
3618 frequency_11(info
) / 2, 3500, 0, 0, 0);
3620 printk (BIOS_SPEW
, "[6e8] <= %x\n", info
->cached_training
->reg_6e8
);
3621 write_mchbar32(0x6e8, info
->cached_training
->reg_6e8
);
3623 set_6d_reg(info
, 0x6e8, 2 * info
->fsb_frequency
, frequency_11(info
), 0,
3624 info
->delay46_ps
[1], 0,
3625 info
->delay54_ps
[1]);
3626 set_2d5x_reg(info
, 0x2d58, 0x78, 0x78, 864, 1195, 762, 786, 0);
3627 set_2d5x_reg(info
, 0x2d60, 0x195, info
->fsb_frequency
, 1352, 725, 455,
3629 set_2d5x_reg(info
, 0x2d68, 0x195, 0x3c, 2707, 5632, 3277, 2207, 0);
3630 set_2d5x_reg(info
, 0x2d70, 0x195, frequency_11(info
) / 2, 1276, 758,
3632 set_2d5x_reg(info
, 0x2d78, 0x195, 0x78, 1021, 799, 510, 513, 0);
3633 set_2d5x_reg(info
, 0x2d80, info
->fsb_frequency
, 0xe1, 0, 2862, 2579,
3635 set_2d5x_reg(info
, 0x2d88, info
->fsb_frequency
, 0xe1, 0, 2690, 2405,
3637 set_2d5x_reg(info
, 0x2da0, 0x78, 0xe1, 0, 2560, 2264, 2251, 0);
3638 set_2d5x_reg(info
, 0x2da8, 0x195, frequency_11(info
), 1060, 775, 484,
3640 set_2d5x_reg(info
, 0x2db0, 0x195, 0x78, 4183, 6023, 2217, 2048, 0);
3641 write_mchbar32(0x2dbc, ((frequency_11(info
) / 2) - 1) | 0xe00000);
3642 write_mchbar32(0x2db8, ((info
->fsb_frequency
- 1) << 16) | 0x77);
3645 static u16
get_max_timing(struct raminfo
*info
, int channel
)
3647 int slot
, rank
, lane
;
3650 if ((read_mchbar8(0x2ca8) >> 2) < 1)
3653 if (info
->revision
< 8)
3656 for (slot
= 0; slot
< NUM_SLOTS
; slot
++)
3657 for (rank
= 0; rank
< NUM_RANKS
; rank
++)
3658 if (info
->populated_ranks
[channel
][slot
][rank
])
3659 for (lane
= 0; lane
< 8 + info
->use_ecc
; lane
++)
3660 ret
= max(ret
, read_500(info
, channel
,
3661 get_timing_register_addr
3667 static void set_274265(struct raminfo
*info
)
3669 int delay_a_ps
, delay_b_ps
, delay_c_ps
, delay_d_ps
;
3670 int delay_e_ps
, delay_e_cycles
, delay_f_cycles
;
3671 int delay_e_over_cycle_ps
;
3675 delay_a_ps
= 4 * halfcycle_ps(info
) + 6 * fsbcycle_ps(info
);
3676 info
->training
.reg2ca9_bit0
= 0;
3677 for (channel
= 0; channel
< NUM_CHANNELS
; channel
++) {
3679 900000 / lcm(2 * info
->fsb_frequency
, frequency_11(info
));
3681 (halfcycle_ps(info
) * get_max_timing(info
, channel
) >> 6)
3682 - info
->some_delay_3_ps_rounded
+ 200;
3684 ((info
->silicon_revision
== 0
3685 || info
->silicon_revision
== 1)
3686 && (info
->revision
>= 8)))
3687 delay_d_ps
+= halfcycle_ps(info
) * 2;
3689 halfcycle_ps(info
) * (!info
->revision_flag_1
+
3690 info
->some_delay_2_halfcycles_ceil
+
3691 2 * info
->some_delay_1_cycle_floor
+
3692 info
->clock_speed_index
+
3693 2 * info
->cas_latency
- 7 + 11);
3694 delay_d_ps
+= info
->revision
>= 8 ? 2758 : 4428;
3696 write_mchbar32(0x140,
3697 (read_mchbar32(0x140) & 0xfaffffff) | 0x2000000);
3698 write_mchbar32(0x138,
3699 (read_mchbar32(0x138) & 0xfaffffff) | 0x2000000);
3700 if ((read_mchbar8(0x144) & 0x1f) > 0x13)
3702 delay_c_ps
= delay_d_ps
+ 1800;
3703 if (delay_c_ps
<= delay_a_ps
)
3707 cycletime_ps
* div_roundup(delay_c_ps
- delay_a_ps
,
3710 delay_e_over_cycle_ps
= delay_e_ps
% (2 * halfcycle_ps(info
));
3711 delay_e_cycles
= delay_e_ps
/ (2 * halfcycle_ps(info
));
3713 div_roundup(2500 - delay_e_over_cycle_ps
,
3714 2 * halfcycle_ps(info
));
3715 if (delay_f_cycles
> delay_e_cycles
) {
3716 info
->delay46_ps
[channel
] = delay_e_ps
;
3719 info
->delay46_ps
[channel
] =
3720 delay_e_over_cycle_ps
+
3721 2 * halfcycle_ps(info
) * delay_f_cycles
;
3722 delay_e_cycles
-= delay_f_cycles
;
3725 if (info
->delay46_ps
[channel
] < 2500) {
3726 info
->delay46_ps
[channel
] = 2500;
3727 info
->training
.reg2ca9_bit0
= 1;
3729 delay_b_ps
= halfcycle_ps(info
) + delay_c_ps
;
3730 if (delay_b_ps
<= delay_a_ps
)
3733 delay_b_ps
-= delay_a_ps
;
3734 info
->delay54_ps
[channel
] =
3735 cycletime_ps
* div_roundup(delay_b_ps
,
3737 2 * halfcycle_ps(info
) * delay_e_cycles
;
3738 if (info
->delay54_ps
[channel
] < 2500)
3739 info
->delay54_ps
[channel
] = 2500;
3740 info
->training
.reg274265
[channel
][0] = delay_e_cycles
;
3741 if (delay_d_ps
+ 7 * halfcycle_ps(info
) <=
3742 24 * halfcycle_ps(info
))
3743 info
->training
.reg274265
[channel
][1] = 0;
3745 info
->training
.reg274265
[channel
][1] =
3746 div_roundup(delay_d_ps
+ 7 * halfcycle_ps(info
),
3747 4 * halfcycle_ps(info
)) - 6;
3748 write_mchbar32((channel
<< 10) + 0x274,
3749 info
->training
.reg274265
[channel
][1]
3750 | (info
->training
.reg274265
[channel
][0] << 16));
3751 info
->training
.reg274265
[channel
][2] =
3752 div_roundup(delay_c_ps
+ 3 * fsbcycle_ps(info
),
3753 4 * halfcycle_ps(info
)) + 1;
3754 write_mchbar16((channel
<< 10) + 0x265,
3755 info
->training
.reg274265
[channel
][2] << 8);
3757 if (info
->training
.reg2ca9_bit0
)
3758 write_mchbar8(0x2ca9, read_mchbar8(0x2ca9) | 1);
3760 write_mchbar8(0x2ca9, read_mchbar8(0x2ca9) & ~1);
3763 static void restore_274265(struct raminfo
*info
)
3767 for (channel
= 0; channel
< NUM_CHANNELS
; channel
++) {
3768 write_mchbar32((channel
<< 10) + 0x274,
3769 (info
->cached_training
->reg274265
[channel
][0] << 16)
3770 | info
->cached_training
->reg274265
[channel
][1]);
3771 write_mchbar16((channel
<< 10) + 0x265,
3772 info
->cached_training
->reg274265
[channel
][2] << 8);
3774 if (info
->cached_training
->reg2ca9_bit0
)
3775 write_mchbar8(0x2ca9, read_mchbar8(0x2ca9) | 1);
3777 write_mchbar8(0x2ca9, read_mchbar8(0x2ca9) & ~1);
3781 static void dmi_setup(void)
3783 gav(read8(DEFAULT_DMIBAR
+ 0x254));
3784 write8(DEFAULT_DMIBAR
+ 0x254, 0x1);
3785 write16(DEFAULT_DMIBAR
+ 0x1b8, 0x18f2);
3786 read_mchbar16(0x48);
3787 write_mchbar16(0x48, 0x2);
3789 write32(DEFAULT_DMIBAR
+ 0xd68, read32(DEFAULT_DMIBAR
+ 0xd68) | 0x08000000);
3791 outl((gav(inl(DEFAULT_GPIOBASE
| 0x38)) & ~0x140000) | 0x400000,
3792 DEFAULT_GPIOBASE
| 0x38);
3793 gav(inb(DEFAULT_GPIOBASE
| 0xe)); // = 0xfdcaff6e
3797 void chipset_init(const int s3resume
)
3803 x2ca8
= read_mchbar8(0x2ca8);
3804 if ((x2ca8
& 1) || (x2ca8
== 8 && !s3resume
)) {
3805 printk(BIOS_DEBUG
, "soft reset detected, rebooting properly\n");
3806 write_mchbar8(0x2ca8, 0);
3817 pre_raminit_3(x2ca8
);
3819 pre_raminit_4a(x2ca8
);
3824 write_mchbar16(0x1170, 0xa880);
3825 write_mchbar8(0x11c1, 0x1);
3826 write_mchbar16(0x1170, 0xb880);
3827 read_mchbar8(0x1210);
3828 write_mchbar8(0x1210, 0x84);
3830 if (get_option(&gfxsize
, "gfx_uma_size") != CB_SUCCESS
) {
3835 ggc
= 0xb00 | ((gfxsize
+ 5) << 4);
3837 pcie_write_config16(NORTHBRIDGE
, D0F0_GGC
, ggc
| 2);
3840 deven
= pcie_read_config16(NORTHBRIDGE
, D0F0_DEVEN
); // = 0x3
3843 write_mchbar8(0x2c30, 0x20);
3844 pcie_read_config8(NORTHBRIDGE
, 0x8); // = 0x18
3845 write_mchbar16(0x2c30, read_mchbar16(0x2c30) | 0x200);
3846 write_mchbar16(0x2c32, 0x434);
3847 read_mchbar32(0x2c44);
3848 write_mchbar32(0x2c44, 0x1053687);
3849 pcie_read_config8(GMA
, 0x62); // = 0x2
3850 pcie_write_config8(GMA
, 0x62, 0x2);
3851 read8(DEFAULT_RCBA
+ 0x2318);
3852 write8(DEFAULT_RCBA
+ 0x2318, 0x47);
3853 read8(DEFAULT_RCBA
+ 0x2320);
3854 write8(DEFAULT_RCBA
+ 0x2320, 0xfc);
3857 read_mchbar32(0x30);
3858 write_mchbar32(0x30, 0x40);
3860 pcie_write_config16(NORTHBRIDGE
, D0F0_GGC
, ggc
);
3861 gav(read32(DEFAULT_RCBA
+ 0x3428));
3862 write32(DEFAULT_RCBA
+ 0x3428, 0x1d);
3865 void raminit(const int s3resume
, const u8
*spd_addrmap
)
3867 unsigned channel
, slot
, lane
, rank
;
3869 struct raminfo info
;
3872 int cbmem_wasnot_inited
;
3874 x2ca8
= read_mchbar8(0x2ca8);
3875 deven
= pcie_read_config16(NORTHBRIDGE
, D0F0_DEVEN
);
3877 memset(&info
, 0x5a, sizeof(info
));
3879 info
.last_500_command
[0] = 0;
3880 info
.last_500_command
[1] = 0;
3882 info
.fsb_frequency
= 135 * 2;
3883 info
.board_lane_delay
[0] = 0x14;
3884 info
.board_lane_delay
[1] = 0x07;
3885 info
.board_lane_delay
[2] = 0x07;
3886 info
.board_lane_delay
[3] = 0x08;
3887 info
.board_lane_delay
[4] = 0x56;
3888 info
.board_lane_delay
[5] = 0x04;
3889 info
.board_lane_delay
[6] = 0x04;
3890 info
.board_lane_delay
[7] = 0x05;
3891 info
.board_lane_delay
[8] = 0x10;
3893 info
.training
.reg_178
= 0;
3894 info
.training
.reg_10b
= 0;
3897 info
.memory_reserved_for_heci_mb
= 0;
3900 timestamp_add_now(101);
3902 if (!s3resume
|| REAL
) {
3903 pcie_read_config8(SOUTHBRIDGE
, GEN_PMCON_2
); // = 0x80
3905 collect_system_info(&info
);
3912 memset(&info
.populated_ranks
, 0, sizeof(info
.populated_ranks
));
3915 for (channel
= 0; channel
< NUM_CHANNELS
; channel
++)
3916 for (slot
= 0; slot
< NUM_SLOTS
; slot
++) {
3920 const u8 useful_addresses
[] = {
3932 0x11, 0x12, 0x13, 0x14, 0x15,
3933 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b,
3935 THERMAL_AND_REFRESH
,
3937 REFERENCE_RAW_CARD_USED
,
3938 RANK1_ADDRESS_MAPPING
,
3939 0x75, 0x76, 0x77, 0x78,
3940 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e,
3941 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84,
3942 0x85, 0x86, 0x87, 0x88,
3943 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e,
3944 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94,
3947 if (!spd_addrmap
[2 * channel
+ slot
])
3949 for (try = 0; try < 5; try++) {
3950 v
= smbus_read_byte(spd_addrmap
[2 * channel
+ slot
],
3959 sizeof(useful_addresses
) /
3960 sizeof(useful_addresses
[0]); addr
++)
3962 spd
[channel
][0][useful_addresses
3964 smbus_read_byte(spd_addrmap
[2 * channel
+ slot
],
3967 if (info
.spd
[channel
][0][DEVICE_TYPE
] != 11)
3968 die("Only DDR3 is supported");
3970 v
= info
.spd
[channel
][0][RANKS_AND_DQ
];
3971 info
.populated_ranks
[channel
][0][0] = 1;
3972 info
.populated_ranks
[channel
][0][1] =
3974 if (((v
>> 3) & 7) > 1)
3975 die("At most 2 ranks are supported");
3976 if ((v
& 7) == 0 || (v
& 7) > 2)
3977 die("Only x8 and x16 modules are supported");
3979 spd
[channel
][slot
][MODULE_TYPE
] & 0xF) != 2
3981 spd
[channel
][slot
][MODULE_TYPE
] & 0xF)
3983 die("Registered memory is not supported");
3984 info
.is_x16_module
[channel
][0] = (v
& 7) - 1;
3985 info
.density
[channel
][slot
] =
3986 info
.spd
[channel
][slot
][DENSITY
] & 0xF;
3989 spd
[channel
][slot
][MEMORY_BUS_WIDTH
] &
3996 for (channel
= 0; channel
< NUM_CHANNELS
; channel
++) {
3998 for (slot
= 0; slot
< NUM_SLOTS
; slot
++)
3999 for (rank
= 0; rank
< NUM_RANKS
; rank
++)
4001 populated_ranks
[channel
][slot
][rank
]
4002 << (2 * slot
+ rank
);
4003 info
.populated_ranks_mask
[channel
] = v
;
4008 gav(pcie_read_config32(NORTHBRIDGE
, D0F0_CAPID0
+ 4));
4012 timestamp_add_now(102);
4014 write_mchbar8(0x2ca8, read_mchbar8(0x2ca8) & 0xfc);
4016 rdmsr (MTRR_PHYS_MASK (3));
4019 collect_system_info(&info
);
4020 calculate_timings(&info
);
4023 pcie_write_config8(NORTHBRIDGE
, 0xdf, 0x82);
4027 u8 reg8
= pcie_read_config8(SOUTHBRIDGE
, GEN_PMCON_2
);
4028 if (x2ca8
== 0 && (reg8
& 0x80)) {
4029 /* Don't enable S4-assertion stretch. Makes trouble on roda/rk9.
4030 reg8 = pci_read_config8(PCI_DEV(0, 0x1f, 0), 0xa4);
4031 pci_write_config8(PCI_DEV(0, 0x1f, 0), 0xa4, reg8 | 0x08);
4036 pci_write_config8(SOUTHBRIDGE
, GEN_PMCON_2
,
4037 (reg8
& ~(1 << 7)));
4040 "Interrupted RAM init, reset required.\n");
4048 gav(read_mchbar8(0x2ca8)); ///!!!!
4051 if (!s3resume
&& x2ca8
== 0)
4052 pcie_write_config8(SOUTHBRIDGE
, GEN_PMCON_2
,
4053 pcie_read_config8(SOUTHBRIDGE
, GEN_PMCON_2
) | 0x80);
4055 compute_derived_timings(&info
);
4058 gav(read_mchbar8(0x164));
4059 write_mchbar8(0x164, 0x26);
4060 write_mchbar16(0x2c20, 0x10);
4063 write_mchbar32(0x18b4, read_mchbar32(0x18b4) | 0x210000); /* OK */
4064 write_mchbar32(0x1890, read_mchbar32(0x1890) | 0x2000000); /* OK */
4065 write_mchbar32(0x18b4, read_mchbar32(0x18b4) | 0x8000);
4067 gav(pcie_read_config32(PCI_DEV(0xff, 2, 1), 0x50)); // !!!!
4068 pcie_write_config8(PCI_DEV(0xff, 2, 1), 0x54, 0x12);
4070 gav(read_mchbar16(0x2c10)); // !!!!
4071 write_mchbar16(0x2c10, 0x412);
4072 gav(read_mchbar16(0x2c10)); // !!!!
4073 write_mchbar16(0x2c12, read_mchbar16(0x2c12) | 0x100); /* OK */
4075 gav(read_mchbar8(0x2ca8)); // !!!!
4076 write_mchbar32(0x1804,
4077 (read_mchbar32(0x1804) & 0xfffffffc) | 0x8400080);
4079 pcie_read_config32(PCI_DEV(0xff, 2, 1), 0x6c); // !!!!
4080 pcie_write_config32(PCI_DEV(0xff, 2, 1), 0x6c, 0x40a0a0);
4081 gav(read_mchbar32(0x1c04)); // !!!!
4082 gav(read_mchbar32(0x1804)); // !!!!
4085 write_mchbar8(0x2ca8, read_mchbar8(0x2ca8) | 1);
4088 write_mchbar32(0x18d8, 0x120000);
4089 write_mchbar32(0x18dc, 0x30a484a);
4090 pcie_write_config32(PCI_DEV(0xff, 2, 1), 0xe0, 0x0);
4091 pcie_write_config32(PCI_DEV(0xff, 2, 1), 0xf4, 0x9444a);
4092 write_mchbar32(0x18d8, 0x40000);
4093 write_mchbar32(0x18dc, 0xb000000);
4094 pcie_write_config32(PCI_DEV(0xff, 2, 1), 0xe0, 0x60000);
4095 pcie_write_config32(PCI_DEV(0xff, 2, 1), 0xf4, 0x0);
4096 write_mchbar32(0x18d8, 0x180000);
4097 write_mchbar32(0x18dc, 0xc0000142);
4098 pcie_write_config32(PCI_DEV(0xff, 2, 1), 0xe0, 0x20000);
4099 pcie_write_config32(PCI_DEV(0xff, 2, 1), 0xf4, 0x142);
4100 write_mchbar32(0x18d8, 0x1e0000);
4102 gav(read_mchbar32(0x18dc)); // !!!!
4103 write_mchbar32(0x18dc, 0x3);
4104 gav(read_mchbar32(0x18dc)); // !!!!
4107 write_mchbar8(0x2ca8, read_mchbar8(0x2ca8) | 1); // guess
4110 write_mchbar32(0x188c, 0x20bc09);
4111 pcie_write_config32(PCI_DEV(0xff, 2, 1), 0xd0, 0x40b0c09);
4112 write_mchbar32(0x1a10, 0x4200010e);
4113 write_mchbar32(0x18b8, read_mchbar32(0x18b8) | 0x200);
4114 gav(read_mchbar32(0x1918)); // !!!!
4115 write_mchbar32(0x1918, 0x332);
4117 gav(read_mchbar32(0x18b8)); // !!!!
4118 write_mchbar32(0x18b8, 0xe00);
4119 gav(read_mchbar32(0x182c)); // !!!!
4120 write_mchbar32(0x182c, 0x10202);
4121 gav(pcie_read_config32(PCI_DEV(0xff, 2, 1), 0x94)); // !!!!
4122 pcie_write_config32(PCI_DEV(0xff, 2, 1), 0x94, 0x10202);
4123 write_mchbar32(0x1a1c, read_mchbar32(0x1a1c) & 0x8fffffff);
4124 write_mchbar32(0x1a70, read_mchbar32(0x1a70) | 0x100000);
4126 write_mchbar32(0x18b4, read_mchbar32(0x18b4) & 0xffff7fff);
4127 gav(read_mchbar32(0x1a68)); // !!!!
4128 write_mchbar32(0x1a68, 0x343800);
4129 gav(read_mchbar32(0x1e68)); // !!!!
4130 gav(read_mchbar32(0x1a68)); // !!!!
4133 write_mchbar8(0x2ca8, read_mchbar8(0x2ca8) | 1); // guess
4136 pcie_read_config32(PCI_DEV(0xff, 2, 0), 0x048); // !!!!
4137 pcie_write_config32(PCI_DEV(0xff, 2, 0), 0x048, 0x140000);
4138 pcie_read_config32(PCI_DEV(0xff, 2, 0), 0x058); // !!!!
4139 pcie_write_config32(PCI_DEV(0xff, 2, 0), 0x058, 0x64555);
4140 pcie_read_config32(PCI_DEV(0xff, 2, 0), 0x058); // !!!!
4141 pcie_read_config32(PCI_DEV (0xff, 0, 0), 0xd0); // !!!!
4142 pcie_write_config32(PCI_DEV (0xff, 0, 0), 0xd0, 0x180);
4143 gav(read_mchbar32(0x1af0)); // !!!!
4144 gav(read_mchbar32(0x1af0)); // !!!!
4145 write_mchbar32(0x1af0, 0x1f020003);
4146 gav(read_mchbar32(0x1af0)); // !!!!
4149 write_mchbar8(0x2ca8, read_mchbar8(0x2ca8) | 1); // guess
4152 gav(read_mchbar32(0x1890)); // !!!!
4153 write_mchbar32(0x1890, 0x80102);
4154 gav(read_mchbar32(0x18b4)); // !!!!
4155 write_mchbar32(0x18b4, 0x216000);
4156 write_mchbar32(0x18a4, 0x22222222);
4157 write_mchbar32(0x18a8, 0x22222222);
4158 write_mchbar32(0x18ac, 0x22222);
4162 info
.cached_training
= get_cached_training();
4166 if (s3resume
&& info
.cached_training
) {
4167 restore_274265(&info
);
4168 printk(BIOS_DEBUG
, "reg2ca9_bit0 = %x\n",
4169 info
.cached_training
->reg2ca9_bit0
);
4170 for (i
= 0; i
< 2; i
++)
4171 for (j
= 0; j
< 3; j
++)
4172 printk(BIOS_DEBUG
, "reg274265[%d][%d] = %x\n",
4173 i
, j
, info
.cached_training
->reg274265
[i
][j
]);
4176 printk(BIOS_DEBUG
, "reg2ca9_bit0 = %x\n",
4177 info
.training
.reg2ca9_bit0
);
4178 for (i
= 0; i
< 2; i
++)
4179 for (j
= 0; j
< 3; j
++)
4180 printk(BIOS_DEBUG
, "reg274265[%d][%d] = %x\n",
4181 i
, j
, info
.training
.reg274265
[i
][j
]);
4184 set_2dxx_series(&info
, s3resume
);
4187 read_mchbar32(0x2cb0);
4188 write_mchbar32(0x2cb0, 0x40);
4194 write_mchbar32(0xff8, 0x1800 | read_mchbar32(0xff8));
4195 read_mchbar32(0x2cb0);
4196 write_mchbar32(0x2cb0, 0x00);
4197 pcie_read_config8(PCI_DEV (0, 0x2, 0x0), 0x4c);
4198 pcie_read_config8(PCI_DEV (0, 0x2, 0x0), 0x4c);
4199 pcie_read_config8(PCI_DEV (0, 0x2, 0x0), 0x4e);
4201 read_mchbar8(0x1150);
4202 read_mchbar8(0x1151);
4203 read_mchbar8(0x1022);
4204 read_mchbar8(0x16d0);
4205 write_mchbar32(0x1300, 0x60606060);
4206 write_mchbar32(0x1304, 0x60606060);
4207 write_mchbar32(0x1308, 0x78797a7b);
4208 write_mchbar32(0x130c, 0x7c7d7e7f);
4209 write_mchbar32(0x1310, 0x60606060);
4210 write_mchbar32(0x1314, 0x60606060);
4211 write_mchbar32(0x1318, 0x60606060);
4212 write_mchbar32(0x131c, 0x60606060);
4213 write_mchbar32(0x1320, 0x50515253);
4214 write_mchbar32(0x1324, 0x54555657);
4215 write_mchbar32(0x1328, 0x58595a5b);
4216 write_mchbar32(0x132c, 0x5c5d5e5f);
4217 write_mchbar32(0x1330, 0x40414243);
4218 write_mchbar32(0x1334, 0x44454647);
4219 write_mchbar32(0x1338, 0x48494a4b);
4220 write_mchbar32(0x133c, 0x4c4d4e4f);
4221 write_mchbar32(0x1340, 0x30313233);
4222 write_mchbar32(0x1344, 0x34353637);
4223 write_mchbar32(0x1348, 0x38393a3b);
4224 write_mchbar32(0x134c, 0x3c3d3e3f);
4225 write_mchbar32(0x1350, 0x20212223);
4226 write_mchbar32(0x1354, 0x24252627);
4227 write_mchbar32(0x1358, 0x28292a2b);
4228 write_mchbar32(0x135c, 0x2c2d2e2f);
4229 write_mchbar32(0x1360, 0x10111213);
4230 write_mchbar32(0x1364, 0x14151617);
4231 write_mchbar32(0x1368, 0x18191a1b);
4232 write_mchbar32(0x136c, 0x1c1d1e1f);
4233 write_mchbar32(0x1370, 0x10203);
4234 write_mchbar32(0x1374, 0x4050607);
4235 write_mchbar32(0x1378, 0x8090a0b);
4236 write_mchbar32(0x137c, 0xc0d0e0f);
4237 write_mchbar8(0x11cc, 0x4e);
4238 write_mchbar32(0x1110, 0x73970404);
4239 write_mchbar32(0x1114, 0x72960404);
4240 write_mchbar32(0x1118, 0x6f950404);
4241 write_mchbar32(0x111c, 0x6d940404);
4242 write_mchbar32(0x1120, 0x6a930404);
4243 write_mchbar32(0x1124, 0x68a41404);
4244 write_mchbar32(0x1128, 0x66a21404);
4245 write_mchbar32(0x112c, 0x63a01404);
4246 write_mchbar32(0x1130, 0x609e1404);
4247 write_mchbar32(0x1134, 0x5f9c1404);
4248 write_mchbar32(0x1138, 0x5c961404);
4249 write_mchbar32(0x113c, 0x58a02404);
4250 write_mchbar32(0x1140, 0x54942404);
4251 write_mchbar32(0x1190, 0x900080a);
4252 write_mchbar16(0x11c0, 0xc40b);
4253 write_mchbar16(0x11c2, 0x303);
4254 write_mchbar16(0x11c4, 0x301);
4255 read_mchbar32(0x1190);
4256 write_mchbar32(0x1190, 0x8900080a);
4257 write_mchbar32(0x11b8, 0x70c3000);
4258 write_mchbar8(0x11ec, 0xa);
4259 write_mchbar16(0x1100, 0x800);
4260 read_mchbar32(0x11bc);
4261 write_mchbar32(0x11bc, 0x1e84800);
4262 write_mchbar16(0x11ca, 0xfa);
4263 write_mchbar32(0x11e4, 0x4e20);
4264 write_mchbar8(0x11bc, 0xf);
4265 write_mchbar16(0x11da, 0x19);
4266 write_mchbar16(0x11ba, 0x470c);
4267 write_mchbar32(0x1680, 0xe6ffe4ff);
4268 write_mchbar32(0x1684, 0xdeffdaff);
4269 write_mchbar32(0x1688, 0xd4ffd0ff);
4270 write_mchbar32(0x168c, 0xccffc6ff);
4271 write_mchbar32(0x1690, 0xc0ffbeff);
4272 write_mchbar32(0x1694, 0xb8ffb0ff);
4273 write_mchbar32(0x1698, 0xa8ff0000);
4274 write_mchbar32(0x169c, 0xc00);
4275 write_mchbar32(0x1290, 0x5000000);
4278 write_mchbar32(0x124c, 0x15040d00);
4279 write_mchbar32(0x1250, 0x7f0000);
4280 write_mchbar32(0x1254, 0x1e220004);
4281 write_mchbar32(0x1258, 0x4000004);
4282 write_mchbar32(0x1278, 0x0);
4283 write_mchbar32(0x125c, 0x0);
4284 write_mchbar32(0x1260, 0x0);
4285 write_mchbar32(0x1264, 0x0);
4286 write_mchbar32(0x1268, 0x0);
4287 write_mchbar32(0x126c, 0x0);
4288 write_mchbar32(0x1270, 0x0);
4289 write_mchbar32(0x1274, 0x0);
4292 if ((deven
& 8) && x2ca8
== 0) {
4293 write_mchbar16(0x1214, 0x320);
4294 write_mchbar32(0x1600, 0x40000000);
4295 read_mchbar32(0x11f4);
4296 write_mchbar32(0x11f4, 0x10000000);
4297 read_mchbar16(0x1230);
4298 write_mchbar16(0x1230, 0x8000);
4299 write_mchbar32(0x1400, 0x13040020);
4300 write_mchbar32(0x1404, 0xe090120);
4301 write_mchbar32(0x1408, 0x5120220);
4302 write_mchbar32(0x140c, 0x5120330);
4303 write_mchbar32(0x1410, 0xe090220);
4304 write_mchbar32(0x1414, 0x1010001);
4305 write_mchbar32(0x1418, 0x1110000);
4306 write_mchbar32(0x141c, 0x9020020);
4307 write_mchbar32(0x1420, 0xd090220);
4308 write_mchbar32(0x1424, 0x2090220);
4309 write_mchbar32(0x1428, 0x2090330);
4310 write_mchbar32(0x142c, 0xd090220);
4311 write_mchbar32(0x1430, 0x1010001);
4312 write_mchbar32(0x1434, 0x1110000);
4313 write_mchbar32(0x1438, 0x11040020);
4314 write_mchbar32(0x143c, 0x4030220);
4315 write_mchbar32(0x1440, 0x1060220);
4316 write_mchbar32(0x1444, 0x1060330);
4317 write_mchbar32(0x1448, 0x4030220);
4318 write_mchbar32(0x144c, 0x1010001);
4319 write_mchbar32(0x1450, 0x1110000);
4320 write_mchbar32(0x1454, 0x4010020);
4321 write_mchbar32(0x1458, 0xb090220);
4322 write_mchbar32(0x145c, 0x1090220);
4323 write_mchbar32(0x1460, 0x1090330);
4324 write_mchbar32(0x1464, 0xb090220);
4325 write_mchbar32(0x1468, 0x1010001);
4326 write_mchbar32(0x146c, 0x1110000);
4327 write_mchbar32(0x1470, 0xf040020);
4328 write_mchbar32(0x1474, 0xa090220);
4329 write_mchbar32(0x1478, 0x1120220);
4330 write_mchbar32(0x147c, 0x1120330);
4331 write_mchbar32(0x1480, 0xa090220);
4332 write_mchbar32(0x1484, 0x1010001);
4333 write_mchbar32(0x1488, 0x1110000);
4334 write_mchbar32(0x148c, 0x7020020);
4335 write_mchbar32(0x1490, 0x1010220);
4336 write_mchbar32(0x1494, 0x10210);
4337 write_mchbar32(0x1498, 0x10320);
4338 write_mchbar32(0x149c, 0x1010220);
4339 write_mchbar32(0x14a0, 0x1010001);
4340 write_mchbar32(0x14a4, 0x1110000);
4341 write_mchbar32(0x14a8, 0xd040020);
4342 write_mchbar32(0x14ac, 0x8090220);
4343 write_mchbar32(0x14b0, 0x1111310);
4344 write_mchbar32(0x14b4, 0x1111420);
4345 write_mchbar32(0x14b8, 0x8090220);
4346 write_mchbar32(0x14bc, 0x1010001);
4347 write_mchbar32(0x14c0, 0x1110000);
4348 write_mchbar32(0x14c4, 0x3010020);
4349 write_mchbar32(0x14c8, 0x7090220);
4350 write_mchbar32(0x14cc, 0x1081310);
4351 write_mchbar32(0x14d0, 0x1081420);
4352 write_mchbar32(0x14d4, 0x7090220);
4353 write_mchbar32(0x14d8, 0x1010001);
4354 write_mchbar32(0x14dc, 0x1110000);
4355 write_mchbar32(0x14e0, 0xb040020);
4356 write_mchbar32(0x14e4, 0x2030220);
4357 write_mchbar32(0x14e8, 0x1051310);
4358 write_mchbar32(0x14ec, 0x1051420);
4359 write_mchbar32(0x14f0, 0x2030220);
4360 write_mchbar32(0x14f4, 0x1010001);
4361 write_mchbar32(0x14f8, 0x1110000);
4362 write_mchbar32(0x14fc, 0x5020020);
4363 write_mchbar32(0x1500, 0x5090220);
4364 write_mchbar32(0x1504, 0x2071310);
4365 write_mchbar32(0x1508, 0x2071420);
4366 write_mchbar32(0x150c, 0x5090220);
4367 write_mchbar32(0x1510, 0x1010001);
4368 write_mchbar32(0x1514, 0x1110000);
4369 write_mchbar32(0x1518, 0x7040120);
4370 write_mchbar32(0x151c, 0x2090220);
4371 write_mchbar32(0x1520, 0x70b1210);
4372 write_mchbar32(0x1524, 0x70b1310);
4373 write_mchbar32(0x1528, 0x2090220);
4374 write_mchbar32(0x152c, 0x1010001);
4375 write_mchbar32(0x1530, 0x1110000);
4376 write_mchbar32(0x1534, 0x1010110);
4377 write_mchbar32(0x1538, 0x1081310);
4378 write_mchbar32(0x153c, 0x5041200);
4379 write_mchbar32(0x1540, 0x5041310);
4380 write_mchbar32(0x1544, 0x1081310);
4381 write_mchbar32(0x1548, 0x1010001);
4382 write_mchbar32(0x154c, 0x1110000);
4383 write_mchbar32(0x1550, 0x1040120);
4384 write_mchbar32(0x1554, 0x4051210);
4385 write_mchbar32(0x1558, 0xd051200);
4386 write_mchbar32(0x155c, 0xd051200);
4387 write_mchbar32(0x1560, 0x4051210);
4388 write_mchbar32(0x1564, 0x1010001);
4389 write_mchbar32(0x1568, 0x1110000);
4390 write_mchbar16(0x1222, 0x220a);
4391 write_mchbar16(0x123c, 0x1fc0);
4392 write_mchbar16(0x1220, 0x1388);
4395 read_mchbar32(0x2c80); // !!!!
4396 write_mchbar32(0x2c80, 0x1053688);
4397 read_mchbar32(0x1c04); // !!!!
4398 write_mchbar32(0x1804, 0x406080);
4400 read_mchbar8(0x2ca8);
4403 write_mchbar8(0x2ca8, read_mchbar8(0x2ca8) & ~3);
4404 write_mchbar8(0x2ca8, read_mchbar8(0x2ca8) + 4);
4405 write_mchbar32(0x1af0, read_mchbar32(0x1af0) | 0x10);
4414 write_mchbar8(0x2ca8, read_mchbar8(0x2ca8));
4415 read_mchbar32(0x2c80); // !!!!
4416 write_mchbar32(0x2c80, 0x53688);
4417 pcie_write_config32(PCI_DEV (0xff, 0, 0), 0x60, 0x20220);
4418 read_mchbar16(0x2c20); // !!!!
4419 read_mchbar16(0x2c10); // !!!!
4420 read_mchbar16(0x2c00); // !!!!
4421 write_mchbar16(0x2c00, 0x8c0);
4423 write_1d0(0, 0x33d, 0, 0);
4424 write_500(&info
, 0, 0, 0xb61, 0, 0);
4425 write_500(&info
, 1, 0, 0xb61, 0, 0);
4426 write_mchbar32(0x1a30, 0x0);
4427 write_mchbar32(0x1a34, 0x0);
4428 write_mchbar16(0x614,
4429 0xb5b | (info
.populated_ranks
[1][0][0] *
4430 0x404) | (info
.populated_ranks
[0][0][0] *
4432 write_mchbar16(0x616, 0x26a);
4433 write_mchbar32(0x134, 0x856000);
4434 write_mchbar32(0x160, 0x5ffffff);
4435 read_mchbar32(0x114); // !!!!
4436 write_mchbar32(0x114, 0xc2024440);
4437 read_mchbar32(0x118); // !!!!
4438 write_mchbar32(0x118, 0x4);
4439 for (channel
= 0; channel
< NUM_CHANNELS
; channel
++)
4440 write_mchbar32(0x260 + (channel
<< 10),
4443 populated_ranks_mask
[channel
] & 3) << 20));
4444 for (channel
= 0; channel
< NUM_CHANNELS
; channel
++) {
4445 write_mchbar16(0x31c + (channel
<< 10), 0x101);
4446 write_mchbar16(0x360 + (channel
<< 10), 0x909);
4447 write_mchbar16(0x3a4 + (channel
<< 10), 0x101);
4448 write_mchbar16(0x3e8 + (channel
<< 10), 0x101);
4449 write_mchbar32(0x320 + (channel
<< 10), 0x29002900);
4450 write_mchbar32(0x324 + (channel
<< 10), 0x0);
4451 write_mchbar32(0x368 + (channel
<< 10), 0x32003200);
4452 write_mchbar16(0x352 + (channel
<< 10), 0x505);
4453 write_mchbar16(0x354 + (channel
<< 10), 0x3c3c);
4454 write_mchbar16(0x356 + (channel
<< 10), 0x1040);
4455 write_mchbar16(0x39a + (channel
<< 10), 0x73e4);
4456 write_mchbar16(0x3de + (channel
<< 10), 0x77ed);
4457 write_mchbar16(0x422 + (channel
<< 10), 0x1040);
4460 write_1d0(0x4, 0x151, 4, 1);
4461 write_1d0(0, 0x142, 3, 1);
4462 rdmsr(0x1ac); // !!!!
4463 write_500(&info
, 1, 1, 0x6b3, 4, 1);
4464 write_500(&info
, 1, 1, 0x6cf, 4, 1);
4466 rmw_1d0(0x21c, 0x38, 0, 6, 1);
4468 write_1d0(((!info
.populated_ranks
[1][0][0]) << 1) | ((!info
.
4472 for (channel
= 0; channel
< NUM_CHANNELS
; channel
++) {
4473 write_mchbar16(0x38e + (channel
<< 10), 0x5f5f);
4474 write_mchbar16(0x3d2 + (channel
<< 10), 0x5f5f);
4479 program_base_timings(&info
);
4481 write_mchbar8(0x5ff, read_mchbar8(0x5ff) | 0x80); /* OK */
4483 write_1d0(0x2, 0x1d5, 2, 1);
4484 write_1d0(0x20, 0x166, 7, 1);
4485 write_1d0(0x0, 0xeb, 3, 1);
4486 write_1d0(0x0, 0xf3, 6, 1);
4488 for (channel
= 0; channel
< NUM_CHANNELS
; channel
++)
4489 for (lane
= 0; lane
< 9; lane
++) {
4490 u16 addr
= 0x125 + get_lane_offset(0, 0, lane
);
4492 a
= read_500(&info
, channel
, addr
, 6); // = 0x20040080 //!!!!
4493 write_500(&info
, channel
, a
, addr
, 6, 1);
4499 if (info
.cached_training
== NULL
) {
4502 "Couldn't find training data. Rebooting\n");
4503 reg32
= inl(DEFAULT_PMBASE
+ 0x04);
4504 outl(reg32
& ~(7 << 10), DEFAULT_PMBASE
+ 0x04);
4515 info
.training
= *info
.cached_training
;
4516 for (tm
= 0; tm
< 4; tm
++)
4517 for (channel
= 0; channel
< NUM_CHANNELS
; channel
++)
4518 for (slot
= 0; slot
< NUM_SLOTS
; slot
++)
4519 for (rank
= 0; rank
< NUM_RANKS
; rank
++)
4520 for (lane
= 0; lane
< 9; lane
++)
4528 get_timing_register_addr
4532 write_1d0(info
.cached_training
->reg_178
, 0x178, 7, 1);
4533 write_1d0(info
.cached_training
->reg_10b
, 0x10b, 6, 1);
4536 read_mchbar32(0x1f4); // !!!!
4537 write_mchbar32(0x1f4, 0x20000);
4538 write_mchbar32(0x1f0, 0x1d000200);
4539 read_mchbar8(0x1f0); // !!!!
4540 write_mchbar8(0x1f0, 0x1);
4541 read_mchbar8(0x1f0); // !!!!
4543 program_board_delay(&info
);
4545 write_mchbar8(0x5ff, 0x0); /* OK */
4546 write_mchbar8(0x5ff, 0x80); /* OK */
4547 write_mchbar8(0x5f4, 0x1); /* OK */
4549 write_mchbar32(0x130, read_mchbar32(0x130) & 0xfffffffd); // | 2 when ?
4550 while (read_mchbar32(0x130) & 1) ;
4551 gav(read_1d0(0x14b, 7)); // = 0x81023100
4552 write_1d0(0x30, 0x14b, 7, 1);
4553 read_1d0(0xd6, 6); // = 0xfa008080 // !!!!
4554 write_1d0(7, 0xd6, 6, 1);
4555 read_1d0(0x328, 6); // = 0xfa018080 // !!!!
4556 write_1d0(7, 0x328, 6, 1);
4558 for (channel
= 0; channel
< NUM_CHANNELS
; channel
++)
4559 set_4cf(&info
, channel
,
4560 info
.populated_ranks
[channel
][0][0] ? 8 : 0);
4562 read_1d0(0x116, 4); // = 0x4040432 // !!!!
4563 write_1d0(2, 0x116, 4, 1);
4564 read_1d0(0xae, 6); // = 0xe8088080 // !!!!
4565 write_1d0(0, 0xae, 6, 1);
4566 read_1d0(0x300, 4); // = 0x48088080 // !!!!
4567 write_1d0(0, 0x300, 6, 1);
4568 read_mchbar16(0x356); // !!!!
4569 write_mchbar16(0x356, 0x1040);
4570 read_mchbar16(0x756); // !!!!
4571 write_mchbar16(0x756, 0x1040);
4572 write_mchbar32(0x140, read_mchbar32(0x140) & ~0x07000000);
4573 write_mchbar32(0x138, read_mchbar32(0x138) & ~0x07000000);
4574 write_mchbar32(0x130, 0x31111301);
4575 /* Wait until REG130b0 is 1. */
4576 while (read_mchbar32(0x130) & 1)
4582 val_a1
= read_1d0(0xa1, 6); // = 0x1cf4040 // !!!!
4583 t
= read_1d0(0x2f3, 6); // = 0x10a4040 // !!!!
4584 rmw_1d0(0x320, 0x07,
4585 (t
& 4) | ((t
& 8) >> 2) | ((t
& 0x10) >> 4), 6, 1);
4586 rmw_1d0(0x14b, 0x78,
4587 ((((val_a1
>> 2) & 4) | (val_a1
& 8)) >> 2) | (val_a1
&
4591 ((((val_a1
>> 2) & 4) | (val_a1
& 8)) >> 2) | (val_a1
&
4596 for (channel
= 0; channel
< NUM_CHANNELS
; channel
++)
4597 set_4cf(&info
, channel
,
4598 info
.populated_ranks
[channel
][0][0] ? 9 : 1);
4600 rmw_1d0(0x116, 0xe, 1, 4, 1); // = 0x4040432 // !!!!
4601 read_mchbar32(0x144); // !!!!
4602 write_1d0(2, 0xae, 6, 1);
4603 write_1d0(2, 0x300, 6, 1);
4604 write_1d0(2, 0x121, 3, 1);
4605 read_1d0(0xd6, 6); // = 0xfa00c0c7 // !!!!
4606 write_1d0(4, 0xd6, 6, 1);
4607 read_1d0(0x328, 6); // = 0xfa00c0c7 // !!!!
4608 write_1d0(4, 0x328, 6, 1);
4610 for (channel
= 0; channel
< NUM_CHANNELS
; channel
++)
4611 set_4cf(&info
, channel
,
4612 info
.populated_ranks
[channel
][0][0] ? 9 : 0);
4614 write_mchbar32(0x130,
4616 populated_ranks
[1][0][0] << 30) | (info
.
4621 while (read_mchbar8(0x130) & 1) ; // !!!!
4622 read_1d0(0xa1, 6); // = 0x1cf4054 // !!!!
4623 read_1d0(0x2f3, 6); // = 0x10a4054 // !!!!
4624 read_1d0(0x21c, 6); // = 0xafa00c0 // !!!!
4625 write_1d0(0, 0x21c, 6, 1);
4626 read_1d0(0x14b, 7); // = 0x810231b0 // !!!!
4627 write_1d0(0x35, 0x14b, 7, 1);
4629 for (channel
= 0; channel
< NUM_CHANNELS
; channel
++)
4630 set_4cf(&info
, channel
,
4631 info
.populated_ranks
[channel
][0][0] ? 0xb : 0x2);
4635 write_mchbar8(0x1e8, 0x4); /* OK */
4637 for (channel
= 0; channel
< NUM_CHANNELS
; channel
++) {
4638 write_500(&info
, channel
,
4639 0x3 & ~(info
.populated_ranks_mask
[channel
]), 0x6b7, 2,
4641 write_500(&info
, channel
, 0x3, 0x69b, 2, 1);
4643 write_mchbar32(0x2d0, (read_mchbar32(0x2d0) & 0xff2c01ff) | 0x200000); /* OK */
4644 write_mchbar16(0x6c0, 0x14a0); /* OK */
4645 write_mchbar32(0x6d0, (read_mchbar32(0x6d0) & 0xff0080ff) | 0x8000); /* OK */
4646 write_mchbar16(0x232, 0x8);
4647 write_mchbar32(0x234, (read_mchbar32(0x234) & 0xfffbfffb) | 0x40004); /* 0x40004 or 0 depending on ? */
4648 write_mchbar32(0x34, (read_mchbar32(0x34) & 0xfffffffd) | 5); /* OK */
4649 write_mchbar32(0x128, 0x2150d05);
4650 write_mchbar8(0x12c, 0x1f); /* OK */
4651 write_mchbar8(0x12d, 0x56); /* OK */
4652 write_mchbar8(0x12e, 0x31);
4653 write_mchbar8(0x12f, 0x0); /* OK */
4654 write_mchbar8(0x271, 0x2); /* OK */
4655 write_mchbar8(0x671, 0x2); /* OK */
4656 write_mchbar8(0x1e8, 0x4); /* OK */
4657 for (channel
= 0; channel
< NUM_CHANNELS
; channel
++)
4658 write_mchbar32(0x294 + (channel
<< 10),
4659 (info
.populated_ranks_mask
[channel
] & 3) << 16);
4660 write_mchbar32(0x134, (read_mchbar32(0x134) & 0xfc01ffff) | 0x10000); /* OK */
4661 write_mchbar32(0x134, (read_mchbar32(0x134) & 0xfc85ffff) | 0x850000); /* OK */
4662 for (channel
= 0; channel
< NUM_CHANNELS
; channel
++)
4663 write_mchbar32(0x260 + (channel
<< 10),
4664 (read_mchbar32(0x260 + (channel
<< 10)) &
4665 ~0xf00000) | 0x8000000 | ((info
.
4666 populated_ranks_mask
4674 for (channel
= 0; channel
< NUM_CHANNELS
; channel
++)
4675 for (slot
= 0; slot
< NUM_SLOTS
; slot
++)
4676 for (rank
= 0; rank
< NUM_RANKS
; rank
++)
4677 if (info
.populated_ranks
[channel
][slot
][rank
]) {
4678 jedec_read(&info
, channel
, slot
, rank
,
4679 totalrank
, 0xa, 0x400);
4683 write_mchbar8(0x12c, 0x9f);
4685 read_mchbar8(0x271); // 2 // !!!!
4686 write_mchbar8(0x271, 0xe);
4687 read_mchbar8(0x671); // !!!!
4688 write_mchbar8(0x671, 0xe);
4691 for (channel
= 0; channel
< NUM_CHANNELS
; channel
++) {
4692 write_mchbar32(0x294 + (channel
<< 10),
4694 populated_ranks_mask
[channel
] & 3) <<
4696 write_mchbar16(0x298 + (channel
<< 10),
4698 populated_ranks
[channel
][0][0]) | (info
.
4705 write_mchbar32(0x29c + (channel
<< 10), 0x77a);
4707 read_mchbar32(0x2c0); /// !!!
4708 write_mchbar32(0x2c0, 0x6009cc00);
4712 a
= read_mchbar8(0x243); // !!!!
4713 b
= read_mchbar8(0x643); // !!!!
4714 write_mchbar8(0x243, a
| 2);
4715 write_mchbar8(0x643, b
| 2);
4718 write_1d0(7, 0x19b, 3, 1);
4719 write_1d0(7, 0x1c0, 3, 1);
4720 write_1d0(4, 0x1c6, 4, 1);
4721 write_1d0(4, 0x1cc, 4, 1);
4722 read_1d0(0x151, 4); // = 0x408c6d74 // !!!!
4723 write_1d0(4, 0x151, 4, 1);
4724 write_mchbar32(0x584, 0xfffff);
4725 write_mchbar32(0x984, 0xfffff);
4727 for (channel
= 0; channel
< NUM_CHANNELS
; channel
++)
4728 for (slot
= 0; slot
< NUM_SLOTS
; slot
++)
4729 for (rank
= 0; rank
< NUM_RANKS
; rank
++)
4731 populated_ranks
[channel
][slot
]
4733 config_rank(&info
, s3resume
,
4737 write_mchbar8(0x243, 0x1);
4738 write_mchbar8(0x643, 0x1);
4741 /* was == 1 but is common */
4742 pcie_write_config16(NORTHBRIDGE
, 0xc8, 3);
4743 write_26c(0, 0x820);
4744 write_26c(1, 0x820);
4745 write_mchbar32(0x130, read_mchbar32(0x130) | 2);
4749 for (channel
= 0; channel
< NUM_CHANNELS
; channel
++) {
4750 write_mchbar32(0x294 + (channel
<< 10),
4752 populated_ranks_mask
[channel
] & 3) <<
4754 write_mchbar16(0x298 + (channel
<< 10),
4756 populated_ranks
[channel
][0][0]) | (info
.
4763 write_mchbar32(0x29c + (channel
<< 10), 0x77a);
4765 read_mchbar32(0x2c0); /// !!!
4766 write_mchbar32(0x2c0, 0x6009cc00);
4769 write_mchbar32(0xfa4, read_mchbar32(0xfa4) & ~0x01000002);
4770 write_mchbar32(0xfb0, 0x2000e019);
4776 /* Before training. */
4777 timestamp_add_now(103);
4780 ram_training(&info
);
4782 /* After training. */
4783 timestamp_add_now(104);
4785 dump_timings(&info
);
4788 ram_check(0x100000, 0x200000);
4790 program_modules_memory_map(&info
, 0);
4791 program_total_memory_map(&info
);
4793 if (info
.non_interleaved_part_mb
!= 0 && info
.interleaved_part_mb
!= 0)
4794 write_mchbar8(0x111, 0x20 | (0 << 2) | (1 << 6) | (0 << 7));
4795 else if (have_match_ranks(&info
, 0, 4) && have_match_ranks(&info
, 1, 4))
4796 write_mchbar8(0x111, 0x20 | (3 << 2) | (0 << 6) | (1 << 7));
4797 else if (have_match_ranks(&info
, 0, 2) && have_match_ranks(&info
, 1, 2))
4798 write_mchbar8(0x111, 0x20 | (3 << 2) | (0 << 6) | (0 << 7));
4800 write_mchbar8(0x111, 0x20 | (3 << 2) | (1 << 6) | (0 << 7));
4802 write_mchbar32(0xfac, read_mchbar32(0xfac) & ~0x80000000); // OK
4803 write_mchbar32(0xfb4, 0x4800); // OK
4804 write_mchbar32(0xfb8, (info
.revision
< 8) ? 0x20 : 0x0); // OK
4805 write_mchbar32(0xe94, 0x7ffff); // OK
4806 write_mchbar32(0xfc0, 0x80002040); // OK
4807 write_mchbar32(0xfc4, 0x701246); // OK
4808 write_mchbar8(0xfc8, read_mchbar8(0xfc8) & ~0x70); // OK
4809 write_mchbar32(0xe5c, 0x1000000 | read_mchbar32(0xe5c)); // OK
4810 write_mchbar32(0x1a70, (read_mchbar32(0x1a70) | 0x00200000) & ~0x00100000); // OK
4811 write_mchbar32(0x50, 0x700b0); // OK
4812 write_mchbar32(0x3c, 0x10); // OK
4813 write_mchbar8(0x1aa8, (read_mchbar8(0x1aa8) & ~0x35) | 0xa); // OK
4814 write_mchbar8(0xff4, read_mchbar8(0xff4) | 0x2); // OK
4815 write_mchbar32(0xff8, (read_mchbar32(0xff8) & ~0xe008) | 0x1020); // OK
4818 write_mchbar32(0xd00, IOMMU_BASE2
| 1);
4819 write_mchbar32(0xd40, IOMMU_BASE1
| 1);
4820 write_mchbar32(0xdc0, IOMMU_BASE4
| 1);
4822 write32p(IOMMU_BASE1
| 0xffc, 0x80000000);
4823 write32p(IOMMU_BASE2
| 0xffc, 0xc0000000);
4824 write32p(IOMMU_BASE4
| 0xffc, 0x80000000);
4829 eax
= read32p(0xffc + (read_mchbar32(0xd00) & ~1)) | 0x08000000; // = 0xe911714b// OK
4830 write32p(0xffc + (read_mchbar32(0xd00) & ~1), eax
); // OK
4831 eax
= read32p(0xffc + (read_mchbar32(0xdc0) & ~1)) | 0x40000000; // = 0xe911714b// OK
4832 write32p(0xffc + (read_mchbar32(0xdc0) & ~1), eax
); // OK
4839 eax
= info
.fsb_frequency
/ 9;
4840 write_mchbar32(0xfcc, (read_mchbar32(0xfcc) & 0xfffc0000) | (eax
* 0x280) | (eax
* 0x5000) | eax
| 0x40000); // OK
4841 write_mchbar32(0x20, 0x33001); //OK
4844 for (channel
= 0; channel
< NUM_CHANNELS
; channel
++) {
4845 write_mchbar32(0x220 + (channel
<< 10), read_mchbar32(0x220 + (channel
<< 10)) & ~0x7770); //OK
4846 if (info
.max_slots_used_in_channel
== 1)
4847 write_mchbar16(0x237 + (channel
<< 10), (read_mchbar16(0x237 + (channel
<< 10)) | 0x0201)); //OK
4849 write_mchbar16(0x237 + (channel
<< 10), (read_mchbar16(0x237 + (channel
<< 10)) & ~0x0201)); //OK
4851 write_mchbar8(0x241 + (channel
<< 10), read_mchbar8(0x241 + (channel
<< 10)) | 1); // OK
4853 if (info
.clock_speed_index
<= 1
4854 && (info
.silicon_revision
== 2
4855 || info
.silicon_revision
== 3))
4856 write_mchbar32(0x248 + (channel
<< 10), (read_mchbar32(0x248 + (channel
<< 10)) | 0x00102000)); // OK
4858 write_mchbar32(0x248 + (channel
<< 10), (read_mchbar32(0x248 + (channel
<< 10)) & ~0x00102000)); // OK
4861 write_mchbar32(0x115, read_mchbar32(0x115) | 0x1000000); // OK
4866 if (!(info
.silicon_revision
== 0 || info
.silicon_revision
== 1))
4868 al
|= ((1 << (info
.max_slots_used_in_channel
- 1)) - 1) << 4;
4869 write_mchbar32(0x210, (al
<< 16) | 0x20); // OK
4872 for (channel
= 0; channel
< NUM_CHANNELS
; channel
++) {
4873 write_mchbar32(0x288 + (channel
<< 10), 0x70605040); // OK
4874 write_mchbar32(0x28c + (channel
<< 10), 0xfffec080); // OK
4875 write_mchbar32(0x290 + (channel
<< 10), 0x282091c | ((info
.max_slots_used_in_channel
- 1) << 0x16)); // OK
4878 pcie_read_config32(NORTHBRIDGE
, 0x40); // = DEFAULT_EPBAR | 0x001 // OK
4879 reg1c
= read32p(DEFAULT_EPBAR
| 0x01c); // = 0x8001 // OK
4880 pcie_read_config32(NORTHBRIDGE
, 0x40); // = DEFAULT_EPBAR | 0x001 // OK
4881 write32p(DEFAULT_EPBAR
| 0x01c, reg1c
); // OK
4882 read_mchbar8(0xe08); // = 0x0
4883 pcie_read_config32(NORTHBRIDGE
, 0xe4); // = 0x316126
4884 write_mchbar8(0x1210, read_mchbar8(0x1210) | 2); // OK
4885 write_mchbar32(0x1200, 0x8800440); // OK
4886 write_mchbar32(0x1204, 0x53ff0453); // OK
4887 write_mchbar32(0x1208, 0x19002043); // OK
4888 write_mchbar16(0x1214, 0x320); // OK
4890 if (info
.revision
== 0x10 || info
.revision
== 0x11) {
4891 write_mchbar16(0x1214, 0x220); // OK
4892 write_mchbar8(0x1210, read_mchbar8(0x1210) | 0x40); // OK
4895 write_mchbar8(0x1214, read_mchbar8(0x1214) | 0x4); // OK
4896 write_mchbar8(0x120c, 0x1); // OK
4897 write_mchbar8(0x1218, 0x3); // OK
4898 write_mchbar8(0x121a, 0x3); // OK
4899 write_mchbar8(0x121c, 0x3); // OK
4900 write_mchbar16(0xc14, 0x0); // OK
4901 write_mchbar16(0xc20, 0x0); // OK
4902 write_mchbar32(0x1c, 0x0); // OK
4904 /* revision dependent here. */
4906 write_mchbar16(0x1230, read_mchbar16(0x1230) | 0x1f07); // OK
4908 if (info
.uma_enabled
)
4909 write_mchbar32(0x11f4, read_mchbar32(0x11f4) | 0x10000000); // OK
4911 write_mchbar16(0x1230, read_mchbar16(0x1230) | 0x8000); // OK
4912 write_mchbar8(0x1214, read_mchbar8(0x1214) | 1); // OK
4917 reg_1020
= read_mchbar32(0x1020); // = 0x6c733c // OK
4918 write_mchbar8(0x1070, 0x1); // OK
4920 write_mchbar32(0x1000, 0x100); // OK
4921 write_mchbar8(0x1007, 0x0); // OK
4923 if (reg_1020
!= 0) {
4924 write_mchbar16(0x1018, 0x0); // OK
4926 ebpb
= reg_1020
& 0xff;
4934 write_mchbar32(0x1014, 0xffffffff); // OK
4936 write_mchbar32(0x1010, ((((ebpb
+ 0x7d) << 7) / bl
) & 0xff) * (! !reg_1020
)); // OK
4938 write_mchbar8(0x101c, 0xb8); // OK
4940 write_mchbar8(0x123e, (read_mchbar8(0x123e) & 0xf) | 0x60); // OK
4941 if (reg_1020
!= 0) {
4942 write_mchbar32(0x123c, (read_mchbar32(0x123c) & ~0x00900000) | 0x600000); // OK
4943 write_mchbar8(0x101c, 0xb8); // OK
4946 setup_heci_uma(&info
);
4948 if (info
.uma_enabled
) {
4950 write_mchbar32(0x11b0, read_mchbar32(0x11b0) | 0x4000); // OK
4951 write_mchbar32(0x11b4, read_mchbar32(0x11b4) | 0x4000); // OK
4952 write_mchbar16(0x1190, read_mchbar16(0x1190) | 0x4000); // OK
4954 ax
= read_mchbar16(0x1190) & 0xf00; // = 0x480a // OK
4955 write_mchbar16(0x1170, ax
| (read_mchbar16(0x1170) & 0x107f) | 0x4080); // OK
4956 write_mchbar16(0x1170, read_mchbar16(0x1170) | 0x1000); // OK
4961 for (ecx
= 0xffff; ecx
&& (read_mchbar16(0x1170) & 0x1000); ecx
--) ; // OK
4962 write_mchbar16(0x1190, read_mchbar16(0x1190) & ~0x4000); // OK
4965 pcie_write_config8(SOUTHBRIDGE
, GEN_PMCON_2
,
4966 pcie_read_config8(SOUTHBRIDGE
, GEN_PMCON_2
) & ~0x80);
4968 write_mchbar16(0x2ca8, 0x8);
4972 dump_timings(&info
);
4973 cbmem_wasnot_inited
= cbmem_recovery(s3resume
);
4976 save_timings(&info
);
4977 if (s3resume
&& cbmem_wasnot_inited
) {
4979 printk(BIOS_ERR
, "Failed S3 resume.\n");
4980 ram_check(0x100000, 0x200000);
4982 /* Clear SLP_TYPE. */
4983 reg32
= inl(DEFAULT_PMBASE
+ 0x04);
4984 outl(reg32
& ~(7 << 10), DEFAULT_PMBASE
+ 0x04);
4986 /* Failed S3 resume, reset to come up cleanly */