blob: 19af3bbde2f54871092727af04ff8221ea0c5ebc [file] [log] [blame]
Vladimir Serbinenkoc6f6be02013-11-12 22:32:08 +01001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2013 Vladimir Serbinenko.
5 *
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.
10 *
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.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21/* Please don't remove this. It's needed it to do debugging
22 and reverse engineering to support in futur more nehalem variants. */
23#ifndef REAL
24#define REAL 1
25#endif
26
27#if REAL
28#include <console/console.h>
29#include <string.h>
30#include <arch/hlt.h>
31#include <arch/io.h>
32#include <cpu/x86/msr.h>
33#include <cbmem.h>
34#include <arch/cbfs.h>
35#include <cbfs.h>
36#include <ip_checksum.h>
37#include <pc80/mc146818rtc.h>
38#include <device/pci_def.h>
39#include <arch/cpu.h>
40#include <spd.h>
41#include "raminit.h"
42#include <timestamp.h>
43#include <cpu/x86/mtrr.h>
44#include <cpu/intel/speedstep.h>
45#include <cpu/intel/turbo.h>
46#endif
47
48#if !REAL
49typedef unsigned char u8;
50typedef unsigned short u16;
51typedef unsigned int u32;
52typedef u32 device_t;
53#endif
54
55#include "nehalem.h"
56
57#include "southbridge/intel/ibexpeak/me.h"
58
59#if REAL
60#include <delay.h>
61#endif
62
63#define NORTHBRIDGE PCI_DEV(0, 0, 0)
64#define SOUTHBRIDGE PCI_DEV(0, 0x1f, 0)
65#define GMA PCI_DEV (0, 0x2, 0x0)
66#define HECIDEV PCI_DEV(0, 0x16, 0)
67#define HECIBAR 0x10
68
69#define FOR_ALL_RANKS \
70 for (channel = 0; channel < NUM_CHANNELS; channel++) \
71 for (slot = 0; slot < NUM_SLOTS; slot++) \
72 for (rank = 0; rank < NUM_RANKS; rank++)
73
74#define FOR_POPULATED_RANKS \
75 for (channel = 0; channel < NUM_CHANNELS; channel++) \
76 for (slot = 0; slot < NUM_SLOTS; slot++) \
77 for (rank = 0; rank < NUM_RANKS; rank++) \
78 if (info->populated_ranks[channel][slot][rank])
79
80#define FOR_POPULATED_RANKS_BACKWARDS \
81 for (channel = NUM_CHANNELS - 1; channel >= 0; channel--) \
82 for (slot = 0; slot < NUM_SLOTS; slot++) \
83 for (rank = 0; rank < NUM_RANKS; rank++) \
84 if (info->populated_ranks[channel][slot][rank])
85
86/* [REG_178][CHANNEL][2 * SLOT + RANK][LANE] */
87typedef struct {
88 u8 smallest;
89 u8 largest;
90} timing_bounds_t[2][2][2][9];
91
92struct ram_training {
93 /* [TM][CHANNEL][SLOT][RANK][LANE] */
94 u16 lane_timings[4][2][2][2][9];
95 u16 reg_178;
96 u16 reg_10b;
97
98 u8 reg178_center;
99 u8 reg178_smallest;
100 u8 reg178_largest;
101 timing_bounds_t timing_bounds[2];
102 u16 timing_offset[2][2][2][9];
103 u16 timing2_offset[2][2][2][9];
104 u16 timing2_bounds[2][2][2][9][2];
105};
106
107#if !REAL
108#include "raminit_fake.c"
109#else
110
111#include <lib.h> /* Prototypes */
112
113static inline void write_mchbar32(u32 addr, u32 val)
114{
115 MCHBAR32(addr) = val;
116}
117
118static inline void write_mchbar16(u32 addr, u16 val)
119{
120 MCHBAR16(addr) = val;
121}
122
123static inline void write_mchbar8(u32 addr, u8 val)
124{
125 MCHBAR8(addr) = val;
126}
127
128
129static inline u32 read_mchbar32(u32 addr)
130{
131 return MCHBAR32(addr);
132}
133
134static inline u16 read_mchbar16(u32 addr)
135{
136 return MCHBAR16(addr);
137}
138
139static inline u8 read_mchbar8(u32 addr)
140{
141 return MCHBAR8(addr);
142}
143
144static inline u8 read_mchbar8_bypass(u32 addr)
145{
146 return MCHBAR8(addr);
147}
148
149static void clflush(u32 addr)
150{
151 asm volatile ("clflush (%0)"::"r" (addr));
152}
153
154typedef struct _u128 {
155 u64 lo;
156 u64 hi;
157} u128;
158
159static void read128(u32 addr, u64 * out)
160{
161 u128 ret;
162 u128 stor;
163 asm volatile ("movdqu %%xmm0, %0\n"
164 "movdqa (%2), %%xmm0\n"
165 "movdqu %%xmm0, %1\n"
166 "movdqu %0, %%xmm0":"+m" (stor), "=m"(ret):"r"(addr));
167 out[0] = ret.lo;
168 out[1] = ret.hi;
169}
170
171#endif
172
173/* OK */
174static void write_1d0(u32 val, u16 addr, int bits, int flag)
175{
176 write_mchbar32(0x1d0, 0);
177 while (read_mchbar32(0x1d0) & 0x800000) ;
178 write_mchbar32(0x1d4,
179 (val & ((1 << bits) - 1)) | (2 << bits) | (flag <<
180 bits));
181 write_mchbar32(0x1d0, 0x40000000 | addr);
182 while (read_mchbar32(0x1d0) & 0x800000) ;
183}
184
185/* OK */
186static u16 read_1d0(u16 addr, int split)
187{
188 u32 val;
189 write_mchbar32(0x1d0, 0);
190 while (read_mchbar32(0x1d0) & 0x800000) ;
191 write_mchbar32(0x1d0,
192 0x80000000 | (((read_mchbar8(0x246) >> 2) & 3) +
193 0x361 - addr));
194 while (read_mchbar32(0x1d0) & 0x800000) ;
195 val = read_mchbar32(0x1d8);
196 write_1d0(0, 0x33d, 0, 0);
197 write_1d0(0, 0x33d, 0, 0);
198 val &= ((1 << split) - 1);
199 // printk (BIOS_ERR, "R1D0C [%x] => %x\n", addr, val);
200 return val;
201}
202
203static void sfence(void)
204{
205#if REAL
206 asm volatile ("sfence");
207#endif
208}
209
210static inline u16 get_lane_offset(int slot, int rank, int lane)
211{
212 return 0x124 * lane + ((lane & 4) ? 0x23e : 0) + 11 * rank + 22 * slot -
213 0x452 * (lane == 8);
214}
215
216static inline u16 get_timing_register_addr(int lane, int tm, int slot, int rank)
217{
218 const u16 offs[] = { 0x1d, 0xa8, 0xe6, 0x5c };
219 return get_lane_offset(slot, rank, lane) + offs[(tm + 3) % 4];
220}
221
222#if REAL
223static u32 gav_real(int line, u32 in)
224{
225 // printk (BIOS_DEBUG, "%d: GAV: %x\n", line, in);
226 return in;
227}
228
229#define gav(x) gav_real (__LINE__, (x))
230#endif
231struct raminfo {
232 u16 clock_speed_index; /* clock_speed (REAL, not DDR) / 133.(3) - 3 */
233 u16 fsb_frequency; /* in 1.(1)/2 MHz. */
234 u8 is_x16_module[2][2]; /* [CHANNEL][SLOT] */
235 u8 density[2][2]; /* [CHANNEL][SLOT] */
236 u8 populated_ranks[2][2][2]; /* [CHANNEL][SLOT][RANK] */
237 int rank_start[2][2][2];
238 u8 cas_latency;
239 u8 board_lane_delay[9];
240 u8 use_ecc;
241 u8 revision;
242 u8 max_supported_clock_speed_index;
243 u8 uma_enabled;
244 u8 spd[2][2][151]; /* [CHANNEL][SLOT][BYTE] */
245 u8 silicon_revision;
246 u8 populated_ranks_mask[2];
247 u8 max_slots_used_in_channel;
248 u8 mode4030[2];
249 u16 avg4044[2];
250 u16 max4048[2];
251 unsigned total_memory_mb;
252 unsigned interleaved_part_mb;
253 unsigned non_interleaved_part_mb;
254
255 u32 heci_bar;
256 u64 heci_uma_addr;
257 unsigned memory_reserved_for_heci_mb;
258
259 struct ram_training training;
260 u32 last_500_command[2];
261
262 u8 reg2ca9_bit0;
263 u8 reg274265[2][3]; /* [CHANNEL][REGISTER] */
264 u32 delay46_ps[2];
265 u32 delay54_ps[2];
266 u8 revision_flag_1;
267 u8 some_delay_1_cycle_floor;
268 u8 some_delay_2_halfcycles_ceil;
269 u8 some_delay_3_ps_rounded;
270
271 const struct ram_training *cached_training;
272};
273
274static void
275write_500(struct raminfo *info, int channel, u32 val, u16 addr, int bits,
276 int flag);
277
278/* OK */
279static u16
280read_500(struct raminfo *info, int channel, u16 addr, int split)
281{
282 u32 val;
283 info->last_500_command[channel] = 0x80000000;
284 write_mchbar32(0x500 + (channel << 10), 0);
285 while (read_mchbar32(0x500 + (channel << 10)) & 0x800000) ;
286 write_mchbar32(0x500 + (channel << 10),
287 0x80000000 |
288 (((read_mchbar8(0x246 + (channel << 10)) >> 2) &
289 3) + 0xb88 - addr));
290 while (read_mchbar32(0x500 + (channel << 10)) & 0x800000) ;
291 val = read_mchbar32(0x508 + (channel << 10));
292 return val & ((1 << split) - 1);
293}
294
295/* OK */
296static void
297write_500(struct raminfo *info, int channel, u32 val, u16 addr, int bits,
298 int flag)
299{
300 if (info->last_500_command[channel] == 0x80000000) {
301 info->last_500_command[channel] = 0x40000000;
302 write_500(info, channel, 0, 0xb61, 0, 0);
303 }
304 write_mchbar32(0x500 + (channel << 10), 0);
305 while (read_mchbar32(0x500 + (channel << 10)) & 0x800000) ;
306 write_mchbar32(0x504 + (channel << 10),
307 (val & ((1 << bits) - 1)) | (2 << bits) | (flag <<
308 bits));
309 write_mchbar32(0x500 + (channel << 10), 0x40000000 | addr);
310 while (read_mchbar32(0x500 + (channel << 10)) & 0x800000) ;
311}
312
313static int rw_test(int rank)
314{
315 const u32 mask = 0xf00fc33c;
316 int ok = 0xff;
317 int i;
318 for (i = 0; i < 64; i++)
319 write32((rank << 28) | (i << 2), 0);
320 sfence();
321 for (i = 0; i < 64; i++)
322 gav(read32((rank << 28) | (i << 2)));
323 sfence();
324 for (i = 0; i < 32; i++) {
325 u32 pat = (((mask >> i) & 1) ? 0xffffffff : 0);
326 write32((rank << 28) | (i << 3), pat);
327 write32((rank << 28) | (i << 3) | 4, pat);
328 }
329 sfence();
330 for (i = 0; i < 32; i++) {
331 u8 pat = (((mask >> i) & 1) ? 0xff : 0);
332 int j;
333 u32 val;
334 gav(val = read32((rank << 28) | (i << 3)));
335 for (j = 0; j < 4; j++)
336 if (((val >> (j * 8)) & 0xff) != pat)
337 ok &= ~(1 << j);
338 gav(val = read32((rank << 28) | (i << 3) | 4));
339 for (j = 0; j < 4; j++)
340 if (((val >> (j * 8)) & 0xff) != pat)
341 ok &= ~(16 << j);
342 }
343 sfence();
344 for (i = 0; i < 64; i++)
345 write32((rank << 28) | (i << 2), 0);
346 sfence();
347 for (i = 0; i < 64; i++)
348 gav(read32((rank << 28) | (i << 2)));
349
350 return ok;
351}
352
353static void
354program_timings(struct raminfo *info, u16 base, int channel, int slot, int rank)
355{
356 int lane;
357 for (lane = 0; lane < 8; lane++) {
358 write_500(info, channel,
359 base +
360 info->training.
361 lane_timings[2][channel][slot][rank][lane],
362 get_timing_register_addr(lane, 2, slot, rank), 9, 0);
363 write_500(info, channel,
364 base +
365 info->training.
366 lane_timings[3][channel][slot][rank][lane],
367 get_timing_register_addr(lane, 3, slot, rank), 9, 0);
368 }
369}
370
371static void write_26c(int channel, u16 si)
372{
373 write_mchbar32(0x26c + (channel << 10), 0x03243f35);
374 write_mchbar32(0x268 + (channel << 10), 0xcfc00000 | (si << 9));
375 write_mchbar16(0x2b9 + (channel << 10), si);
376}
377
378static u32 get_580(int channel, u8 addr)
379{
380 u32 ret;
381 gav(read_1d0(0x142, 3));
382 write_mchbar8(0x5ff, 0x0); /* OK */
383 write_mchbar8(0x5ff, 0x80); /* OK */
384 write_mchbar32(0x580 + (channel << 10), 0x8493c012 | addr);
385 write_mchbar8(0x580 + (channel << 10),
386 read_mchbar8(0x580 + (channel << 10)) | 1);
387 while (!((ret = read_mchbar32(0x580 + (channel << 10))) & 0x10000)) ;
388 write_mchbar8(0x580 + (channel << 10),
389 read_mchbar8(0x580 + (channel << 10)) & ~1);
390 return ret;
391}
392
393const int cached_config = 0;
394
395#define NUM_CHANNELS 2
396#define NUM_SLOTS 2
397#define NUM_RANKS 2
398#define RANK_SHIFT 28
399#define CHANNEL_SHIFT 10
400
401#include "raminit_tables.c"
402
403static void seq9(struct raminfo *info, int channel, int slot, int rank)
404{
405 int i, lane;
406
407 for (i = 0; i < 2; i++)
408 for (lane = 0; lane < 8; lane++)
409 write_500(info, channel,
410 info->training.lane_timings[i +
411 1][channel][slot]
412 [rank][lane], get_timing_register_addr(lane,
413 i + 1,
414 slot,
415 rank),
416 9, 0);
417
418 write_1d0(1, 0x103, 6, 1);
419 for (lane = 0; lane < 8; lane++)
420 write_500(info, channel,
421 info->training.
422 lane_timings[0][channel][slot][rank][lane],
423 get_timing_register_addr(lane, 0, slot, rank), 9, 0);
424
425 for (i = 0; i < 2; i++) {
426 for (lane = 0; lane < 8; lane++)
427 write_500(info, channel,
428 info->training.lane_timings[i +
429 1][channel][slot]
430 [rank][lane], get_timing_register_addr(lane,
431 i + 1,
432 slot,
433 rank),
434 9, 0);
435 gav(get_580(channel, ((i + 1) << 2) | (rank << 5)));
436 }
437
438 gav(read_1d0(0x142, 3)); // = 0x10408118
439 write_mchbar8(0x5ff, 0x0); /* OK */
440 write_mchbar8(0x5ff, 0x80); /* OK */
441 write_1d0(0x2, 0x142, 3, 1);
442 for (lane = 0; lane < 8; lane++) {
443 // printk (BIOS_ERR, "before: %x\n", info->training.lane_timings[2][channel][slot][rank][lane]);
444 info->training.lane_timings[2][channel][slot][rank][lane] =
445 read_500(info, channel,
446 get_timing_register_addr(lane, 2, slot, rank), 9);
447 //printk (BIOS_ERR, "after: %x\n", info->training.lane_timings[2][channel][slot][rank][lane]);
448 info->training.lane_timings[3][channel][slot][rank][lane] =
449 info->training.lane_timings[2][channel][slot][rank][lane] +
450 0x20;
451 }
452}
453
454static int count_ranks_in_channel(struct raminfo *info, int channel)
455{
456 int slot, rank;
457 int res = 0;
458 for (slot = 0; slot < NUM_SLOTS; slot++)
459 for (rank = 0; rank < NUM_SLOTS; rank++)
460 res += info->populated_ranks[channel][slot][rank];
461 return res;
462}
463
464static void
465config_rank(struct raminfo *info, int s3resume, int channel, int slot, int rank)
466{
467 int add;
468
469 write_1d0(0, 0x178, 7, 1);
470 seq9(info, channel, slot, rank);
471 program_timings(info, 0x80, channel, slot, rank);
472
473 if (channel == 0)
474 add = count_ranks_in_channel(info, 1);
475 else
476 add = 0;
477 if (!s3resume)
478 gav(rw_test(rank + add));
479 program_timings(info, 0x00, channel, slot, rank);
480 if (!s3resume)
481 gav(rw_test(rank + add));
482 if (!s3resume)
483 gav(rw_test(rank + add));
484 write_1d0(0, 0x142, 3, 1);
485 write_1d0(0, 0x103, 6, 1);
486
487 gav(get_580(channel, 0xc | (rank << 5)));
488 gav(read_1d0(0x142, 3));
489
490 write_mchbar8(0x5ff, 0x0); /* OK */
491 write_mchbar8(0x5ff, 0x80); /* OK */
492}
493
494static void set_4cf(struct raminfo *info, int channel, u8 val)
495{
496 gav(read_500(info, channel, 0x4cf, 4)); // = 0xc2300cf9
497 write_500(info, channel, val, 0x4cf, 4, 1);
498 gav(read_500(info, channel, 0x659, 4)); // = 0x80300839
499 write_500(info, channel, val, 0x659, 4, 1);
500 gav(read_500(info, channel, 0x697, 4)); // = 0x80300839
501 write_500(info, channel, val, 0x697, 4, 1);
502}
503
504static void set_334(int zero)
505{
506 int j, k, channel;
507 const u32 val3[] = { 0x2a2b2a2b, 0x26272627, 0x2e2f2e2f, 0x2a2b };
508 u32 vd8[2][16];
509
510 for (channel = 0; channel < NUM_CHANNELS; channel++) {
511 for (j = 0; j < 4; j++) {
512 u32 a = (j == 1) ? 0x29292929 : 0x31313131;
513 u32 lmask = (j == 3) ? 0xffff : 0xffffffff;
514 u16 c;
515 if ((j == 0 || j == 3) && zero)
516 c = 0;
517 else if (j == 3)
518 c = 0x5f;
519 else
520 c = 0x5f5f;
521
522 for (k = 0; k < 2; k++) {
523 write_mchbar32(0x138 + 8 * k,
524 (channel << 26) | (j << 24));
525 gav(vd8[1][(channel << 3) | (j << 1) | k] =
526 read_mchbar32(0x138 + 8 * k));
527 gav(vd8[0][(channel << 3) | (j << 1) | k] =
528 read_mchbar32(0x13c + 8 * k));
529 }
530
531 write_mchbar32(0x334 + (channel << 10) + (j * 0x44),
532 zero ? 0 : val3[j]);
533 write_mchbar32(0x32c + (channel << 10) + (j * 0x44),
534 zero ? 0 : (0x18191819 & lmask));
535 write_mchbar16(0x34a + (channel << 10) + (j * 0x44), c);
536 write_mchbar32(0x33c + (channel << 10) + (j * 0x44),
537 zero ? 0 : (a & lmask));
538 write_mchbar32(0x344 + (channel << 10) + (j * 0x44),
539 zero ? 0 : (a & lmask));
540 }
541 }
542
543 write_mchbar32(0x130, read_mchbar32(0x130) | 1); /* OK */
544 while (read_mchbar8(0x130) & 1) ; /* OK */
545}
546
547static void rmw_1d0(u16 addr, u32 and, u32 or, int split, int flag)
548{
549 u32 v;
550 v = read_1d0(addr, split);
551 write_1d0((v & and) | or, addr, split, flag);
552}
553
554static int find_highest_bit_set(u16 val)
555{
556 int i;
557 for (i = 15; i >= 0; i--)
558 if (val & (1 << i))
559 return i;
560 return -1;
561}
562
563static int find_lowest_bit_set32(u32 val)
564{
565 int i;
566 for (i = 0; i < 32; i++)
567 if (val & (1 << i))
568 return i;
569 return -1;
570}
571
572#define max(a,b) (((a) > (b)) ? (a) : (b))
573#define min(a,b) (((a) < (b)) ? (a) : (b))
574
575enum {
576 DEVICE_TYPE = 2,
577 MODULE_TYPE = 3,
578 DENSITY = 4,
579 RANKS_AND_DQ = 7,
580 MEMORY_BUS_WIDTH = 8,
581 TIMEBASE_DIVIDEND = 10,
582 TIMEBASE_DIVISOR = 11,
583 CYCLETIME = 12,
584
585 CAS_LATENCIES_LSB = 14,
586 CAS_LATENCIES_MSB = 15,
587 CAS_LATENCY_TIME = 16,
588 THERMAL_AND_REFRESH = 31,
589 REFERENCE_RAW_CARD_USED = 62,
590 RANK1_ADDRESS_MAPPING = 63
591};
592
593static void calculate_timings(struct raminfo *info)
594{
595 unsigned cycletime;
596 unsigned cas_latency_time;
597 unsigned supported_cas_latencies;
598 unsigned channel, slot;
599 unsigned clock_speed_index;
600 unsigned min_cas_latency;
601 unsigned cas_latency;
602 unsigned max_clock_index;
603
604 /* Find common CAS latency */
605 supported_cas_latencies = 0x3fe;
606 for (channel = 0; channel < NUM_CHANNELS; channel++)
607 for (slot = 0; slot < NUM_SLOTS; slot++)
608 if (info->populated_ranks[channel][slot][0])
609 supported_cas_latencies &=
610 2 *
611 (info->
612 spd[channel][slot][CAS_LATENCIES_LSB] |
613 (info->
614 spd[channel][slot][CAS_LATENCIES_MSB] <<
615 8));
616
617 max_clock_index = min(3, info->max_supported_clock_speed_index);
618
619 cycletime = min_cycletime[max_clock_index];
620 cas_latency_time = min_cas_latency_time[max_clock_index];
621
622 for (channel = 0; channel < NUM_CHANNELS; channel++)
623 for (slot = 0; slot < NUM_SLOTS; slot++)
624 if (info->populated_ranks[channel][slot][0]) {
625 unsigned timebase;
626 timebase =
627 1000 *
628 info->
629 spd[channel][slot][TIMEBASE_DIVIDEND] /
630 info->spd[channel][slot][TIMEBASE_DIVISOR];
631 cycletime =
632 max(cycletime,
633 timebase *
634 info->spd[channel][slot][CYCLETIME]);
635 cas_latency_time =
636 max(cas_latency_time,
637 timebase *
638 info->
639 spd[channel][slot][CAS_LATENCY_TIME]);
640 }
641 for (clock_speed_index = 0; clock_speed_index < 3; clock_speed_index++) {
642 if (cycletime == min_cycletime[clock_speed_index])
643 break;
644 if (cycletime > min_cycletime[clock_speed_index]) {
645 clock_speed_index--;
646 cycletime = min_cycletime[clock_speed_index];
647 break;
648 }
649 }
650 min_cas_latency = (cas_latency_time + cycletime - 1) / cycletime;
651 cas_latency = 0;
652 while (supported_cas_latencies) {
653 cas_latency = find_highest_bit_set(supported_cas_latencies) + 3;
654 if (cas_latency <= min_cas_latency)
655 break;
656 supported_cas_latencies &=
657 ~(1 << find_highest_bit_set(supported_cas_latencies));
658 }
659
660 if (cas_latency != min_cas_latency && clock_speed_index)
661 clock_speed_index--;
662
663 if (cas_latency * min_cycletime[clock_speed_index] > 20000)
664 die("Couldn't configure DRAM");
665 info->clock_speed_index = clock_speed_index;
666 info->cas_latency = cas_latency;
667}
668
669static void program_base_timings(struct raminfo *info)
670{
671 unsigned channel;
672 unsigned slot, rank, lane;
673 unsigned extended_silicon_revision;
674 int i;
675
676 extended_silicon_revision = info->silicon_revision;
677 if (info->silicon_revision == 0)
678 for (channel = 0; channel < NUM_CHANNELS; channel++)
679 for (slot = 0; slot < NUM_SLOTS; slot++)
680 if ((info->
681 spd[channel][slot][MODULE_TYPE] & 0xF) ==
682 3)
683 extended_silicon_revision = 4;
684
685 for (channel = 0; channel < NUM_CHANNELS; channel++) {
686 for (slot = 0; slot < NUM_SLOTS; slot++)
687 for (rank = 0; rank < NUM_SLOTS; rank++) {
688 int card_timing_2;
689 if (!info->populated_ranks[channel][slot][rank])
690 continue;
691
692 for (lane = 0; lane < 9; lane++) {
693 int tm_reg;
694 int card_timing;
695
696 card_timing = 0;
697 if ((info->
698 spd[channel][slot][MODULE_TYPE] &
699 0xF) == 3) {
700 int reference_card;
701 reference_card =
702 info->
703 spd[channel][slot]
704 [REFERENCE_RAW_CARD_USED] &
705 0x1f;
706 if (reference_card == 3)
707 card_timing =
708 u16_ffd1188[0][lane]
709 [info->
710 clock_speed_index];
711 if (reference_card == 5)
712 card_timing =
713 u16_ffd1188[1][lane]
714 [info->
715 clock_speed_index];
716 }
717
718 info->training.
719 lane_timings[0][channel][slot][rank]
720 [lane] =
721 u8_FFFD1218[info->
722 clock_speed_index];
723 info->training.
724 lane_timings[1][channel][slot][rank]
725 [lane] = 256;
726
727 for (tm_reg = 2; tm_reg < 4; tm_reg++)
728 info->training.
729 lane_timings[tm_reg]
730 [channel][slot][rank][lane]
731 =
732 u8_FFFD1240[channel]
733 [extended_silicon_revision]
734 [lane][2 * slot +
735 rank][info->
736 clock_speed_index]
737 + info->max4048[channel]
738 +
739 u8_FFFD0C78[channel]
740 [extended_silicon_revision]
741 [info->
742 mode4030[channel]][slot]
743 [rank][info->
744 clock_speed_index]
745 + card_timing;
746 for (tm_reg = 0; tm_reg < 4; tm_reg++)
747 write_500(info, channel,
748 info->training.
749 lane_timings[tm_reg]
750 [channel][slot][rank]
751 [lane],
752 get_timing_register_addr
753 (lane, tm_reg, slot,
754 rank), 9, 0);
755 }
756
757 card_timing_2 = 0;
758 if (!(extended_silicon_revision != 4
759 || (info->
760 populated_ranks_mask[channel] & 5) ==
761 5)) {
762 if ((info->
763 spd[channel][slot]
764 [REFERENCE_RAW_CARD_USED] & 0x1F)
765 == 3)
766 card_timing_2 =
767 u16_FFFE0EB8[0][info->
768 clock_speed_index];
769 if ((info->
770 spd[channel][slot]
771 [REFERENCE_RAW_CARD_USED] & 0x1F)
772 == 5)
773 card_timing_2 =
774 u16_FFFE0EB8[1][info->
775 clock_speed_index];
776 }
777
778 for (i = 0; i < 3; i++)
779 write_500(info, channel,
780 (card_timing_2 +
781 info->max4048[channel]
782 +
783 u8_FFFD0EF8[channel]
784 [extended_silicon_revision]
785 [info->
786 mode4030[channel]][info->
787 clock_speed_index]),
788 u16_fffd0c50[i][slot][rank],
789 8, 1);
790 write_500(info, channel,
791 (info->max4048[channel] +
792 u8_FFFD0C78[channel]
793 [extended_silicon_revision][info->
794 mode4030
795 [channel]]
796 [slot][rank][info->
797 clock_speed_index]),
798 u16_fffd0c70[slot][rank], 7, 1);
799 }
800 if (!info->populated_ranks_mask[channel])
801 continue;
802 for (i = 0; i < 3; i++)
803 write_500(info, channel,
804 (info->max4048[channel] +
805 info->avg4044[channel]
806 +
807 u8_FFFD17E0[channel]
808 [extended_silicon_revision][info->
809 mode4030
810 [channel]][info->
811 clock_speed_index]),
812 u16_fffd0c68[i], 8, 1);
813 }
814}
815
816static unsigned int fsbcycle_ps(struct raminfo *info)
817{
818 return 900000 / info->fsb_frequency;
819}
820
821/* The time of DDR transfer in ps. */
822static unsigned int halfcycle_ps(struct raminfo *info)
823{
824 return 3750 / (info->clock_speed_index + 3);
825}
826
827/* The time of clock cycle in ps. */
828static unsigned int cycle_ps(struct raminfo *info)
829{
830 return 2 * halfcycle_ps(info);
831}
832
833/* Frequency in 1.(1)=10/9 MHz units. */
834static unsigned frequency_11(struct raminfo *info)
835{
836 return (info->clock_speed_index + 3) * 120;
837}
838
839/* Frequency in 0.1 MHz units. */
840static unsigned frequency_01(struct raminfo *info)
841{
842 return 100 * frequency_11(info) / 9;
843}
844
845static unsigned ps_to_halfcycles(struct raminfo *info, unsigned int ps)
846{
847 return (frequency_11(info) * 2) * ps / 900000;
848}
849
850static unsigned ns_to_cycles(struct raminfo *info, unsigned int ns)
851{
852 return (frequency_11(info)) * ns / 900;
853}
854
855static void compute_derived_timings(struct raminfo *info)
856{
857 unsigned channel, slot, rank;
858 int extended_silicon_revision;
859 int some_delay_1_ps;
860 int some_delay_2_ps;
861 int some_delay_2_halfcycles_ceil;
862 int some_delay_2_halfcycles_floor;
863 int some_delay_3_ps;
864 int some_delay_3_halfcycles;
865 int some_delay_3_ps_rounded;
866 int some_delay_1_cycle_ceil;
867 int some_delay_1_cycle_floor;
868
869 some_delay_3_halfcycles = 0;
870 some_delay_3_ps_rounded = 0;
871 extended_silicon_revision = info->silicon_revision;
872 if (!info->silicon_revision)
873 for (channel = 0; channel < NUM_CHANNELS; channel++)
874 for (slot = 0; slot < NUM_SLOTS; slot++)
875 if ((info->
876 spd[channel][slot][MODULE_TYPE] & 0xF) ==
877 3)
878 extended_silicon_revision = 4;
879 if (info->board_lane_delay[7] < 5)
880 info->board_lane_delay[7] = 5;
881 info->revision_flag_1 = 2;
882 if (info->silicon_revision == 2 || info->silicon_revision == 3)
883 info->revision_flag_1 = 0;
884 if (info->revision < 16)
885 info->revision_flag_1 = 0;
886
887 if (info->revision < 8)
888 info->revision_flag_1 = 0;
889 if (info->revision >= 8 && (info->silicon_revision == 0
890 || info->silicon_revision == 1))
891 some_delay_2_ps = 735;
892 else
893 some_delay_2_ps = 750;
894
895 if (info->revision >= 0x10 && (info->silicon_revision == 0
896 || info->silicon_revision == 1))
897 some_delay_1_ps = 3929;
898 else
899 some_delay_1_ps = 3490;
900
901 some_delay_1_cycle_floor = some_delay_1_ps / cycle_ps(info);
902 some_delay_1_cycle_ceil = some_delay_1_ps / cycle_ps(info);
903 if (some_delay_1_ps % cycle_ps(info))
904 some_delay_1_cycle_ceil++;
905 else
906 some_delay_1_cycle_floor--;
907 info->some_delay_1_cycle_floor = some_delay_1_cycle_floor;
908 if (info->revision_flag_1)
909 some_delay_2_ps = halfcycle_ps(info) >> 6;
910 some_delay_2_ps +=
911 max(some_delay_1_ps - 30,
912 2 * halfcycle_ps(info) * (some_delay_1_cycle_ceil - 1) + 1000) +
913 375;
914 some_delay_3_ps =
915 halfcycle_ps(info) - some_delay_2_ps % halfcycle_ps(info);
916 if (info->revision_flag_1) {
917 if (some_delay_3_ps < 150)
918 some_delay_3_halfcycles = 0;
919 else
920 some_delay_3_halfcycles =
921 (some_delay_3_ps << 6) / halfcycle_ps(info);
922 some_delay_3_ps_rounded =
923 halfcycle_ps(info) * some_delay_3_halfcycles >> 6;
924 }
925 some_delay_2_halfcycles_ceil =
926 (some_delay_2_ps + halfcycle_ps(info) - 1) / halfcycle_ps(info) -
927 2 * (some_delay_1_cycle_ceil - 1);
928 if (info->revision_flag_1 && some_delay_3_ps < 150)
929 some_delay_2_halfcycles_ceil++;
930 some_delay_2_halfcycles_floor = some_delay_2_halfcycles_ceil;
931 if (info->revision < 0x10)
932 some_delay_2_halfcycles_floor =
933 some_delay_2_halfcycles_ceil - 1;
934 if (!info->revision_flag_1)
935 some_delay_2_halfcycles_floor++;
936 info->some_delay_2_halfcycles_ceil = some_delay_2_halfcycles_ceil;
937 info->some_delay_3_ps_rounded = some_delay_3_ps_rounded;
938 if ((info->populated_ranks[0][0][0] && info->populated_ranks[0][1][0])
939 || (info->populated_ranks[1][0][0]
940 && info->populated_ranks[1][1][0]))
941 info->max_slots_used_in_channel = 2;
942 else
943 info->max_slots_used_in_channel = 1;
944 for (channel = 0; channel < 2; channel++)
945 write_mchbar32(0x244 + (channel << 10),
946 ((info->revision < 8) ? 1 : 0x200)
947 | ((2 - info->max_slots_used_in_channel) << 17) |
948 (channel << 21) | (info->
949 some_delay_1_cycle_floor <<
950 18) | 0x9510);
951 if (info->max_slots_used_in_channel == 1) {
952 info->mode4030[0] = (count_ranks_in_channel(info, 0) == 2);
953 info->mode4030[1] = (count_ranks_in_channel(info, 1) == 2);
954 } else {
955 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 */
956 info->mode4030[1] = ((count_ranks_in_channel(info, 1) == 1)
957 || (count_ranks_in_channel(info, 1) ==
958 2)) ? 2 : 3;
959 }
960 for (channel = 0; channel < NUM_CHANNELS; channel++) {
961 int max_of_unk;
962 int min_of_unk_2;
963
964 int i, count;
965 int sum;
966
967 if (!info->populated_ranks_mask[channel])
968 continue;
969
970 max_of_unk = 0;
971 min_of_unk_2 = 32767;
972
973 sum = 0;
974 count = 0;
975 for (i = 0; i < 3; i++) {
976 int unk1;
977 if (info->revision < 8)
978 unk1 =
979 u8_FFFD1891[0][channel][info->
980 clock_speed_index]
981 [i];
982 else if (!
983 (info->revision >= 0x10
984 || info->revision_flag_1))
985 unk1 =
986 u8_FFFD1891[1][channel][info->
987 clock_speed_index]
988 [i];
989 else
990 unk1 = 0;
991 for (slot = 0; slot < NUM_SLOTS; slot++)
992 for (rank = 0; rank < NUM_RANKS; rank++) {
993 int a = 0;
994 int b = 0;
995
996 if (!info->
997 populated_ranks[channel][slot]
998 [rank])
999 continue;
1000 if (extended_silicon_revision == 4
1001 && (info->
1002 populated_ranks_mask[channel] &
1003 5) != 5) {
1004 if ((info->
1005 spd[channel][slot]
1006 [REFERENCE_RAW_CARD_USED] &
1007 0x1F) == 3) {
1008 a = u16_ffd1178[0]
1009 [info->
1010 clock_speed_index];
1011 b = u16_fe0eb8[0][info->
1012 clock_speed_index];
1013 } else
1014 if ((info->
1015 spd[channel][slot]
1016 [REFERENCE_RAW_CARD_USED]
1017 & 0x1F) == 5) {
1018 a = u16_ffd1178[1]
1019 [info->
1020 clock_speed_index];
1021 b = u16_fe0eb8[1][info->
1022 clock_speed_index];
1023 }
1024 }
1025 min_of_unk_2 = min(min_of_unk_2, a);
1026 min_of_unk_2 = min(min_of_unk_2, b);
1027 if (rank == 0) {
1028 sum += a;
1029 count++;
1030 }
1031 {
1032 int t;
1033 t = b +
1034 u8_FFFD0EF8[channel]
1035 [extended_silicon_revision]
1036 [info->
1037 mode4030[channel]][info->
1038 clock_speed_index];
1039 if (unk1 >= t)
1040 max_of_unk =
1041 max(max_of_unk,
1042 unk1 - t);
1043 }
1044 }
1045 {
1046 int t =
1047 u8_FFFD17E0[channel]
1048 [extended_silicon_revision][info->
1049 mode4030
1050 [channel]]
1051 [info->clock_speed_index] + min_of_unk_2;
1052 if (unk1 >= t)
1053 max_of_unk = max(max_of_unk, unk1 - t);
1054 }
1055 }
1056
1057 info->avg4044[channel] = sum / count;
1058 info->max4048[channel] = max_of_unk;
1059 }
1060}
1061
1062static void jedec_read(struct raminfo *info,
1063 int channel, int slot, int rank,
1064 int total_rank, u8 addr3, unsigned int value)
1065{
1066 /* Handle mirrored mapping. */
1067 if ((rank & 1) && (info->spd[channel][slot][RANK1_ADDRESS_MAPPING] & 1))
1068 addr3 =
1069 (addr3 & 0xCF) | ((addr3 & 0x10) << 1) | ((addr3 >> 1) &
1070 0x10);
1071 write_mchbar8(0x271, addr3 | (read_mchbar8(0x271) & 0xC1));
1072 write_mchbar8(0x671, addr3 | (read_mchbar8(0x671) & 0xC1));
1073
1074 /* Handle mirrored mapping. */
1075 if ((rank & 1) && (info->spd[channel][slot][RANK1_ADDRESS_MAPPING] & 1))
1076 value =
1077 (value & ~0x1f8) | ((value >> 1) & 0xa8) | ((value & 0xa8)
1078 << 1);
1079
1080 read32((value << 3) | (total_rank << 28));
1081
1082 write_mchbar8(0x271, (read_mchbar8(0x271) & 0xC3) | 2);
1083 write_mchbar8(0x671, (read_mchbar8(0x671) & 0xC3) | 2);
1084
1085 read32(total_rank << 28);
1086}
1087
1088enum {
1089 MR1_RZQ12 = 512,
1090 MR1_RZQ2 = 64,
1091 MR1_RZQ4 = 4,
1092 MR1_ODS34OHM = 2
1093};
1094
1095enum {
1096 MR0_BT_INTERLEAVED = 8,
1097 MR0_DLL_RESET_ON = 256
1098};
1099
1100enum {
1101 MR2_RTT_WR_DISABLED = 0,
1102 MR2_RZQ2 = 1 << 10
1103};
1104
1105static void jedec_init(struct raminfo *info)
1106{
1107 int write_recovery;
1108 int channel, slot, rank;
1109 int total_rank;
1110 int dll_on;
1111 int self_refresh_temperature;
1112 int auto_self_refresh;
1113
1114 auto_self_refresh = 1;
1115 self_refresh_temperature = 1;
1116 if (info->board_lane_delay[3] <= 10) {
1117 if (info->board_lane_delay[3] <= 8)
1118 write_recovery = info->board_lane_delay[3] - 4;
1119 else
1120 write_recovery = 5;
1121 } else {
1122 write_recovery = 6;
1123 }
1124 FOR_POPULATED_RANKS {
1125 auto_self_refresh &=
1126 (info->spd[channel][slot][THERMAL_AND_REFRESH] >> 2) & 1;
1127 self_refresh_temperature &=
1128 info->spd[channel][slot][THERMAL_AND_REFRESH] & 1;
1129 }
1130 if (auto_self_refresh == 1)
1131 self_refresh_temperature = 0;
1132
1133 dll_on = ((info->silicon_revision != 2 && info->silicon_revision != 3)
1134 || (info->populated_ranks[0][0][0]
1135 && info->populated_ranks[0][1][0])
1136 || (info->populated_ranks[1][0][0]
1137 && info->populated_ranks[1][1][0]));
1138
1139 total_rank = 0;
1140
1141 for (channel = NUM_CHANNELS - 1; channel >= 0; channel--) {
1142 int rtt, rtt_wr = MR2_RTT_WR_DISABLED;
1143 int rzq_reg58e;
1144
1145 if (info->silicon_revision == 2 || info->silicon_revision == 3) {
1146 rzq_reg58e = 64;
1147 rtt = MR1_RZQ2;
1148 if (info->clock_speed_index != 0) {
1149 rzq_reg58e = 4;
1150 if (info->populated_ranks_mask[channel] == 3)
1151 rtt = MR1_RZQ4;
1152 }
1153 } else {
1154 if ((info->populated_ranks_mask[channel] & 5) == 5) {
1155 rtt = MR1_RZQ12;
1156 rzq_reg58e = 64;
1157 rtt_wr = MR2_RZQ2;
1158 } else {
1159 rzq_reg58e = 4;
1160 rtt = MR1_RZQ4;
1161 }
1162 }
1163
1164 write_mchbar16(0x588 + (channel << 10), 0x0);
1165 write_mchbar16(0x58a + (channel << 10), 0x4);
1166 write_mchbar16(0x58c + (channel << 10), rtt | MR1_ODS34OHM);
1167 write_mchbar16(0x58e + (channel << 10), rzq_reg58e | 0x82);
1168 write_mchbar16(0x590 + (channel << 10), 0x1282);
1169
1170 for (slot = 0; slot < NUM_SLOTS; slot++)
1171 for (rank = 0; rank < NUM_RANKS; rank++)
1172 if (info->populated_ranks[channel][slot][rank]) {
1173 jedec_read(info, channel, slot, rank,
1174 total_rank, 0x28,
1175 rtt_wr | (info->
1176 clock_speed_index
1177 << 3)
1178 | (auto_self_refresh << 6) |
1179 (self_refresh_temperature <<
1180 7));
1181 jedec_read(info, channel, slot, rank,
1182 total_rank, 0x38, 0);
1183 jedec_read(info, channel, slot, rank,
1184 total_rank, 0x18,
1185 rtt | MR1_ODS34OHM);
1186 jedec_read(info, channel, slot, rank,
1187 total_rank, 6,
1188 (dll_on << 12) |
1189 (write_recovery << 9)
1190 | ((info->cas_latency - 4) <<
1191 4) | MR0_BT_INTERLEAVED |
1192 MR0_DLL_RESET_ON);
1193 total_rank++;
1194 }
1195 }
1196}
1197
1198static void program_modules_memory_map(struct raminfo *info, int pre_jedec)
1199{
1200 unsigned channel, slot, rank;
1201 unsigned int total_mb[2] = { 0, 0 }; /* total memory per channel in MB */
1202 unsigned int channel_0_non_interleaved;
1203
1204 FOR_ALL_RANKS {
1205 if (info->populated_ranks[channel][slot][rank]) {
1206 total_mb[channel] +=
1207 pre_jedec ? 256 : (256 << info->
1208 density[channel][slot] >> info->
1209 is_x16_module[channel][slot]);
1210 write_mchbar8(0x208 + rank + 2 * slot + (channel << 10),
1211 (pre_jedec ? (1 | ((1 + 1) << 1))
1212 : (info->
1213 is_x16_module[channel][slot] |
1214 ((info->density[channel][slot] +
1215 1) << 1))) | 0x80);
1216 }
1217 write_mchbar16(0x200 + (channel << 10) + 4 * slot + 2 * rank,
1218 total_mb[channel] >> 6);
1219 }
1220
1221 info->total_memory_mb = total_mb[0] + total_mb[1];
1222
1223 info->interleaved_part_mb =
1224 pre_jedec ? 0 : 2 * min(total_mb[0], total_mb[1]);
1225 info->non_interleaved_part_mb =
1226 total_mb[0] + total_mb[1] - info->interleaved_part_mb;
1227 channel_0_non_interleaved = total_mb[0] - info->interleaved_part_mb / 2;
1228 write_mchbar32(0x100,
1229 channel_0_non_interleaved | (info->
1230 non_interleaved_part_mb <<
1231 16));
1232 if (!pre_jedec)
1233 write_mchbar16(0x104, info->interleaved_part_mb);
1234}
1235
1236static void program_board_delay(struct raminfo *info)
1237{
1238 int cas_latency_shift;
1239 int some_delay_ns;
1240 int some_delay_3_half_cycles;
1241
1242 unsigned channel, i;
1243 int high_multiplier;
1244 int lane_3_delay;
1245 int cas_latency_derived;
1246
1247 high_multiplier = 0;
1248 some_delay_ns = 200;
1249 some_delay_3_half_cycles = 4;
1250 cas_latency_shift = info->silicon_revision == 0
1251 || info->silicon_revision == 1 ? 1 : 0;
1252 if (info->revision < 8) {
1253 some_delay_ns = 600;
1254 cas_latency_shift = 0;
1255 }
1256 {
1257 int speed_bit;
1258 speed_bit =
1259 ((info->clock_speed_index > 1
1260 || (info->silicon_revision != 2
1261 && info->silicon_revision != 3))) ^ (info->revision >=
1262 0x10);
1263 write_500(info, 0, speed_bit | ((!info->use_ecc) << 1), 0x60e,
1264 3, 1);
1265 write_500(info, 1, speed_bit | ((!info->use_ecc) << 1), 0x60e,
1266 3, 1);
1267 if (info->revision >= 0x10 && info->clock_speed_index <= 1
1268 && (info->silicon_revision == 2
1269 || info->silicon_revision == 3))
1270 rmw_1d0(0x116, 5, 2, 4, 1);
1271 }
1272 write_mchbar32(0x120,
1273 (1 << (info->max_slots_used_in_channel + 28)) |
1274 0x188e7f9f);
1275
1276 write_mchbar8(0x124,
1277 info->board_lane_delay[4] +
1278 ((frequency_01(info) + 999) / 1000));
1279 write_mchbar16(0x125, 0x1360);
1280 write_mchbar8(0x127, 0x40);
1281 if (info->fsb_frequency < frequency_11(info) / 2) {
1282 unsigned some_delay_2_half_cycles;
1283 high_multiplier = 1;
1284 some_delay_2_half_cycles = ps_to_halfcycles(info,
1285 ((3 *
1286 fsbcycle_ps(info))
1287 >> 1) +
1288 (halfcycle_ps(info)
1289 *
1290 reg178_min[info->
1291 clock_speed_index]
1292 >> 6)
1293 +
1294 4 *
1295 halfcycle_ps(info)
1296 + 2230);
1297 some_delay_3_half_cycles =
1298 min((some_delay_2_half_cycles +
1299 (frequency_11(info) * 2) * (28 -
1300 some_delay_2_half_cycles) /
1301 (frequency_11(info) * 2 -
1302 4 * (info->fsb_frequency))) >> 3, 7);
1303 }
1304 if (read_mchbar8(0x2ca9) & 1)
1305 some_delay_3_half_cycles = 3;
1306 for (channel = 0; channel < NUM_CHANNELS; channel++) {
1307 write_mchbar32(0x220 + (channel << 10),
1308 read_mchbar32(0x220 +
1309 (channel << 10)) | 0x18001117);
1310 write_mchbar32(0x224 + (channel << 10),
1311 (info->max_slots_used_in_channel - 1)
1312 |
1313 ((info->cas_latency - 5 -
1314 info->clock_speed_index) << 21)
1315 |
1316 ((info->max_slots_used_in_channel +
1317 info->cas_latency - cas_latency_shift -
1318 4) << 16)
1319 | ((info->cas_latency - cas_latency_shift - 4) <<
1320 26)
1321 |
1322 ((info->cas_latency - info->clock_speed_index +
1323 info->max_slots_used_in_channel - 6) << 8));
1324 write_mchbar32(0x228 + (channel << 10),
1325 info->max_slots_used_in_channel);
1326 write_mchbar8(0x239 + (channel << 10), 32);
1327 write_mchbar32(0x248 + (channel << 10),
1328 (high_multiplier << 24) |
1329 (some_delay_3_half_cycles << 25) | 0x840000);
1330 write_mchbar32(0x278 + (channel << 10), 0xc362042);
1331 write_mchbar32(0x27c + (channel << 10), 0x8b000062);
1332 write_mchbar32(0x24c + (channel << 10),
1333 ((! !info->
1334 clock_speed_index) << 17) | (((2 +
1335 info->
1336 clock_speed_index
1337 -
1338 (! !info->
1339 clock_speed_index)))
1340 << 12) | 0x10200);
1341
1342 write_mchbar8(0x267 + (channel << 10), 0x4);
1343 write_mchbar16(0x272 + (channel << 10), 0x155);
1344 write_mchbar32(0x2bc + (channel << 10),
1345 (read_mchbar32(0x2bc + (channel << 10)) &
1346 0xFF000000)
1347 | 0x707070);
1348
1349 write_500(info, channel,
1350 ((!info->populated_ranks[channel][1][1])
1351 | (!info->populated_ranks[channel][1][0] << 1)
1352 | (!info->populated_ranks[channel][0][1] << 2)
1353 | (!info->populated_ranks[channel][0][0] << 3)),
1354 0x4c9, 4, 1);
1355 }
1356
1357 write_mchbar8(0x2c4, ((1 + (info->clock_speed_index != 0)) << 6) | 0xC);
1358 {
1359 u8 freq_divisor = 2;
1360 if (info->fsb_frequency == frequency_11(info))
1361 freq_divisor = 3;
1362 else if (2 * info->fsb_frequency < 3 * (frequency_11(info) / 2))
1363 freq_divisor = 1;
1364 else
1365 freq_divisor = 2;
1366 write_mchbar32(0x2c0, (freq_divisor << 11) | 0x6009c400);
1367 }
1368
1369 if (info->board_lane_delay[3] <= 10) {
1370 if (info->board_lane_delay[3] <= 8)
1371 lane_3_delay = info->board_lane_delay[3];
1372 else
1373 lane_3_delay = 10;
1374 } else {
1375 lane_3_delay = 12;
1376 }
1377 cas_latency_derived = info->cas_latency - info->clock_speed_index + 2;
1378 if (info->clock_speed_index > 1)
1379 cas_latency_derived++;
1380 for (channel = 0; channel < NUM_CHANNELS; channel++) {
1381 write_mchbar32(0x240 + (channel << 10),
1382 ((info->clock_speed_index ==
1383 0) * 0x11000) | 0x1002100 | ((2 +
1384 info->
1385 clock_speed_index)
1386 << 4) | (info->
1387 cas_latency
1388 - 3));
1389 write_500(info, channel, (info->clock_speed_index << 1) | 1,
1390 0x609, 6, 1);
1391 write_500(info, channel,
1392 info->clock_speed_index + 2 * info->cas_latency - 7,
1393 0x601, 6, 1);
1394
1395 write_mchbar32(0x250 + (channel << 10),
1396 ((lane_3_delay + info->clock_speed_index +
1397 9) << 6)
1398 | (info->board_lane_delay[7] << 2) | (info->
1399 board_lane_delay
1400 [4] << 16)
1401 | (info->board_lane_delay[1] << 25) | (info->
1402 board_lane_delay
1403 [1] << 29)
1404 | 1);
1405 write_mchbar32(0x254 + (channel << 10),
1406 (info->
1407 board_lane_delay[1] >> 3) | ((info->
1408 board_lane_delay
1409 [8] +
1410 4 *
1411 info->
1412 use_ecc) << 6) |
1413 0x80 | (info->board_lane_delay[6] << 1) | (info->
1414 board_lane_delay
1415 [2] <<
1416 28) |
1417 (cas_latency_derived << 16) | 0x4700000);
1418 write_mchbar32(0x258 + (channel << 10),
1419 ((info->board_lane_delay[5] +
1420 info->clock_speed_index +
1421 9) << 12) | ((info->clock_speed_index -
1422 info->cas_latency + 12) << 8)
1423 | (info->board_lane_delay[2] << 17) | (info->
1424 board_lane_delay
1425 [4] << 24)
1426 | 0x47);
1427 write_mchbar32(0x25c + (channel << 10),
1428 (info->board_lane_delay[1] << 1) | (info->
1429 board_lane_delay
1430 [0] << 8) |
1431 0x1da50000);
1432 write_mchbar8(0x264 + (channel << 10), 0xff);
1433 write_mchbar8(0x5f8 + (channel << 10),
1434 (cas_latency_shift << 3) | info->use_ecc);
1435 }
1436
1437 program_modules_memory_map(info, 1);
1438
1439 write_mchbar16(0x610,
1440 (min(ns_to_cycles(info, some_delay_ns) / 2, 127) << 9)
1441 | (read_mchbar16(0x610) & 0x1C3) | 0x3C);
1442 write_mchbar16(0x612, read_mchbar16(0x612) | 0x100);
1443 write_mchbar16(0x214, read_mchbar16(0x214) | 0x3E00);
1444 for (i = 0; i < 8; i++) {
1445 pcie_write_config32(PCI_DEV (QUICKPATH_BUS, 0, 1), 0x80 + 4 * i,
1446 (info->total_memory_mb - 64) | !i | 2);
1447 pcie_write_config32(PCI_DEV (QUICKPATH_BUS, 0, 1), 0xc0 + 4 * i, 0);
1448 }
1449}
1450
1451#define BETTER_MEMORY_MAP 0
1452
1453static void program_total_memory_map(struct raminfo *info)
1454{
1455 unsigned int TOM, TOLUD, TOUUD;
1456 unsigned int quickpath_reserved;
1457 unsigned int REMAPbase;
1458 unsigned int uma_base_igd;
1459 unsigned int uma_base_gtt;
1460 int memory_remap;
1461 unsigned int memory_map[8];
1462 int i;
1463 unsigned int current_limit;
1464 unsigned int tseg_base;
1465 int uma_size_igd = 0, uma_size_gtt = 0;
1466
1467 memset(memory_map, 0, sizeof(memory_map));
1468
1469#if REAL
1470 if (info->uma_enabled) {
1471 u16 t = pcie_read_config16(NORTHBRIDGE, D0F0_GGC);
1472 gav(t);
1473 const int uma_sizes_gtt[16] =
1474 { 0, 1, 0, 2, 0, 0, 0, 0, 0, 2, 3, 4, 42, 42, 42, 42 };
1475 /* Igd memory */
1476 const int uma_sizes_igd[16] = {
1477 0, 0, 0, 0, 0, 32, 48, 64, 128, 256, 96, 160, 224, 352,
1478 256, 512
1479 };
1480
1481 uma_size_igd = uma_sizes_igd[(t >> 4) & 0xF];
1482 uma_size_gtt = uma_sizes_gtt[(t >> 8) & 0xF];
1483 }
1484#endif
1485
1486 TOM = info->total_memory_mb;
1487 if (TOM == 4096)
1488 TOM = 4032;
1489 TOUUD = ALIGN_DOWN(TOM - info->memory_reserved_for_heci_mb, 64);
1490 TOLUD = ALIGN_DOWN(min(3072 + ALIGN_UP(uma_size_igd + uma_size_gtt, 64)
1491 , TOUUD), 64);
1492 memory_remap = 0;
1493 if (TOUUD - TOLUD > 64) {
1494 memory_remap = 1;
1495 REMAPbase = max(4096, TOUUD);
1496 TOUUD = TOUUD - TOLUD + 4096;
1497 }
1498 if (TOUUD > 4096)
1499 memory_map[2] = TOUUD | 1;
1500 quickpath_reserved = 0;
1501
1502 {
1503 u32 t;
1504
1505 gav(t = pcie_read_config32(PCI_DEV(QUICKPATH_BUS, 0, 1), 0x68));
1506 if (t & 0x800)
1507 quickpath_reserved =
1508 (1 << find_lowest_bit_set32(t >> 20));
1509 }
1510 if (memory_remap)
1511 TOUUD -= quickpath_reserved;
1512
1513#if !REAL
1514 if (info->uma_enabled) {
1515 u16 t = pcie_read_config16(NORTHBRIDGE, D0F0_GGC);
1516 gav(t);
1517 const int uma_sizes_gtt[16] =
1518 { 0, 1, 0, 2, 0, 0, 0, 0, 0, 2, 3, 4, 42, 42, 42, 42 };
1519 /* Igd memory */
1520 const int uma_sizes_igd[16] = {
1521 0, 0, 0, 0, 0, 32, 48, 64, 128, 256, 96, 160, 224, 352,
1522 256, 512
1523 };
1524
1525 uma_size_igd = uma_sizes_igd[(t >> 4) & 0xF];
1526 uma_size_gtt = uma_sizes_gtt[(t >> 8) & 0xF];
1527 }
1528#endif
1529
1530 uma_base_igd = TOLUD - uma_size_igd;
1531 uma_base_gtt = uma_base_igd - uma_size_gtt;
1532 tseg_base = ALIGN_DOWN(uma_base_gtt, 64) - (CONFIG_SMM_TSEG_SIZE >> 20);
1533 if (!memory_remap)
1534 tseg_base -= quickpath_reserved;
1535 tseg_base = ALIGN_DOWN(tseg_base, 8);
1536
1537 pcie_write_config16(NORTHBRIDGE, D0F0_TOLUD, TOLUD << 4);
1538 pcie_write_config16(NORTHBRIDGE, D0F0_TOM, TOM >> 6);
1539 if (memory_remap) {
1540 pcie_write_config16(NORTHBRIDGE, D0F0_REMAPBASE, REMAPbase >> 6);
1541 pcie_write_config16(NORTHBRIDGE, D0F0_REMAPLIMIT, (TOUUD - 64) >> 6);
1542 }
1543 pcie_write_config16(NORTHBRIDGE, D0F0_TOUUD, TOUUD);
1544
1545 if (info->uma_enabled) {
1546 pcie_write_config32(NORTHBRIDGE, D0F0_IGD_BASE, uma_base_igd << 20);
1547 pcie_write_config32(NORTHBRIDGE, D0F0_GTT_BASE, uma_base_gtt << 20);
1548 }
1549 pcie_write_config32(NORTHBRIDGE, TSEG, tseg_base << 20);
1550
1551 current_limit = 0;
1552 memory_map[0] = ALIGN_DOWN(uma_base_gtt, 64) | 1;
1553 memory_map[1] = 4096;
1554 for (i = 0; i < ARRAY_SIZE(memory_map); i++) {
1555 current_limit = max(current_limit, memory_map[i] & ~1);
1556 pcie_write_config32(PCI_DEV(QUICKPATH_BUS, 0, 1), 4 * i + 0x80,
1557 (memory_map[i] & 1) | ALIGN_DOWN(current_limit -
1558 1, 64) | 2);
1559 pcie_write_config32(PCI_DEV(QUICKPATH_BUS, 0, 1), 4 * i + 0xc0, 0);
1560 }
1561}
1562
1563static void collect_system_info(struct raminfo *info)
1564{
1565 u32 capid0[3];
1566 int i;
1567 unsigned channel;
1568
1569 /* Wait for some bit, maybe TXT clear. */
1570 while (!(read8(0xfed40000) & (1 << 7))) ;
1571
1572 if (!info->heci_bar)
1573 gav(info->heci_bar =
1574 pcie_read_config32(HECIDEV, HECIBAR) & 0xFFFFFFF8);
1575 if (!info->memory_reserved_for_heci_mb) {
1576 /* Wait for ME to be ready */
1577 intel_early_me_init();
1578 info->memory_reserved_for_heci_mb = intel_early_me_uma_size();
1579 }
1580
1581 for (i = 0; i < 3; i++)
1582 gav(capid0[i] =
1583 pcie_read_config32(NORTHBRIDGE, D0F0_CAPID0 | (i << 2)));
1584 gav(info->revision = pcie_read_config8(NORTHBRIDGE, PCI_REVISION_ID));
1585 info->max_supported_clock_speed_index = (~capid0[1] & 7);
1586
1587 if ((capid0[1] >> 11) & 1)
1588 info->uma_enabled = 0;
1589 else
1590 gav(info->uma_enabled =
1591 pcie_read_config8(NORTHBRIDGE, D0F0_DEVEN) & 8);
1592 /* Unrecognised: [0000:fffd3d2d] 37f81.37f82 ! CPUID: eax: 00000001; ecx: 00000e00 => 00020655.00010800.029ae3ff.bfebfbff */
1593 info->silicon_revision = 0;
1594
1595 if (capid0[2] & 2) {
1596 info->silicon_revision = 0;
1597 info->max_supported_clock_speed_index = 2;
1598 for (channel = 0; channel < NUM_CHANNELS; channel++)
1599 if (info->populated_ranks[channel][0][0]
1600 && (info->spd[channel][0][MODULE_TYPE] & 0xf) ==
1601 3) {
1602 info->silicon_revision = 2;
1603 info->max_supported_clock_speed_index = 1;
1604 }
1605 } else {
1606 switch (((capid0[2] >> 18) & 1) + 2 * ((capid0[1] >> 3) & 1)) {
1607 case 1:
1608 case 2:
1609 info->silicon_revision = 3;
1610 break;
1611 case 3:
1612 info->silicon_revision = 0;
1613 break;
1614 case 0:
1615 info->silicon_revision = 2;
1616 break;
1617 }
1618 switch (pcie_read_config16(NORTHBRIDGE, PCI_DEVICE_ID)) {
1619 case 0x40:
1620 info->silicon_revision = 0;
1621 break;
1622 case 0x48:
1623 info->silicon_revision = 1;
1624 break;
1625 }
1626 }
1627}
1628
1629static void write_training_data(struct raminfo *info)
1630{
1631 int tm, channel, slot, rank, lane;
1632 if (info->revision < 8)
1633 return;
1634
1635 for (tm = 0; tm < 4; tm++)
1636 for (channel = 0; channel < NUM_CHANNELS; channel++)
1637 for (slot = 0; slot < NUM_SLOTS; slot++)
1638 for (rank = 0; rank < NUM_RANKS; rank++)
1639 for (lane = 0; lane < 9; lane++)
1640 write_500(info, channel,
1641 info->
1642 cached_training->
1643 lane_timings[tm]
1644 [channel][slot][rank]
1645 [lane],
1646 get_timing_register_addr
1647 (lane, tm, slot,
1648 rank), 9, 0);
1649 write_1d0(info->cached_training->reg_178, 0x178, 7, 1);
1650 write_1d0(info->cached_training->reg_10b, 0x10b, 6, 1);
1651}
1652
1653static void dump_timings(struct raminfo *info)
1654{
1655#if REAL
1656 int channel, slot, rank, lane, i;
1657 printk(BIOS_DEBUG, "Timings:\n");
1658 FOR_POPULATED_RANKS {
1659 printk(BIOS_DEBUG, "channel %d, slot %d, rank %d\n", channel,
1660 slot, rank);
1661 for (lane = 0; lane < 9; lane++) {
1662 printk(BIOS_DEBUG, "lane %d: ", lane);
1663 for (i = 0; i < 4; i++) {
1664 printk(BIOS_DEBUG, "%x (%x) ",
1665 read_500(info, channel,
1666 get_timing_register_addr
1667 (lane, i, slot, rank),
1668 9),
1669 info->training.
1670 lane_timings[i][channel][slot][rank]
1671 [lane]);
1672 }
1673 printk(BIOS_DEBUG, "\n");
1674 }
1675 }
1676 printk(BIOS_DEBUG, "[178] = %x (%x)\n", read_1d0(0x178, 7),
1677 info->training.reg_178);
1678 printk(BIOS_DEBUG, "[10b] = %x (%x)\n", read_1d0(0x10b, 6),
1679 info->training.reg_10b);
1680#endif
1681}
1682
1683static void save_timings(struct raminfo *info)
1684{
1685#if CONFIG_EARLY_CBMEM_INIT
1686 struct ram_training train;
1687 struct mrc_data_container *mrcdata;
1688 int output_len = ALIGN(sizeof(train), 16);
1689 int channel, slot, rank, lane, i;
1690
1691 train = info->training;
1692 FOR_POPULATED_RANKS for (lane = 0; lane < 9; lane++)
1693 for (i = 0; i < 4; i++)
1694 train.lane_timings[i][channel][slot][rank][lane] =
1695 read_500(info, channel,
1696 get_timing_register_addr(lane, i, slot,
1697 rank), 9);
1698 train.reg_178 = read_1d0(0x178, 7);
1699 train.reg_10b = read_1d0(0x10b, 6);
1700
1701 /* Save the MRC S3 restore data to cbmem */
1702 cbmem_initialize();
1703 mrcdata = cbmem_add
1704 (CBMEM_ID_MRCDATA, output_len + sizeof(struct mrc_data_container));
1705
1706 printk(BIOS_DEBUG, "Relocate MRC DATA from %p to %p (%u bytes)\n",
1707 &train, mrcdata, output_len);
1708
1709 mrcdata->mrc_signature = MRC_DATA_SIGNATURE;
1710 mrcdata->mrc_data_size = output_len;
1711 mrcdata->reserved = 0;
1712 memcpy(mrcdata->mrc_data, &train, sizeof(train));
1713
1714 /* Zero the unused space in aligned buffer. */
1715 if (output_len > sizeof(train))
1716 memset(mrcdata->mrc_data + sizeof(train), 0,
1717 output_len - sizeof(train));
1718
1719 mrcdata->mrc_checksum = compute_ip_checksum(mrcdata->mrc_data,
1720 mrcdata->mrc_data_size);
1721#endif
1722}
1723
1724#if REAL
1725static const struct ram_training *get_cached_training(void)
1726{
1727 struct mrc_data_container *cont;
1728 cont = find_current_mrc_cache();
1729 if (!cont)
1730 return 0;
1731 return (void *)cont->mrc_data;
1732}
1733#endif
1734
1735/* FIXME: add timeout. */
1736static void wait_heci_ready(void)
1737{
1738 while (!(read32(DEFAULT_HECIBAR | 0xc) & 8)) ; // = 0x8000000c
1739 write32((DEFAULT_HECIBAR | 0x4),
1740 (read32(DEFAULT_HECIBAR | 0x4) & ~0x10) | 0xc);
1741}
1742
1743/* FIXME: add timeout. */
1744static void wait_heci_cb_avail(int len)
1745{
1746 union {
1747 struct mei_csr csr;
1748 u32 raw;
1749 } csr;
1750
1751 while (!(read32(DEFAULT_HECIBAR | 0xc) & 8)) ;
1752
1753 do
1754 csr.raw = read32(DEFAULT_HECIBAR | 0x4);
1755 while (len >
1756 csr.csr.buffer_depth - (csr.csr.buffer_write_ptr -
1757 csr.csr.buffer_read_ptr));
1758}
1759
1760static void send_heci_packet(struct mei_header *head, u32 * payload)
1761{
1762 int len = (head->length + 3) / 4;
1763 int i;
1764
1765 wait_heci_cb_avail(len + 1);
1766
1767 /* FIXME: handle leftovers correctly. */
1768 write32(DEFAULT_HECIBAR | 0, *(u32 *) head);
1769 for (i = 0; i < len - 1; i++)
1770 write32(DEFAULT_HECIBAR | 0, payload[i]);
1771
1772 write32(DEFAULT_HECIBAR | 0, payload[i] & ((1 << (8 * len)) - 1));
1773 write32(DEFAULT_HECIBAR | 0x4, read32(DEFAULT_HECIBAR | 0x4) | 0x4);
1774}
1775
1776static void
1777send_heci_message(u8 * msg, int len, u8 hostaddress, u8 clientaddress)
1778{
1779 struct mei_header head;
1780 int maxlen;
1781
1782 wait_heci_ready();
1783 maxlen = (read32(DEFAULT_HECIBAR | 0x4) >> 24) * 4 - 4;
1784
1785 while (len) {
1786 int cur = len;
1787 if (cur > maxlen) {
1788 cur = maxlen;
1789 head.is_complete = 0;
1790 } else
1791 head.is_complete = 1;
1792 head.length = cur;
1793 head.reserved = 0;
1794 head.client_address = clientaddress;
1795 head.host_address = hostaddress;
1796 send_heci_packet(&head, (u32 *) msg);
1797 len -= cur;
1798 msg += cur;
1799 }
1800}
1801
1802/* FIXME: Add timeout. */
1803static int
1804recv_heci_packet(struct raminfo *info, struct mei_header *head, u32 * packet,
1805 u32 * packet_size)
1806{
1807 union {
1808 struct mei_csr csr;
1809 u32 raw;
1810 } csr;
1811 int i = 0;
1812
1813 write32(DEFAULT_HECIBAR | 0x4, read32(DEFAULT_HECIBAR | 0x4) | 2);
1814 do {
1815 csr.raw = read32(DEFAULT_HECIBAR | 0xc);
1816#if !REAL
1817 if (i++ > 346)
1818 return -1;
1819#endif
1820 }
1821 while (csr.csr.buffer_write_ptr == csr.csr.buffer_read_ptr);
1822 *(u32 *) head = read32(DEFAULT_HECIBAR | 0x8);
1823 if (!head->length) {
1824 write32(DEFAULT_HECIBAR | 0x4,
1825 read32(DEFAULT_HECIBAR | 0x4) | 2);
1826 *packet_size = 0;
1827 return 0;
1828 }
1829 if (head->length + 4 > 4 * csr.csr.buffer_depth
1830 || head->length > *packet_size) {
1831 *packet_size = 0;
1832 return -1;
1833 }
1834
1835 do
1836 csr.raw = read32(DEFAULT_HECIBAR | 0xc);
1837 while ((head->length + 3) >> 2 >
1838 csr.csr.buffer_write_ptr - csr.csr.buffer_read_ptr);
1839
1840 for (i = 0; i < (head->length + 3) >> 2; i++)
1841 packet[i++] = read32(DEFAULT_HECIBAR | 0x8);
1842 *packet_size = head->length;
1843 if (!csr.csr.ready)
1844 *packet_size = 0;
1845 write32(DEFAULT_HECIBAR | 0x4, read32(DEFAULT_HECIBAR | 0x4) | 4);
1846 return 0;
1847}
1848
1849/* FIXME: Add timeout. */
1850static int
1851recv_heci_message(struct raminfo *info, u32 * message, u32 * message_size)
1852{
1853 struct mei_header head;
1854 int current_position;
1855
1856 current_position = 0;
1857 while (1) {
1858 u32 current_size;
1859 current_size = *message_size - current_position;
1860 if (recv_heci_packet
1861 (info, &head, message + (current_position >> 2),
1862 &current_size) == -1)
1863 break;
1864 if (!current_size)
1865 break;
1866 current_position += current_size;
1867 if (head.is_complete) {
1868 *message_size = current_position;
1869 return 0;
1870 }
1871
1872 if (current_position >= *message_size)
1873 break;
1874 }
1875 *message_size = 0;
1876 return -1;
1877}
1878
1879static void send_heci_uma_message(struct raminfo *info)
1880{
1881 struct uma_reply {
1882 u8 group_id;
1883 u8 command;
1884 u8 reserved;
1885 u8 result;
1886 u8 field2;
1887 u8 unk3[0x48 - 4 - 1];
1888 } __attribute__ ((packed)) reply;
1889 struct uma_message {
1890 u8 group_id;
1891 u8 cmd;
1892 u8 reserved;
1893 u8 result;
1894 u32 c2;
1895 u64 heci_uma_addr;
1896 u32 memory_reserved_for_heci_mb;
1897 u16 c3;
1898 } __attribute__ ((packed)) msg = {
1899 0, MKHI_SET_UMA, 0, 0,
1900 0x82,
1901 info->heci_uma_addr, info->memory_reserved_for_heci_mb, 0};
1902 u32 reply_size;
1903
1904 send_heci_message((u8 *) & msg, sizeof(msg), 0, 7);
1905
1906 reply_size = sizeof(reply);
1907 if (recv_heci_message(info, (u32 *) & reply, &reply_size) == -1)
1908 return;
1909
1910 if (reply.command != (MKHI_SET_UMA | (1 << 7)))
1911 die("HECI init failed\n");
1912}
1913
1914static void setup_heci_uma(struct raminfo *info)
1915{
1916 u32 reg44;
1917
1918 reg44 = pcie_read_config32(HECIDEV, 0x44); // = 0x80010020
1919 info->memory_reserved_for_heci_mb = 0;
1920 info->heci_uma_addr = 0;
1921 if (!((reg44 & 0x10000) && !(pcie_read_config32(HECIDEV, 0x40) & 0x20)))
1922 return;
1923
1924 info->heci_bar = pcie_read_config32(HECIDEV, 0x10) & 0xFFFFFFF0;
1925 info->memory_reserved_for_heci_mb = reg44 & 0x3f;
1926 info->heci_uma_addr =
1927 ((u64)
1928 ((((u64) pcie_read_config16(NORTHBRIDGE, D0F0_TOM)) << 6) -
1929 info->memory_reserved_for_heci_mb)) << 20;
1930
1931 pcie_read_config32(NORTHBRIDGE, DMIBAR);
1932 if (info->memory_reserved_for_heci_mb) {
1933 write32(DEFAULT_DMIBAR | 0x14,
1934 read32(DEFAULT_DMIBAR | 0x14) & ~0x80);
1935 write32(DEFAULT_RCBA | 0x14,
1936 read32(DEFAULT_RCBA | 0x14) & ~0x80);
1937 write32(DEFAULT_DMIBAR | 0x20,
1938 read32(DEFAULT_DMIBAR | 0x20) & ~0x80);
1939 write32(DEFAULT_RCBA | 0x20,
1940 read32(DEFAULT_RCBA | 0x20) & ~0x80);
1941 write32(DEFAULT_DMIBAR | 0x2c,
1942 read32(DEFAULT_DMIBAR | 0x2c) & ~0x80);
1943 write32(DEFAULT_RCBA | 0x30,
1944 read32(DEFAULT_RCBA | 0x30) & ~0x80);
1945 write32(DEFAULT_DMIBAR | 0x38,
1946 read32(DEFAULT_DMIBAR | 0x38) & ~0x80);
1947 write32(DEFAULT_RCBA | 0x40,
1948 read32(DEFAULT_RCBA | 0x40) & ~0x80);
1949
1950 write32(DEFAULT_RCBA | 0x40, 0x87000080); // OK
1951 write32(DEFAULT_DMIBAR | 0x38, 0x87000080); // OK
1952 while (read16(DEFAULT_RCBA | 0x46) & 2
1953 && read16(DEFAULT_DMIBAR | 0x3e) & 2) ;
1954 }
1955
1956 write_mchbar32(0x24, 0x10000 + info->memory_reserved_for_heci_mb);
1957
1958 send_heci_uma_message(info);
1959
1960 pcie_write_config32(HECIDEV, 0x10, 0x0);
1961 pcie_write_config8(HECIDEV, 0x4, 0x0);
1962
1963}
1964
1965static int have_match_ranks(struct raminfo *info, int channel, int ranks)
1966{
1967 int ranks_in_channel;
1968 ranks_in_channel = info->populated_ranks[channel][0][0]
1969 + info->populated_ranks[channel][0][1]
1970 + info->populated_ranks[channel][1][0]
1971 + info->populated_ranks[channel][1][1];
1972
1973 /* empty channel */
1974 if (ranks_in_channel == 0)
1975 return 1;
1976
1977 if (ranks_in_channel != ranks)
1978 return 0;
1979 /* single slot */
1980 if (info->populated_ranks[channel][0][0] !=
1981 info->populated_ranks[channel][1][0])
1982 return 1;
1983 if (info->populated_ranks[channel][0][1] !=
1984 info->populated_ranks[channel][1][1])
1985 return 1;
1986 if (info->is_x16_module[channel][0] != info->is_x16_module[channel][1])
1987 return 0;
1988 if (info->density[channel][0] != info->density[channel][1])
1989 return 0;
1990 return 1;
1991}
1992
1993#define WTF1 1
1994
1995static void read_4090(struct raminfo *info)
1996{
1997 int i, channel, slot, rank, lane;
1998 for (i = 0; i < 2; i++)
1999 for (slot = 0; slot < NUM_SLOTS; slot++)
2000 for (rank = 0; rank < NUM_RANKS; rank++)
2001 for (lane = 0; lane < 9; lane++)
2002 info->training.
2003 lane_timings[0][i][slot][rank][lane]
2004 = 32;
2005
2006 for (i = 1; i < 4; i++)
2007 for (channel = 0; channel < NUM_CHANNELS; channel++)
2008 for (slot = 0; slot < NUM_SLOTS; slot++)
2009 for (rank = 0; rank < NUM_RANKS; rank++)
2010 for (lane = 0; lane < 9; lane++) {
2011 info->training.
2012 lane_timings[i][channel]
2013 [slot][rank][lane] =
2014 read_500(info, channel,
2015 get_timing_register_addr
2016 (lane, i, slot,
2017 rank), 9)
2018 + (i == 1) * 11; // !!!!
2019 }
2020
2021}
2022
2023static u32 get_etalon2(int flip, u32 addr)
2024{
2025 const u16 invmask[] = {
2026 0xaaaa, 0x6db6, 0x4924, 0xeeee, 0xcccc, 0x8888, 0x7bde, 0x739c,
2027 0x6318, 0x4210, 0xefbe, 0xcf3c, 0x8e38, 0x0c30, 0x0820
2028 };
2029 u32 ret;
2030 u32 comp4 = addr / 480;
2031 addr %= 480;
2032 u32 comp1 = addr & 0xf;
2033 u32 comp2 = (addr >> 4) & 1;
2034 u32 comp3 = addr >> 5;
2035
2036 if (comp4)
2037 ret = 0x1010101 << (comp4 - 1);
2038 else
2039 ret = 0;
2040 if (flip ^ (((invmask[comp3] >> comp1) ^ comp2) & 1))
2041 ret = ~ret;
2042
2043 return ret;
2044}
2045
2046static void disable_cache(void)
2047{
2048 msr_t msr = {.lo = 0, .hi = 0 };
2049
2050 wrmsr(MTRRphysBase_MSR(3), msr);
2051 wrmsr(MTRRphysMask_MSR(3), msr);
2052}
2053
2054static void enable_cache(unsigned int base, unsigned int size)
2055{
2056 msr_t msr;
2057 msr.lo = base | MTRR_TYPE_WRPROT;
2058 msr.hi = 0;
2059 wrmsr(MTRRphysBase_MSR(3), msr);
2060 msr.lo = ((~(ALIGN_DOWN(size + 4096, 4096) - 1) | MTRRdefTypeEn)
2061 & 0xffffffff);
2062 msr.hi = 0x0000000f;
2063 wrmsr(MTRRphysMask_MSR(3), msr);
2064}
2065
2066static void flush_cache(u32 start, u32 size)
2067{
2068 u32 end;
2069 u32 addr;
2070
2071 end = start + (ALIGN_DOWN(size + 4096, 4096));
2072 for (addr = start; addr < end; addr += 64)
2073 clflush(addr);
2074}
2075
2076static void clear_errors(void)
2077{
2078 pcie_write_config8(NORTHBRIDGE, 0xc0, 0x01);
2079}
2080
2081static void write_testing(struct raminfo *info, int totalrank, int flip)
2082{
2083 int nwrites = 0;
2084 /* in 8-byte units. */
2085 u32 offset;
2086 u32 base;
2087
2088 base = totalrank << 28;
2089 for (offset = 0; offset < 9 * 480; offset += 2) {
2090 write32(base + offset * 8, get_etalon2(flip, offset));
2091 write32(base + offset * 8 + 4, get_etalon2(flip, offset));
2092 write32(base + offset * 8 + 8, get_etalon2(flip, offset + 1));
2093 write32(base + offset * 8 + 12, get_etalon2(flip, offset + 1));
2094 nwrites += 4;
2095 if (nwrites >= 320) {
2096 clear_errors();
2097 nwrites = 0;
2098 }
2099 }
2100}
2101
2102static u8 check_testing(struct raminfo *info, u8 total_rank, int flip)
2103{
2104 u8 failmask = 0;
2105 int i;
2106 int comp1, comp2, comp3;
2107 u32 failxor[2] = { 0, 0 };
2108
2109 enable_cache((total_rank << 28), 1728 * 5 * 4);
2110
2111 for (comp3 = 0; comp3 < 9 && failmask != 0xff; comp3++) {
2112 for (comp1 = 0; comp1 < 4; comp1++)
2113 for (comp2 = 0; comp2 < 60; comp2++) {
2114 u32 re[4];
2115 u32 curroffset =
2116 comp3 * 8 * 60 + 2 * comp1 + 8 * comp2;
2117 read128((total_rank << 28) | (curroffset << 3),
2118 (u64 *) re);
2119 failxor[0] |=
2120 get_etalon2(flip, curroffset) ^ re[0];
2121 failxor[1] |=
2122 get_etalon2(flip, curroffset) ^ re[1];
2123 failxor[0] |=
2124 get_etalon2(flip, curroffset | 1) ^ re[2];
2125 failxor[1] |=
2126 get_etalon2(flip, curroffset | 1) ^ re[3];
2127 }
2128 for (i = 0; i < 8; i++)
2129 if ((0xff << (8 * (i % 4))) & failxor[i / 4])
2130 failmask |= 1 << i;
2131 }
2132 disable_cache();
2133 flush_cache((total_rank << 28), 1728 * 5 * 4);
2134 return failmask;
2135}
2136
2137const u32 seed1[0x18] = {
2138 0x3a9d5ab5, 0x576cb65b, 0x555773b6, 0x2ab772ee,
2139 0x555556ee, 0x3a9d5ab5, 0x576cb65b, 0x555773b6,
2140 0x2ab772ee, 0x555556ee, 0x5155a555, 0x5155a555,
2141 0x5155a555, 0x5155a555, 0x3a9d5ab5, 0x576cb65b,
2142 0x555773b6, 0x2ab772ee, 0x555556ee, 0x55d6b4a5,
2143 0x366d6b3a, 0x2ae5ddbb, 0x3b9ddbb7, 0x55d6b4a5,
2144};
2145
2146static u32 get_seed2(int a, int b)
2147{
2148 const u32 seed2[5] = {
2149 0x55555555, 0x33333333, 0x2e555a55, 0x55555555,
2150 0x5b6db6db,
2151 };
2152 u32 r;
2153 r = seed2[(a + (a >= 10)) / 5];
2154 return b ? ~r : r;
2155}
2156
2157static int make_shift(int comp2, int comp5, int x)
2158{
2159 const u8 seed3[32] = {
2160 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2161 0x00, 0x00, 0x38, 0x1c, 0x3c, 0x18, 0x38, 0x38,
2162 0x38, 0x38, 0x38, 0x38, 0x0f, 0x0f, 0x0f, 0x0f,
2163 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
2164 };
2165
2166 return (comp2 - ((seed3[comp5] >> (x & 7)) & 1)) & 0x1f;
2167}
2168
2169static u32 get_etalon(int flip, u32 addr)
2170{
2171 u32 mask_byte = 0;
2172 int comp1 = (addr >> 1) & 1;
2173 int comp2 = (addr >> 3) & 0x1f;
2174 int comp3 = (addr >> 8) & 0xf;
2175 int comp4 = (addr >> 12) & 0xf;
2176 int comp5 = (addr >> 16) & 0x1f;
2177 u32 mask_bit = ~(0x10001 << comp3);
2178 u32 part1;
2179 u32 part2;
2180 int byte;
2181
2182 part2 =
2183 ((seed1[comp5] >>
2184 make_shift(comp2, comp5,
2185 (comp3 >> 3) | (comp1 << 2) | 2)) & 1) ^ flip;
2186 part1 =
2187 ((seed1[comp5] >>
2188 make_shift(comp2, comp5,
2189 (comp3 >> 3) | (comp1 << 2) | 0)) & 1) ^ flip;
2190
2191 for (byte = 0; byte < 4; byte++)
2192 if ((get_seed2(comp5, comp4) >>
2193 make_shift(comp2, comp5, (byte | (comp1 << 2)))) & 1)
2194 mask_byte |= 0xff << (8 * byte);
2195
2196 return (mask_bit & mask_byte) | (part1 << comp3) | (part2 <<
2197 (comp3 + 16));
2198}
2199
2200static void
2201write_testing_type2(struct raminfo *info, u8 totalrank, u8 region, u8 block,
2202 char flip)
2203{
2204 int i;
2205 for (i = 0; i < 2048; i++)
2206 write32((totalrank << 28) | (region << 25) | (block << 16) |
2207 (i << 2), get_etalon(flip, (block << 16) | (i << 2)));
2208}
2209
2210static u8
2211check_testing_type2(struct raminfo *info, u8 totalrank, u8 region, u8 block,
2212 char flip)
2213{
2214 u8 failmask = 0;
2215 u32 failxor[2];
2216 int i;
2217 int comp1, comp2, comp3;
2218
2219 failxor[0] = 0;
2220 failxor[1] = 0;
2221
2222 enable_cache(totalrank << 28, 134217728);
2223 for (comp3 = 0; comp3 < 2 && failmask != 0xff; comp3++) {
2224 for (comp1 = 0; comp1 < 16; comp1++)
2225 for (comp2 = 0; comp2 < 64; comp2++) {
2226 u32 addr =
2227 (totalrank << 28) | (region << 25) | (block
2228 << 16)
2229 | (comp3 << 12) | (comp2 << 6) | (comp1 <<
2230 2);
2231 failxor[comp1 & 1] |=
2232 read32(addr) ^ get_etalon(flip, addr);
2233 }
2234 for (i = 0; i < 8; i++)
2235 if ((0xff << (8 * (i % 4))) & failxor[i / 4])
2236 failmask |= 1 << i;
2237 }
2238 disable_cache();
2239 flush_cache((totalrank << 28) | (region << 25) | (block << 16), 16384);
2240 return failmask;
2241}
2242
2243static int check_bounded(unsigned short *vals, u16 bound)
2244{
2245 int i;
2246
2247 for (i = 0; i < 8; i++)
2248 if (vals[i] < bound)
2249 return 0;
2250 return 1;
2251}
2252
2253enum state {
2254 BEFORE_USABLE = 0, AT_USABLE = 1, AT_MARGIN = 2, COMPLETE = 3
2255};
2256
2257static int validate_state(enum state *in)
2258{
2259 int i;
2260 for (i = 0; i < 8; i++)
2261 if (in[i] != COMPLETE)
2262 return 0;
2263 return 1;
2264}
2265
2266static void
2267do_fsm(enum state *state, u16 * counter,
2268 u8 fail_mask, int margin, int uplimit,
2269 u8 * res_low, u8 * res_high, u8 val)
2270{
2271 int lane;
2272
2273 for (lane = 0; lane < 8; lane++) {
2274 int is_fail = (fail_mask >> lane) & 1;
2275 switch (state[lane]) {
2276 case BEFORE_USABLE:
2277 if (!is_fail) {
2278 counter[lane] = 1;
2279 state[lane] = AT_USABLE;
2280 break;
2281 }
2282 counter[lane] = 0;
2283 state[lane] = BEFORE_USABLE;
2284 break;
2285 case AT_USABLE:
2286 if (!is_fail) {
2287 ++counter[lane];
2288 if (counter[lane] >= margin) {
2289 state[lane] = AT_MARGIN;
2290 res_low[lane] = val - margin + 1;
2291 break;
2292 }
2293 state[lane] = 1;
2294 break;
2295 }
2296 counter[lane] = 0;
2297 state[lane] = BEFORE_USABLE;
2298 break;
2299 case AT_MARGIN:
2300 if (is_fail) {
2301 state[lane] = COMPLETE;
2302 res_high[lane] = val - 1;
2303 } else {
2304 counter[lane]++;
2305 state[lane] = AT_MARGIN;
2306 if (val == uplimit) {
2307 state[lane] = COMPLETE;
2308 res_high[lane] = uplimit;
2309 }
2310 }
2311 break;
2312 case COMPLETE:
2313 break;
2314 }
2315 }
2316}
2317
2318static void
2319train_ram_at_178(struct raminfo *info, u8 channel, int slot, int rank,
2320 u8 total_rank, u8 reg_178, int first_run, int niter,
2321 timing_bounds_t * timings)
2322{
2323 int lane;
2324 enum state state[8];
2325 u16 count[8];
2326 u8 lower_usable[8];
2327 u8 upper_usable[8];
2328 unsigned short num_sucessfully_checked[8];
2329 u8 secondary_total_rank;
2330 u8 reg1b3;
2331
2332 if (info->populated_ranks_mask[1]) {
2333 if (channel == 1)
2334 secondary_total_rank =
2335 info->populated_ranks[1][0][0] +
2336 info->populated_ranks[1][0][1]
2337 + info->populated_ranks[1][1][0] +
2338 info->populated_ranks[1][1][1];
2339 else
2340 secondary_total_rank = 0;
2341 } else
2342 secondary_total_rank = total_rank;
2343
2344 {
2345 int i;
2346 for (i = 0; i < 8; i++)
2347 state[i] = BEFORE_USABLE;
2348 }
2349
2350 if (!first_run) {
2351 int is_all_ok = 1;
2352 for (lane = 0; lane < 8; lane++)
2353 if (timings[reg_178][channel][slot][rank][lane].
2354 smallest ==
2355 timings[reg_178][channel][slot][rank][lane].
2356 largest) {
2357 timings[reg_178][channel][slot][rank][lane].
2358 smallest = 0;
2359 timings[reg_178][channel][slot][rank][lane].
2360 largest = 0;
2361 is_all_ok = 0;
2362 }
2363 if (is_all_ok) {
2364 int i;
2365 for (i = 0; i < 8; i++)
2366 state[i] = COMPLETE;
2367 }
2368 }
2369
2370 for (reg1b3 = 0; reg1b3 < 0x30 && !validate_state(state); reg1b3++) {
2371 u8 failmask = 0;
2372 write_1d0(reg1b3 ^ 32, 0x1b3, 6, 1);
2373 write_1d0(reg1b3 ^ 32, 0x1a3, 6, 1);
2374 failmask = check_testing(info, total_rank, 0);
2375 write_mchbar32(0xfb0, read_mchbar32(0xfb0) | 0x00030000);
2376 do_fsm(state, count, failmask, 5, 47, lower_usable,
2377 upper_usable, reg1b3);
2378 }
2379
2380 if (reg1b3) {
2381 write_1d0(0, 0x1b3, 6, 1);
2382 write_1d0(0, 0x1a3, 6, 1);
2383 for (lane = 0; lane < 8; lane++) {
2384 if (state[lane] == COMPLETE) {
2385 timings[reg_178][channel][slot][rank][lane].
2386 smallest =
2387 lower_usable[lane] +
2388 (info->training.
2389 lane_timings[0][channel][slot][rank][lane]
2390 & 0x3F) - 32;
2391 timings[reg_178][channel][slot][rank][lane].
2392 largest =
2393 upper_usable[lane] +
2394 (info->training.
2395 lane_timings[0][channel][slot][rank][lane]
2396 & 0x3F) - 32;
2397 }
2398 }
2399 }
2400
2401 if (!first_run) {
2402 for (lane = 0; lane < 8; lane++)
2403 if (state[lane] == COMPLETE) {
2404 write_500(info, channel,
2405 timings[reg_178][channel][slot][rank]
2406 [lane].smallest,
2407 get_timing_register_addr(lane, 0,
2408 slot, rank),
2409 9, 1);
2410 write_500(info, channel,
2411 timings[reg_178][channel][slot][rank]
2412 [lane].smallest +
2413 info->training.
2414 lane_timings[1][channel][slot][rank]
2415 [lane]
2416 -
2417 info->training.
2418 lane_timings[0][channel][slot][rank]
2419 [lane], get_timing_register_addr(lane,
2420 1,
2421 slot,
2422 rank),
2423 9, 1);
2424 num_sucessfully_checked[lane] = 0;
2425 } else
2426 num_sucessfully_checked[lane] = -1;
2427
2428 do {
2429 u8 failmask = 0;
2430 int i;
2431 for (i = 0; i < niter; i++) {
2432 if (failmask == 0xFF)
2433 break;
2434 failmask |=
2435 check_testing_type2(info, total_rank, 2, i,
2436 0);
2437 failmask |=
2438 check_testing_type2(info, total_rank, 3, i,
2439 1);
2440 }
2441 write_mchbar32(0xfb0,
2442 read_mchbar32(0xfb0) | 0x00030000);
2443 for (lane = 0; lane < 8; lane++)
2444 if (num_sucessfully_checked[lane] != 0xffff) {
2445 if ((1 << lane) & failmask) {
2446 if (timings[reg_178][channel]
2447 [slot][rank][lane].
2448 largest <=
2449 timings[reg_178][channel]
2450 [slot][rank][lane].smallest)
2451 num_sucessfully_checked
2452 [lane] = -1;
2453 else {
2454 num_sucessfully_checked
2455 [lane] = 0;
2456 timings[reg_178]
2457 [channel][slot]
2458 [rank][lane].
2459 smallest++;
2460 write_500(info, channel,
2461 timings
2462 [reg_178]
2463 [channel]
2464 [slot][rank]
2465 [lane].
2466 smallest,
2467 get_timing_register_addr
2468 (lane, 0,
2469 slot, rank),
2470 9, 1);
2471 write_500(info, channel,
2472 timings
2473 [reg_178]
2474 [channel]
2475 [slot][rank]
2476 [lane].
2477 smallest +
2478 info->
2479 training.
2480 lane_timings
2481 [1][channel]
2482 [slot][rank]
2483 [lane]
2484 -
2485 info->
2486 training.
2487 lane_timings
2488 [0][channel]
2489 [slot][rank]
2490 [lane],
2491 get_timing_register_addr
2492 (lane, 1,
2493 slot, rank),
2494 9, 1);
2495 }
2496 } else
2497 num_sucessfully_checked[lane]++;
2498 }
2499 }
2500 while (!check_bounded(num_sucessfully_checked, 2));
2501
2502 for (lane = 0; lane < 8; lane++)
2503 if (state[lane] == COMPLETE) {
2504 write_500(info, channel,
2505 timings[reg_178][channel][slot][rank]
2506 [lane].largest,
2507 get_timing_register_addr(lane, 0,
2508 slot, rank),
2509 9, 1);
2510 write_500(info, channel,
2511 timings[reg_178][channel][slot][rank]
2512 [lane].largest +
2513 info->training.
2514 lane_timings[1][channel][slot][rank]
2515 [lane]
2516 -
2517 info->training.
2518 lane_timings[0][channel][slot][rank]
2519 [lane], get_timing_register_addr(lane,
2520 1,
2521 slot,
2522 rank),
2523 9, 1);
2524 num_sucessfully_checked[lane] = 0;
2525 } else
2526 num_sucessfully_checked[lane] = -1;
2527
2528 do {
2529 int failmask = 0;
2530 int i;
2531 for (i = 0; i < niter; i++) {
2532 if (failmask == 0xFF)
2533 break;
2534 failmask |=
2535 check_testing_type2(info, total_rank, 2, i,
2536 0);
2537 failmask |=
2538 check_testing_type2(info, total_rank, 3, i,
2539 1);
2540 }
2541
2542 write_mchbar32(0xfb0,
2543 read_mchbar32(0xfb0) | 0x00030000);
2544 for (lane = 0; lane < 8; lane++) {
2545 if (num_sucessfully_checked[lane] != 0xffff) {
2546 if ((1 << lane) & failmask) {
2547 if (timings[reg_178][channel]
2548 [slot][rank][lane].
2549 largest <=
2550 timings[reg_178][channel]
2551 [slot][rank][lane].
2552 smallest) {
2553 num_sucessfully_checked
2554 [lane] = -1;
2555 } else {
2556 num_sucessfully_checked
2557 [lane] = 0;
2558 timings[reg_178]
2559 [channel][slot]
2560 [rank][lane].
2561 largest--;
2562 write_500(info, channel,
2563 timings
2564 [reg_178]
2565 [channel]
2566 [slot][rank]
2567 [lane].
2568 largest,
2569 get_timing_register_addr
2570 (lane, 0,
2571 slot, rank),
2572 9, 1);
2573 write_500(info, channel,
2574 timings
2575 [reg_178]
2576 [channel]
2577 [slot][rank]
2578 [lane].
2579 largest +
2580 info->
2581 training.
2582 lane_timings
2583 [1][channel]
2584 [slot][rank]
2585 [lane]
2586 -
2587 info->
2588 training.
2589 lane_timings
2590 [0][channel]
2591 [slot][rank]
2592 [lane],
2593 get_timing_register_addr
2594 (lane, 1,
2595 slot, rank),
2596 9, 1);
2597 }
2598 } else
2599 num_sucessfully_checked[lane]++;
2600 }
2601 }
2602 }
2603 while (!check_bounded(num_sucessfully_checked, 3));
2604
2605 for (lane = 0; lane < 8; lane++) {
2606 write_500(info, channel,
2607 info->training.
2608 lane_timings[0][channel][slot][rank][lane],
2609 get_timing_register_addr(lane, 0, slot, rank),
2610 9, 1);
2611 write_500(info, channel,
2612 info->training.
2613 lane_timings[1][channel][slot][rank][lane],
2614 get_timing_register_addr(lane, 1, slot, rank),
2615 9, 1);
2616 if (timings[reg_178][channel][slot][rank][lane].
2617 largest <=
2618 timings[reg_178][channel][slot][rank][lane].
2619 smallest) {
2620 timings[reg_178][channel][slot][rank][lane].
2621 largest = 0;
2622 timings[reg_178][channel][slot][rank][lane].
2623 smallest = 0;
2624 }
2625 }
2626 }
2627}
2628
2629static void set_10b(struct raminfo *info, u8 val)
2630{
2631 int channel;
2632 int slot, rank;
2633 int lane;
2634
2635 if (read_1d0(0x10b, 6) == val)
2636 return;
2637
2638 write_1d0(val, 0x10b, 6, 1);
2639
2640 FOR_POPULATED_RANKS_BACKWARDS for (lane = 0; lane < 9; lane++) {
2641 u16 reg_500;
2642 reg_500 = read_500(info, channel,
2643 get_timing_register_addr(lane, 0, slot,
2644 rank), 9);
2645 if (val == 1) {
2646 if (lut16[info->clock_speed_index] <= reg_500)
2647 reg_500 -= lut16[info->clock_speed_index];
2648 else
2649 reg_500 = 0;
2650 } else {
2651 reg_500 += lut16[info->clock_speed_index];
2652 }
2653 write_500(info, channel, reg_500,
2654 get_timing_register_addr(lane, 0, slot, rank), 9, 1);
2655 }
2656}
2657
2658static void set_ecc(int onoff)
2659{
2660 int channel;
2661 for (channel = 0; channel < NUM_CHANNELS; channel++) {
2662 u8 t;
2663 t = read_mchbar8((channel << 10) + 0x5f8);
2664 if (onoff)
2665 t |= 1;
2666 else
2667 t &= ~1;
2668 write_mchbar8((channel << 10) + 0x5f8, t);
2669 }
2670}
2671
2672static void set_178(u8 val)
2673{
2674 if (val >= 31)
2675 val = val - 31;
2676 else
2677 val = 63 - val;
2678
2679 write_1d0(2 * val, 0x178, 7, 1);
2680}
2681
2682static void
2683write_500_timings_type(struct raminfo *info, int channel, int slot, int rank,
2684 int type)
2685{
2686 int lane;
2687
2688 for (lane = 0; lane < 8; lane++)
2689 write_500(info, channel,
2690 info->training.
2691 lane_timings[type][channel][slot][rank][lane],
2692 get_timing_register_addr(lane, type, slot, rank), 9,
2693 0);
2694}
2695
2696static void
2697try_timing_offsets(struct raminfo *info, int channel,
2698 int slot, int rank, int totalrank)
2699{
2700 u16 count[8];
2701 enum state state[8];
2702 u8 lower_usable[8], upper_usable[8];
2703 int lane;
2704 int i;
2705 int flip = 1;
2706 int timing_offset;
2707
2708 for (i = 0; i < 8; i++)
2709 state[i] = BEFORE_USABLE;
2710
2711 memset(count, 0, sizeof(count));
2712
2713 for (lane = 0; lane < 8; lane++)
2714 write_500(info, channel,
2715 info->training.
2716 lane_timings[2][channel][slot][rank][lane] + 32,
2717 get_timing_register_addr(lane, 3, slot, rank), 9, 1);
2718
2719 for (timing_offset = 0; !validate_state(state) && timing_offset < 64;
2720 timing_offset++) {
2721 u8 failmask;
2722 write_1d0(timing_offset ^ 32, 0x1bb, 6, 1);
2723 failmask = 0;
2724 for (i = 0; i < 2 && failmask != 0xff; i++) {
2725 flip = !flip;
2726 write_testing(info, totalrank, flip);
2727 failmask |= check_testing(info, totalrank, flip);
2728 }
2729 do_fsm(state, count, failmask, 10, 63, lower_usable,
2730 upper_usable, timing_offset);
2731 }
2732 write_1d0(0, 0x1bb, 6, 1);
2733 dump_timings(info);
2734 if (!validate_state(state))
2735 die("Couldn't discover DRAM timings (1)\n");
2736
2737 for (lane = 0; lane < 8; lane++) {
2738 u8 bias = 0;
2739
2740 if (info->silicon_revision) {
2741 int usable_length;
2742
2743 usable_length = upper_usable[lane] - lower_usable[lane];
2744 if (usable_length >= 20) {
2745 bias = usable_length / 2 - 10;
2746 if (bias >= 2)
2747 bias = 2;
2748 }
2749 }
2750 write_500(info, channel,
2751 info->training.
2752 lane_timings[2][channel][slot][rank][lane] +
2753 (upper_usable[lane] + lower_usable[lane]) / 2 - bias,
2754 get_timing_register_addr(lane, 3, slot, rank), 9, 1);
2755 info->training.timing2_bounds[channel][slot][rank][lane][0] =
2756 info->training.lane_timings[2][channel][slot][rank][lane] +
2757 lower_usable[lane];
2758 info->training.timing2_bounds[channel][slot][rank][lane][1] =
2759 info->training.lane_timings[2][channel][slot][rank][lane] +
2760 upper_usable[lane];
2761 info->training.timing2_offset[channel][slot][rank][lane] =
2762 info->training.lane_timings[2][channel][slot][rank][lane];
2763 }
2764}
2765
2766static u8
2767choose_training(struct raminfo *info, int channel, int slot, int rank,
2768 int lane, timing_bounds_t * timings, u8 center_178)
2769{
2770 u16 central_weight;
2771 u16 side_weight;
2772 unsigned int sum = 0, count = 0;
2773 u8 span;
2774 u8 lower_margin, upper_margin;
2775 u8 reg_178;
2776 u8 result;
2777
2778 span = 12;
2779 central_weight = 20;
2780 side_weight = 20;
2781 if (info->silicon_revision == 1 && channel == 1) {
2782 central_weight = 5;
2783 side_weight = 20;
2784 if ((info->
2785 populated_ranks_mask[1] ^ (info->
2786 populated_ranks_mask[1] >> 2)) &
2787 1)
2788 span = 18;
2789 }
2790 if ((info->populated_ranks_mask[0] & 5) == 5) {
2791 central_weight = 20;
2792 side_weight = 20;
2793 }
2794 if (info->clock_speed_index >= 2
2795 && (info->populated_ranks_mask[0] & 5) == 5 && slot == 1) {
2796 if (info->silicon_revision == 1) {
2797 switch (channel) {
2798 case 0:
2799 if (lane == 1) {
2800 central_weight = 10;
2801 side_weight = 20;
2802 }
2803 break;
2804 case 1:
2805 if (lane == 6) {
2806 side_weight = 5;
2807 central_weight = 20;
2808 }
2809 break;
2810 }
2811 }
2812 if (info->silicon_revision == 0 && channel == 0 && lane == 0) {
2813 side_weight = 5;
2814 central_weight = 20;
2815 }
2816 }
2817 for (reg_178 = center_178 - span; reg_178 <= center_178 + span;
2818 reg_178 += span) {
2819 u8 smallest;
2820 u8 largest;
2821 largest = timings[reg_178][channel][slot][rank][lane].largest;
2822 smallest = timings[reg_178][channel][slot][rank][lane].smallest;
2823 if (largest - smallest + 1 >= 5) {
2824 unsigned int weight;
2825 if (reg_178 == center_178)
2826 weight = central_weight;
2827 else
2828 weight = side_weight;
2829 sum += weight * (largest + smallest);
2830 count += weight;
2831 }
2832 }
2833 dump_timings(info);
2834 if (count == 0)
2835 die("Couldn't discover DRAM timings (2)\n");
2836 result = sum / (2 * count);
2837 lower_margin =
2838 result - timings[center_178][channel][slot][rank][lane].smallest;
2839 upper_margin =
2840 timings[center_178][channel][slot][rank][lane].largest - result;
2841 if (upper_margin < 10 && lower_margin > 10)
2842 result -= min(lower_margin - 10, 10 - upper_margin);
2843 if (upper_margin > 10 && lower_margin < 10)
2844 result += min(upper_margin - 10, 10 - lower_margin);
2845 return result;
2846}
2847
2848#define STANDARD_MIN_MARGIN 5
2849
2850static u8 choose_reg178(struct raminfo *info, timing_bounds_t * timings)
2851{
2852 u16 margin[64];
2853 int lane, rank, slot, channel;
2854 u8 reg178;
2855 int count = 0, sum = 0;
2856
2857 for (reg178 = reg178_min[info->clock_speed_index];
2858 reg178 < reg178_max[info->clock_speed_index];
2859 reg178 += reg178_step[info->clock_speed_index]) {
2860 margin[reg178] = -1;
2861 FOR_POPULATED_RANKS_BACKWARDS for (lane = 0; lane < 8; lane++) {
2862 int curmargin =
2863 timings[reg178][channel][slot][rank][lane].largest -
2864 timings[reg178][channel][slot][rank][lane].
2865 smallest + 1;
2866 if (curmargin < margin[reg178])
2867 margin[reg178] = curmargin;
2868 }
2869 if (margin[reg178] >= STANDARD_MIN_MARGIN) {
2870 u16 weight;
2871 weight = margin[reg178] - STANDARD_MIN_MARGIN;
2872 sum += weight * reg178;
2873 count += weight;
2874 }
2875 }
2876 dump_timings(info);
2877 if (count == 0)
2878 die("Couldn't discover DRAM timings (3)\n");
2879
2880 u8 threshold;
2881
2882 for (threshold = 30; threshold >= 5; threshold--) {
2883 int usable_length = 0;
2884 int smallest_fount = 0;
2885 for (reg178 = reg178_min[info->clock_speed_index];
2886 reg178 < reg178_max[info->clock_speed_index];
2887 reg178 += reg178_step[info->clock_speed_index])
2888 if (margin[reg178] >= threshold) {
2889 usable_length +=
2890 reg178_step[info->clock_speed_index];
2891 info->training.reg178_largest =
2892 reg178 -
2893 2 * reg178_step[info->clock_speed_index];
2894
2895 if (!smallest_fount) {
2896 smallest_fount = 1;
2897 info->training.reg178_smallest =
2898 reg178 +
2899 reg178_step[info->
2900 clock_speed_index];
2901 }
2902 }
2903 if (usable_length >= 0x21)
2904 break;
2905 }
2906
2907 return sum / count;
2908}
2909
2910static int check_cached_sanity(struct raminfo *info)
2911{
2912 int lane;
2913 int slot, rank;
2914 int channel;
2915
2916 if (!info->cached_training)
2917 return 0;
2918
2919 for (channel = 0; channel < NUM_CHANNELS; channel++)
2920 for (slot = 0; slot < NUM_SLOTS; slot++)
2921 for (rank = 0; rank < NUM_RANKS; rank++)
2922 for (lane = 0; lane < 8 + info->use_ecc; lane++) {
2923 u16 cached_value, estimation_value;
2924 cached_value =
2925 info->cached_training->
2926 lane_timings[1][channel][slot][rank]
2927 [lane];
2928 if (cached_value >= 0x18
2929 && cached_value <= 0x1E7) {
2930 estimation_value =
2931 info->training.
2932 lane_timings[1][channel]
2933 [slot][rank][lane];
2934 if (estimation_value <
2935 cached_value - 24)
2936 return 0;
2937 if (estimation_value >
2938 cached_value + 24)
2939 return 0;
2940 }
2941 }
2942 return 1;
2943}
2944
2945static int try_cached_training(struct raminfo *info)
2946{
2947 u8 saved_243[2];
2948 u8 tm;
2949
2950 int channel, slot, rank, lane;
2951 int flip = 1;
2952 int i, j;
2953
2954 if (!check_cached_sanity(info))
2955 return 0;
2956
2957 info->training.reg178_center = info->cached_training->reg178_center;
2958 info->training.reg178_smallest = info->cached_training->reg178_smallest;
2959 info->training.reg178_largest = info->cached_training->reg178_largest;
2960 memcpy(&info->training.timing_bounds,
2961 &info->cached_training->timing_bounds,
2962 sizeof(info->training.timing_bounds));
2963 memcpy(&info->training.timing_offset,
2964 &info->cached_training->timing_offset,
2965 sizeof(info->training.timing_offset));
2966
2967 write_1d0(2, 0x142, 3, 1);
2968 saved_243[0] = read_mchbar8(0x243);
2969 saved_243[1] = read_mchbar8(0x643);
2970 write_mchbar8(0x243, saved_243[0] | 2);
2971 write_mchbar8(0x643, saved_243[1] | 2);
2972 set_ecc(0);
2973 pcie_write_config16(NORTHBRIDGE, 0xc8, 3);
2974 if (read_1d0(0x10b, 6) & 1)
2975 set_10b(info, 0);
2976 for (tm = 0; tm < 2; tm++) {
2977 int totalrank;
2978
2979 set_178(tm ? info->cached_training->reg178_largest : info->
2980 cached_training->reg178_smallest);
2981
2982 totalrank = 0;
2983 /* Check timing ranges. With i == 0 we check smallest one and with
2984 i == 1 the largest bound. With j == 0 we check that on the bound
2985 it still works whereas with j == 1 we check that just outside of
2986 bound we fail.
2987 */
2988 FOR_POPULATED_RANKS_BACKWARDS {
2989 for (i = 0; i < 2; i++) {
2990 for (lane = 0; lane < 8; lane++) {
2991 write_500(info, channel,
2992 info->cached_training->
2993 timing2_bounds[channel][slot]
2994 [rank][lane][i],
2995 get_timing_register_addr(lane,
2996 3,
2997 slot,
2998 rank),
2999 9, 1);
3000
3001 if (!i)
3002 write_500(info, channel,
3003 info->
3004 cached_training->
3005 timing2_offset
3006 [channel][slot][rank]
3007 [lane],
3008 get_timing_register_addr
3009 (lane, 2, slot, rank),
3010 9, 1);
3011 write_500(info, channel,
3012 i ? info->cached_training->
3013 timing_bounds[tm][channel]
3014 [slot][rank][lane].
3015 largest : info->
3016 cached_training->
3017 timing_bounds[tm][channel]
3018 [slot][rank][lane].smallest,
3019 get_timing_register_addr(lane,
3020 0,
3021 slot,
3022 rank),
3023 9, 1);
3024 write_500(info, channel,
3025 info->cached_training->
3026 timing_offset[channel][slot]
3027 [rank][lane] +
3028 (i ? info->cached_training->
3029 timing_bounds[tm][channel]
3030 [slot][rank][lane].
3031 largest : info->
3032 cached_training->
3033 timing_bounds[tm][channel]
3034 [slot][rank][lane].
3035 smallest) - 64,
3036 get_timing_register_addr(lane,
3037 1,
3038 slot,
3039 rank),
3040 9, 1);
3041 }
3042 for (j = 0; j < 2; j++) {
3043 u8 failmask;
3044 u8 expected_failmask;
3045 char reg1b3;
3046
3047 reg1b3 = (j == 1) + 4;
3048 reg1b3 =
3049 j == i ? reg1b3 : (-reg1b3) & 0x3f;
3050 write_1d0(reg1b3, 0x1bb, 6, 1);
3051 write_1d0(reg1b3, 0x1b3, 6, 1);
3052 write_1d0(reg1b3, 0x1a3, 6, 1);
3053
3054 flip = !flip;
3055 write_testing(info, totalrank, flip);
3056 failmask =
3057 check_testing(info, totalrank,
3058 flip);
3059 expected_failmask =
3060 j == 0 ? 0x00 : 0xff;
3061 if (failmask != expected_failmask)
3062 goto fail;
3063 }
3064 }
3065 totalrank++;
3066 }
3067 }
3068
3069 set_178(info->cached_training->reg178_center);
3070 if (info->use_ecc)
3071 set_ecc(1);
3072 write_training_data(info);
3073 write_1d0(0, 322, 3, 1);
3074 info->training = *info->cached_training;
3075
3076 write_1d0(0, 0x1bb, 6, 1);
3077 write_1d0(0, 0x1b3, 6, 1);
3078 write_1d0(0, 0x1a3, 6, 1);
3079 write_mchbar8(0x243, saved_243[0]);
3080 write_mchbar8(0x643, saved_243[1]);
3081
3082 return 1;
3083
3084fail:
3085 FOR_POPULATED_RANKS {
3086 write_500_timings_type(info, channel, slot, rank, 1);
3087 write_500_timings_type(info, channel, slot, rank, 2);
3088 write_500_timings_type(info, channel, slot, rank, 3);
3089 }
3090
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]);
3096
3097 return 0;
3098}
3099
3100static void do_ram_training(struct raminfo *info)
3101{
3102 u8 saved_243[2];
3103 int totalrank = 0;
3104 u8 reg_178;
3105 int niter;
3106
3107 timing_bounds_t timings[64];
3108 int lane, rank, slot, channel;
3109 u8 reg178_center;
3110
3111 write_1d0(2, 0x142, 3, 1);
3112 saved_243[0] = read_mchbar8(0x243);
3113 saved_243[1] = read_mchbar8(0x643);
3114 write_mchbar8(0x243, saved_243[0] | 2);
3115 write_mchbar8(0x643, saved_243[1] | 2);
3116 switch (info->clock_speed_index) {
3117 case 0:
3118 niter = 5;
3119 break;
3120 case 1:
3121 niter = 10;
3122 break;
3123 default:
3124 niter = 19;
3125 break;
3126 }
3127 set_ecc(0);
3128
3129 FOR_POPULATED_RANKS_BACKWARDS {
3130 int i;
3131
3132 write_500_timings_type(info, channel, slot, rank, 0);
3133
3134 write_testing(info, totalrank, 0);
3135 for (i = 0; i < niter; i++) {
3136 write_testing_type2(info, totalrank, 2, i, 0);
3137 write_testing_type2(info, totalrank, 3, i, 1);
3138 }
3139 pcie_write_config8(NORTHBRIDGE, 0xc0, 0x01);
3140 totalrank++;
3141 }
3142
3143 if (reg178_min[info->clock_speed_index] <
3144 reg178_max[info->clock_speed_index])
3145 memset(timings[reg178_min[info->clock_speed_index]], 0,
3146 sizeof(timings[0]) *
3147 (reg178_max[info->clock_speed_index] -
3148 reg178_min[info->clock_speed_index]));
3149 for (reg_178 = reg178_min[info->clock_speed_index];
3150 reg_178 < reg178_max[info->clock_speed_index];
3151 reg_178 += reg178_step[info->clock_speed_index]) {
3152 totalrank = 0;
3153 set_178(reg_178);
3154 for (channel = NUM_CHANNELS - 1; channel >= 0; channel--)
3155 for (slot = 0; slot < NUM_SLOTS; slot++)
3156 for (rank = 0; rank < NUM_RANKS; rank++) {
3157 memset(&timings[reg_178][channel][slot]
3158 [rank][0].smallest, 0, 16);
3159 if (info->
3160 populated_ranks[channel][slot]
3161 [rank]) {
3162 train_ram_at_178(info, channel,
3163 slot, rank,
3164 totalrank,
3165 reg_178, 1,
3166 niter,
3167 timings);
3168 totalrank++;
3169 }
3170 }
3171 }
3172
3173 reg178_center = choose_reg178(info, timings);
3174
3175 FOR_POPULATED_RANKS_BACKWARDS for (lane = 0; lane < 8; lane++) {
3176 info->training.timing_bounds[0][channel][slot][rank][lane].
3177 smallest =
3178 timings[info->training.
3179 reg178_smallest][channel][slot][rank][lane].
3180 smallest;
3181 info->training.timing_bounds[0][channel][slot][rank][lane].
3182 largest =
3183 timings[info->training.
3184 reg178_smallest][channel][slot][rank][lane].largest;
3185 info->training.timing_bounds[1][channel][slot][rank][lane].
3186 smallest =
3187 timings[info->training.
3188 reg178_largest][channel][slot][rank][lane].smallest;
3189 info->training.timing_bounds[1][channel][slot][rank][lane].
3190 largest =
3191 timings[info->training.
3192 reg178_largest][channel][slot][rank][lane].largest;
3193 info->training.timing_offset[channel][slot][rank][lane] =
3194 info->training.lane_timings[1][channel][slot][rank][lane]
3195 -
3196 info->training.lane_timings[0][channel][slot][rank][lane] +
3197 64;
3198 }
3199
3200 if (info->silicon_revision == 1
3201 && (info->
3202 populated_ranks_mask[1] ^ (info->
3203 populated_ranks_mask[1] >> 2)) & 1) {
3204 int ranks_after_channel1;
3205
3206 totalrank = 0;
3207 for (reg_178 = reg178_center - 18;
3208 reg_178 <= reg178_center + 18; reg_178 += 18) {
3209 totalrank = 0;
3210 set_178(reg_178);
3211 for (slot = 0; slot < NUM_SLOTS; slot++)
3212 for (rank = 0; rank < NUM_RANKS; rank++) {
3213 if (info->
3214 populated_ranks[1][slot][rank]) {
3215 train_ram_at_178(info, 1, slot,
3216 rank,
3217 totalrank,
3218 reg_178, 0,
3219 niter,
3220 timings);
3221 totalrank++;
3222 }
3223 }
3224 }
3225 ranks_after_channel1 = totalrank;
3226
3227 for (reg_178 = reg178_center - 12;
3228 reg_178 <= reg178_center + 12; reg_178 += 12) {
3229 totalrank = ranks_after_channel1;
3230 set_178(reg_178);
3231 for (slot = 0; slot < NUM_SLOTS; slot++)
3232 for (rank = 0; rank < NUM_RANKS; rank++)
3233 if (info->
3234 populated_ranks[0][slot][rank]) {
3235 train_ram_at_178(info, 0, slot,
3236 rank,
3237 totalrank,
3238 reg_178, 0,
3239 niter,
3240 timings);
3241 totalrank++;
3242 }
3243
3244 }
3245 } else {
3246 for (reg_178 = reg178_center - 12;
3247 reg_178 <= reg178_center + 12; reg_178 += 12) {
3248 totalrank = 0;
3249 set_178(reg_178);
3250 FOR_POPULATED_RANKS_BACKWARDS {
3251 train_ram_at_178(info, channel, slot, rank,
3252 totalrank, reg_178, 0, niter,
3253 timings);
3254 totalrank++;
3255 }
3256 }
3257 }
3258
3259 set_178(reg178_center);
3260 FOR_POPULATED_RANKS_BACKWARDS for (lane = 0; lane < 8; lane++) {
3261 u16 tm0;
3262
3263 tm0 =
3264 choose_training(info, channel, slot, rank, lane, timings,
3265 reg178_center);
3266 write_500(info, channel, tm0,
3267 get_timing_register_addr(lane, 0, slot, rank), 9, 1);
3268 write_500(info, channel,
3269 tm0 +
3270 info->training.
3271 lane_timings[1][channel][slot][rank][lane] -
3272 info->training.
3273 lane_timings[0][channel][slot][rank][lane],
3274 get_timing_register_addr(lane, 1, slot, rank), 9, 1);
3275 }
3276
3277 totalrank = 0;
3278 FOR_POPULATED_RANKS_BACKWARDS {
3279 try_timing_offsets(info, channel, slot, rank, totalrank);
3280 totalrank++;
3281 }
3282 write_mchbar8(0x243, saved_243[0]);
3283 write_mchbar8(0x643, saved_243[1]);
3284 write_1d0(0, 0x142, 3, 1);
3285 info->training.reg178_center = reg178_center;
3286}
3287
3288static void ram_training(struct raminfo *info)
3289{
3290 u16 saved_fc4;
3291
3292 saved_fc4 = read_mchbar16(0xfc4);
3293 write_mchbar16(0xfc4, 0xffff);
3294
3295 if (info->revision >= 8)
3296 read_4090(info);
3297
3298 if (!try_cached_training(info))
3299 do_ram_training(info);
3300 if ((info->silicon_revision == 2 || info->silicon_revision == 3)
3301 && info->clock_speed_index < 2)
3302 set_10b(info, 1);
3303 write_mchbar16(0xfc4, saved_fc4);
3304}
3305
3306static unsigned gcd(unsigned a, unsigned b)
3307{
3308 unsigned t;
3309 if (a > b) {
3310 t = a;
3311 a = b;
3312 b = t;
3313 }
3314 /* invariant a < b. */
3315 while (a) {
3316 t = b % a;
3317 b = a;
3318 a = t;
3319 }
3320 return b;
3321}
3322
3323static inline int div_roundup(int a, int b)
3324{
3325 return (a + b - 1) / b;
3326}
3327
3328static unsigned lcm(unsigned a, unsigned b)
3329{
3330 return (a * b) / gcd(a, b);
3331}
3332
3333struct stru1 {
3334 u8 freqs_reversed;
3335 u8 freq_diff_reduced;
3336 u8 freq_min_reduced;
3337 u8 divisor_f4_to_fmax;
3338 u8 divisor_f3_to_fmax;
3339 u8 freq4_to_max_remainder;
3340 u8 freq3_to_2_remainder;
3341 u8 freq3_to_2_remaindera;
3342 u8 freq4_to_2_remainder;
3343 int divisor_f3_to_f1, divisor_f4_to_f2;
3344 int common_time_unit_ps;
3345 int freq_max_reduced;
3346};
3347
3348static void
3349compute_frequence_ratios(struct raminfo *info, u16 freq1, u16 freq2,
3350 int num_cycles_2, int num_cycles_1, int round_it,
3351 int add_freqs, struct stru1 *result)
3352{
3353 int g;
3354 int common_time_unit_ps;
3355 int freq1_reduced, freq2_reduced;
3356 int freq_min_reduced;
3357 int freq_max_reduced;
3358 int freq3, freq4;
3359
3360 g = gcd(freq1, freq2);
3361 freq1_reduced = freq1 / g;
3362 freq2_reduced = freq2 / g;
3363 freq_min_reduced = min(freq1_reduced, freq2_reduced);
3364 freq_max_reduced = max(freq1_reduced, freq2_reduced);
3365
3366 common_time_unit_ps = div_roundup(900000, lcm(freq1, freq2));
3367 freq3 = div_roundup(num_cycles_2, common_time_unit_ps) - 1;
3368 freq4 = div_roundup(num_cycles_1, common_time_unit_ps) - 1;
3369 if (add_freqs) {
3370 freq3 += freq2_reduced;
3371 freq4 += freq1_reduced;
3372 }
3373
3374 if (round_it) {
3375 result->freq3_to_2_remainder = 0;
3376 result->freq3_to_2_remaindera = 0;
3377 result->freq4_to_max_remainder = 0;
3378 result->divisor_f4_to_f2 = 0;
3379 result->divisor_f3_to_f1 = 0;
3380 } else {
3381 if (freq2_reduced < freq1_reduced) {
3382 result->freq3_to_2_remainder =
3383 result->freq3_to_2_remaindera =
3384 freq3 % freq1_reduced - freq1_reduced + 1;
3385 result->freq4_to_max_remainder =
3386 -(freq4 % freq1_reduced);
3387 result->divisor_f3_to_f1 = freq3 / freq1_reduced;
3388 result->divisor_f4_to_f2 =
3389 (freq4 -
3390 (freq1_reduced - freq2_reduced)) / freq2_reduced;
3391 result->freq4_to_2_remainder =
3392 -(char)((freq1_reduced - freq2_reduced) +
3393 ((u8) freq4 -
3394 (freq1_reduced -
3395 freq2_reduced)) % (u8) freq2_reduced);
3396 } else {
3397 if (freq2_reduced > freq1_reduced) {
3398 result->freq4_to_max_remainder =
3399 (freq4 % freq2_reduced) - freq2_reduced + 1;
3400 result->freq4_to_2_remainder =
3401 freq4 % freq_max_reduced -
3402 freq_max_reduced + 1;
3403 } else {
3404 result->freq4_to_max_remainder =
3405 -(freq4 % freq2_reduced);
3406 result->freq4_to_2_remainder =
3407 -(char)(freq4 % freq_max_reduced);
3408 }
3409 result->divisor_f4_to_f2 = freq4 / freq2_reduced;
3410 result->divisor_f3_to_f1 =
3411 (freq3 -
3412 (freq2_reduced - freq1_reduced)) / freq1_reduced;
3413 result->freq3_to_2_remainder = -(freq3 % freq2_reduced);
3414 result->freq3_to_2_remaindera =
3415 -(char)((freq_max_reduced - freq_min_reduced) +
3416 (freq3 -
3417 (freq_max_reduced -
3418 freq_min_reduced)) % freq1_reduced);
3419 }
3420 }
3421 result->divisor_f3_to_fmax = freq3 / freq_max_reduced;
3422 result->divisor_f4_to_fmax = freq4 / freq_max_reduced;
3423 if (round_it) {
3424 if (freq2_reduced > freq1_reduced) {
3425 if (freq3 % freq_max_reduced)
3426 result->divisor_f3_to_fmax++;
3427 }
3428 if (freq2_reduced < freq1_reduced) {
3429 if (freq4 % freq_max_reduced)
3430 result->divisor_f4_to_fmax++;
3431 }
3432 }
3433 result->freqs_reversed = (freq2_reduced < freq1_reduced);
3434 result->freq_diff_reduced = freq_max_reduced - freq_min_reduced;
3435 result->freq_min_reduced = freq_min_reduced;
3436 result->common_time_unit_ps = common_time_unit_ps;
3437 result->freq_max_reduced = freq_max_reduced;
3438}
3439
3440static void
3441set_2d5x_reg(struct raminfo *info, u16 reg, u16 freq1, u16 freq2,
3442 int num_cycles_2, int num_cycles_1, int num_cycles_3,
3443 int num_cycles_4, int reverse)
3444{
3445 struct stru1 vv;
3446 char multiplier;
3447
3448 compute_frequence_ratios(info, freq1, freq2, num_cycles_2, num_cycles_1,
3449 0, 1, &vv);
3450
3451 multiplier =
3452 div_roundup(max
3453 (div_roundup(num_cycles_2, vv.common_time_unit_ps) +
3454 div_roundup(num_cycles_3, vv.common_time_unit_ps),
3455 div_roundup(num_cycles_1,
3456 vv.common_time_unit_ps) +
3457 div_roundup(num_cycles_4, vv.common_time_unit_ps))
3458 + vv.freq_min_reduced - 1, vv.freq_max_reduced) - 1;
3459
3460 u32 y =
3461 (u8) ((vv.freq_max_reduced - vv.freq_min_reduced) +
3462 vv.freq_max_reduced * multiplier)
3463 | (vv.
3464 freqs_reversed << 8) | ((u8) (vv.freq_min_reduced *
3465 multiplier) << 16) | ((u8) (vv.
3466 freq_min_reduced
3467 *
3468 multiplier)
3469 << 24);
3470 u32 x =
3471 vv.freq3_to_2_remaindera | (vv.freq4_to_2_remainder << 8) | (vv.
3472 divisor_f3_to_f1
3473 << 16)
3474 | (vv.divisor_f4_to_f2 << 20) | (vv.freq_min_reduced << 24);
3475 if (reverse) {
3476 write_mchbar32(reg, y);
3477 write_mchbar32(reg + 4, x);
3478 } else {
3479 write_mchbar32(reg + 4, y);
3480 write_mchbar32(reg, x);
3481 }
3482}
3483
3484static void
3485set_6d_reg(struct raminfo *info, u16 reg, u16 freq1, u16 freq2,
3486 int num_cycles_1, int num_cycles_2, int num_cycles_3,
3487 int num_cycles_4)
3488{
3489 struct stru1 ratios1;
3490 struct stru1 ratios2;
3491
3492 compute_frequence_ratios(info, freq1, freq2, num_cycles_1, num_cycles_2,
3493 0, 1, &ratios2);
3494 compute_frequence_ratios(info, freq1, freq2, num_cycles_3, num_cycles_4,
3495 0, 1, &ratios1);
3496 write_mchbar32(reg,
3497 ratios1.freq4_to_max_remainder | (ratios2.
3498 freq4_to_max_remainder
3499 << 8)
3500 | (ratios1.divisor_f4_to_fmax << 16) | (ratios2.
3501 divisor_f4_to_fmax
3502 << 20));
3503}
3504
3505static void
3506set_2dx8_reg(struct raminfo *info, u16 reg, u8 mode, u16 freq1, u16 freq2,
3507 int num_cycles_2, int num_cycles_1, int round_it, int add_freqs)
3508{
3509 struct stru1 ratios;
3510
3511 compute_frequence_ratios(info, freq1, freq2, num_cycles_2, num_cycles_1,
3512 round_it, add_freqs, &ratios);
3513 switch (mode) {
3514 case 0:
3515 write_mchbar32(reg + 4,
3516 ratios.freq_diff_reduced | (ratios.
3517 freqs_reversed <<
3518 8));
3519 write_mchbar32(reg,
3520 ratios.freq3_to_2_remainder | (ratios.
3521 freq4_to_max_remainder
3522 << 8)
3523 | (ratios.divisor_f3_to_fmax << 16) | (ratios.
3524 divisor_f4_to_fmax
3525 << 20) |
3526 (ratios.freq_min_reduced << 24));
3527 break;
3528
3529 case 1:
3530 write_mchbar32(reg,
3531 ratios.freq3_to_2_remainder | (ratios.
3532 divisor_f3_to_fmax
3533 << 16));
3534 break;
3535
3536 case 2:
3537 write_mchbar32(reg,
3538 ratios.freq3_to_2_remainder | (ratios.
3539 freq4_to_max_remainder
3540 << 8) | (ratios.
3541 divisor_f3_to_fmax
3542 << 16) |
3543 (ratios.divisor_f4_to_fmax << 20));
3544 break;
3545
3546 case 4:
3547 write_mchbar32(reg, (ratios.divisor_f3_to_fmax << 4)
3548 | (ratios.divisor_f4_to_fmax << 8) | (ratios.
3549 freqs_reversed
3550 << 12) |
3551 (ratios.freq_min_reduced << 16) | (ratios.
3552 freq_diff_reduced
3553 << 24));
3554 break;
3555 }
3556}
3557
3558static void set_2dxx_series(struct raminfo *info)
3559{
3560 set_2dx8_reg(info, 0x2d00, 0, 0x78, frequency_11(info) / 2, 1359, 1005,
3561 0, 1);
3562 set_2dx8_reg(info, 0x2d08, 0, 0x78, 0x78, 3273, 5033, 1, 1);
3563 set_2dx8_reg(info, 0x2d10, 0, 0x78, info->fsb_frequency, 1475, 1131, 0,
3564 1);
3565 set_2dx8_reg(info, 0x2d18, 0, 2 * info->fsb_frequency,
3566 frequency_11(info), 1231, 1524, 0, 1);
3567 set_2dx8_reg(info, 0x2d20, 0, 2 * info->fsb_frequency,
3568 frequency_11(info) / 2, 1278, 2008, 0, 1);
3569 set_2dx8_reg(info, 0x2d28, 0, info->fsb_frequency, frequency_11(info),
3570 1167, 1539, 0, 1);
3571 set_2dx8_reg(info, 0x2d30, 0, info->fsb_frequency,
3572 frequency_11(info) / 2, 1403, 1318, 0, 1);
3573 set_2dx8_reg(info, 0x2d38, 0, info->fsb_frequency, 0x78, 3460, 5363, 1,
3574 1);
3575 set_2dx8_reg(info, 0x2d40, 0, info->fsb_frequency, 0x3c, 2792, 5178, 1,
3576 1);
3577 set_2dx8_reg(info, 0x2d48, 0, 2 * info->fsb_frequency, 0x78, 2738, 4610,
3578 1, 1);
3579 set_2dx8_reg(info, 0x2d50, 0, info->fsb_frequency, 0x78, 2819, 5932, 1,
3580 1);
3581 set_2dx8_reg(info, 0x6d4, 1, info->fsb_frequency,
3582 frequency_11(info) / 2, 4000, 0, 0, 0);
3583 set_2dx8_reg(info, 0x6d8, 2, info->fsb_frequency,
3584 frequency_11(info) / 2, 4000, 4000, 0, 0);
3585
3586 set_6d_reg(info, 0x6dc, 2 * info->fsb_frequency, frequency_11(info), 0,
3587 info->delay46_ps[0], 0, info->delay54_ps[0]);
3588 set_2dx8_reg(info, 0x6e0, 1, 2 * info->fsb_frequency,
3589 frequency_11(info), 2500, 0, 0, 0);
3590 set_2dx8_reg(info, 0x6e4, 1, 2 * info->fsb_frequency,
3591 frequency_11(info) / 2, 3500, 0, 0, 0);
3592 set_6d_reg(info, 0x6e8, 2 * info->fsb_frequency, frequency_11(info), 0,
3593 info->delay46_ps[1], 0, info->delay54_ps[1]);
3594 set_2d5x_reg(info, 0x2d58, 0x78, 0x78, 864, 1195, 762, 786, 0);
3595 set_2d5x_reg(info, 0x2d60, 0x195, info->fsb_frequency, 1352, 725, 455,
3596 470, 0);
3597 set_2d5x_reg(info, 0x2d68, 0x195, 0x3c, 2707, 5632, 3277, 2207, 0);
3598 set_2d5x_reg(info, 0x2d70, 0x195, frequency_11(info) / 2, 1276, 758,
3599 454, 459, 0);
3600 set_2d5x_reg(info, 0x2d78, 0x195, 0x78, 1021, 799, 510, 513, 0);
3601 set_2d5x_reg(info, 0x2d80, info->fsb_frequency, 0xe1, 0, 2862, 2579,
3602 2588, 0);
3603 set_2d5x_reg(info, 0x2d88, info->fsb_frequency, 0xe1, 0, 2690, 2405,
3604 2405, 0);
3605 set_2d5x_reg(info, 0x2da0, 0x78, 0xe1, 0, 2560, 2264, 2251, 0);
3606 set_2d5x_reg(info, 0x2da8, 0x195, frequency_11(info), 1060, 775, 484,
3607 480, 0);
3608 set_2d5x_reg(info, 0x2db0, 0x195, 0x78, 4183, 6023, 2217, 2048, 0);
3609 write_mchbar32(0x2dbc, ((frequency_11(info) / 2) - 1) | 0xe00000);
3610 write_mchbar32(0x2db8, ((info->fsb_frequency - 1) << 16) | 0x77);
3611}
3612
3613static u16 get_max_timing(struct raminfo *info, int channel)
3614{
3615 int slot, rank, lane;
3616 u16 ret = 0;
3617
3618 if ((read_mchbar8(0x2ca8) >> 2) < 1)
3619 return 384;
3620
3621 if (info->revision < 8)
3622 return 256;
3623
3624 for (slot = 0; slot < NUM_SLOTS; slot++)
3625 for (rank = 0; rank < NUM_RANKS; rank++)
3626 if (info->populated_ranks[channel][slot][rank])
3627 for (lane = 0; lane < 8 + info->use_ecc; lane++)
3628 ret = max(ret, read_500(info, channel,
3629 get_timing_register_addr
3630 (lane, 0, slot,
3631 rank), 9));
3632 return ret;
3633}
3634
3635static void set_274265(struct raminfo *info)
3636{
3637 int delay_a_ps, delay_b_ps, delay_c_ps, delay_d_ps;
3638 int delay_e_ps, delay_e_cycles, delay_f_cycles;
3639 int delay_e_over_cycle_ps;
3640 int cycletime_ps;
3641 int channel;
3642
3643 delay_a_ps = 4 * halfcycle_ps(info) + 6 * fsbcycle_ps(info);
3644 info->reg2ca9_bit0 = 0;
3645 for (channel = 0; channel < NUM_CHANNELS; channel++) {
3646 cycletime_ps =
3647 900000 / lcm(2 * info->fsb_frequency, frequency_11(info));
3648 delay_d_ps =
3649 (halfcycle_ps(info) * get_max_timing(info, channel) >> 6)
3650 - info->some_delay_3_ps_rounded + 200;
3651 if (!
3652 ((info->silicon_revision == 0
3653 || info->silicon_revision == 1)
3654 && (info->revision >= 8)))
3655 delay_d_ps += halfcycle_ps(info) * 2;
3656 delay_d_ps +=
3657 halfcycle_ps(info) * (!info->revision_flag_1 +
3658 info->some_delay_2_halfcycles_ceil +
3659 2 * info->some_delay_1_cycle_floor +
3660 info->clock_speed_index +
3661 2 * info->cas_latency - 7 + 11);
3662 delay_d_ps += info->revision >= 8 ? 2758 : 4428;
3663
3664 write_mchbar32(0x140,
3665 (read_mchbar32(0x140) & 0xfaffffff) | 0x2000000);
3666 write_mchbar32(0x138,
3667 (read_mchbar32(0x138) & 0xfaffffff) | 0x2000000);
3668 if ((read_mchbar8(0x144) & 0x1f) > 0x13)
3669 delay_d_ps += 650;
3670 delay_c_ps = delay_d_ps + 1800;
3671 if (delay_c_ps <= delay_a_ps)
3672 delay_e_ps = 0;
3673 else
3674 delay_e_ps =
3675 cycletime_ps * div_roundup(delay_c_ps - delay_a_ps,
3676 cycletime_ps);
3677
3678 delay_e_over_cycle_ps = delay_e_ps % (2 * halfcycle_ps(info));
3679 delay_e_cycles = delay_e_ps / (2 * halfcycle_ps(info));
3680 delay_f_cycles =
3681 div_roundup(2500 - delay_e_over_cycle_ps,
3682 2 * halfcycle_ps(info));
3683 if (delay_f_cycles > delay_e_cycles) {
3684 info->delay46_ps[channel] = delay_e_ps;
3685 delay_e_cycles = 0;
3686 } else {
3687 info->delay46_ps[channel] =
3688 delay_e_over_cycle_ps +
3689 2 * halfcycle_ps(info) * delay_f_cycles;
3690 delay_e_cycles -= delay_f_cycles;
3691 }
3692
3693 if (info->delay46_ps[channel] < 2500) {
3694 info->delay46_ps[channel] = 2500;
3695 info->reg2ca9_bit0 = 1;
3696 }
3697 delay_b_ps = halfcycle_ps(info) + delay_c_ps;
3698 if (delay_b_ps <= delay_a_ps)
3699 delay_b_ps = 0;
3700 else
3701 delay_b_ps -= delay_a_ps;
3702 info->delay54_ps[channel] =
3703 cycletime_ps * div_roundup(delay_b_ps,
3704 cycletime_ps) -
3705 2 * halfcycle_ps(info) * delay_e_cycles;
3706 if (info->delay54_ps[channel] < 2500)
3707 info->delay54_ps[channel] = 2500;
3708 info->reg274265[channel][0] = delay_e_cycles;
3709 if (delay_d_ps + 7 * halfcycle_ps(info) <=
3710 24 * halfcycle_ps(info))
3711 info->reg274265[channel][1] = 0;
3712 else
3713 info->reg274265[channel][1] =
3714 div_roundup(delay_d_ps + 7 * halfcycle_ps(info),
3715 4 * halfcycle_ps(info)) - 6;
3716 write_mchbar32((channel << 10) + 0x274,
3717 info->reg274265[channel][1] | (info->
3718 reg274265[channel]
3719 [0] << 16));
3720 info->reg274265[channel][2] =
3721 div_roundup(delay_c_ps + 3 * fsbcycle_ps(info),
3722 4 * halfcycle_ps(info)) + 1;
3723 write_mchbar16((channel << 10) + 0x265,
3724 info->reg274265[channel][2] << 8);
3725 }
3726 if (info->reg2ca9_bit0)
3727 write_mchbar8(0x2ca9, read_mchbar8(0x2ca9) | 1);
3728 else
3729 write_mchbar8(0x2ca9, read_mchbar8(0x2ca9) & ~1);
3730}
3731
3732static void restore_274265(struct raminfo *info)
3733{
3734 int channel;
3735
3736 for (channel = 0; channel < NUM_CHANNELS; channel++) {
3737 write_mchbar32((channel << 10) + 0x274,
3738 (info->reg274265[channel][0] << 16) | info->
3739 reg274265[channel][1]);
3740 write_mchbar16((channel << 10) + 0x265,
3741 info->reg274265[channel][2] << 8);
3742 }
3743 if (info->reg2ca9_bit0)
3744 write_mchbar8(0x2ca9, read_mchbar8(0x2ca9) | 1);
3745 else
3746 write_mchbar8(0x2ca9, read_mchbar8(0x2ca9) & ~1);
3747}
3748
3749#if REAL
3750static void dmi_setup(void)
3751{
3752 gav(read8(DEFAULT_DMIBAR | 0x254));
3753 write8(DEFAULT_DMIBAR | 0x254, 0x1);
3754 write16(DEFAULT_DMIBAR | 0x1b8, 0x18f2);
3755 read_mchbar16(0x48);
3756 write_mchbar16(0x48, 0x2);
3757
3758 write32(DEFAULT_DMIBAR | 0xd68, read32(DEFAULT_DMIBAR | 0xd68) | 0x08000000);
3759
3760 outl((gav(inl(DEFAULT_GPIOBASE | 0x38)) & ~0x140000) | 0x400000,
3761 DEFAULT_GPIOBASE | 0x38);
3762 gav(inb(DEFAULT_GPIOBASE | 0xe)); // = 0xfdcaff6e
3763}
3764#endif
3765
3766static void
3767set_fsb_frequency (void)
3768{
3769 u8 block[5];
3770 u16 fsbfreq = 62879;
3771 smbus_block_read(0x69, 0, 5, block);
3772 block[0] = fsbfreq;
3773 block[1] = fsbfreq >> 8;
3774
3775 smbus_block_write(0x69, 0, 5, block);
3776}
3777
3778#if REAL
3779void raminit(const int s3resume)
3780#else
3781void raminit(int s3resume)
3782#endif
3783{
3784 unsigned channel, slot, lane, rank;
3785 int i;
3786 struct raminfo info;
3787
3788#if !REAL
3789 pre_raminit1();
3790#endif
3791
3792 if (s3resume) {
3793 read_mchbar32(0x1e8);
3794 write_mchbar32(0x1e8, 0x6);
3795 read_mchbar32(0x1e8);
3796 write_mchbar32(0x1e8, 0x4);
3797 }
3798
3799#if !REAL
3800 pre_raminit_2();
3801#endif
3802 u8 x2ca8;
3803
3804 gav(x2ca8 = read_mchbar8(0x2ca8));
3805 if ((x2ca8 & 1) || (x2ca8 == 8 && !s3resume)) {
3806 printk(BIOS_DEBUG, "soft reset detected, rebooting properly\n");
3807 write_mchbar8(0x2ca8, 0);
3808 outb(0xe, 0xcf9);
3809#if REAL
3810 while (1) {
3811 asm volatile ("hlt");
3812 }
3813#else
3814 printf("CP5\n");
3815 exit(0);
3816#endif
3817 }
3818#if !REAL
3819 if (!s3resume) {
3820 pre_raminit_3(x2ca8);
3821 }
3822#endif
3823
3824#if !REAL
3825 pre_raminit_4a();
3826#endif
3827
3828 dmi_setup();
3829
3830 write_mchbar16(0x1170, 0xa880);
3831 write_mchbar8(0x11c1, 0x1);
3832 write_mchbar16(0x1170, 0xb880);
3833 read_mchbar8(0x1210);
3834 write_mchbar8(0x1210, 0x84);
3835 pcie_read_config8(NORTHBRIDGE, D0F0_GGC); // = 0x52
3836 pcie_write_config8(NORTHBRIDGE, D0F0_GGC, 0x2);
3837 pcie_read_config8(NORTHBRIDGE, D0F0_GGC); // = 0x2
3838 pcie_write_config8(NORTHBRIDGE, D0F0_GGC, 0x52);
3839 pcie_read_config16(NORTHBRIDGE, D0F0_GGC); // = 0xb52
3840
3841 pcie_write_config16(NORTHBRIDGE, D0F0_GGC, 0xb52);
3842
3843 u16 deven;
3844 deven = pcie_read_config16(NORTHBRIDGE, D0F0_DEVEN); // = 0x3
3845
3846 if (deven & 8) {
3847 write_mchbar8(0x2c30, 0x20);
3848 pcie_read_config8(NORTHBRIDGE, 0x8); // = 0x18
3849 write_mchbar16(0x2c30, read_mchbar16(0x2c30) | 0x200);
3850 write_mchbar16(0x2c32, 0x434);
3851 read_mchbar32(0x2c44);
3852 write_mchbar32(0x2c44, 0x1053687);
3853 pcie_read_config8(GMA, 0x62); // = 0x2
3854 pcie_write_config8(GMA, 0x62, 0x2);
3855 read8(DEFAULT_RCBA | 0x2318);
3856 write8(DEFAULT_RCBA | 0x2318, 0x47);
3857 read8(DEFAULT_RCBA | 0x2320);
3858 write8(DEFAULT_RCBA | 0x2320, 0xfc);
3859 }
3860
3861 read_mchbar32(0x30);
3862 write_mchbar32(0x30, 0x40);
3863
3864 pcie_read_config8(SOUTHBRIDGE, 0x8); // = 0x6
3865 pcie_read_config16(NORTHBRIDGE, D0F0_GGC); // = 0xb52
3866 pcie_write_config16(NORTHBRIDGE, D0F0_GGC, 0xb50);
3867 gav(read32(DEFAULT_RCBA | 0x3428));
3868 write32(DEFAULT_RCBA | 0x3428, 0x1d);
3869
3870#if !REAL
3871 pre_raminit_5(s3resume);
3872#else
3873 set_fsb_frequency();
3874#endif
3875
3876 memset(&info, 0x5a, sizeof(info));
3877
3878 info.last_500_command[0] = 0;
3879 info.last_500_command[1] = 0;
3880
3881 info.fsb_frequency = 135 * 2;
3882 info.board_lane_delay[0] = 0x14;
3883 info.board_lane_delay[1] = 0x07;
3884 info.board_lane_delay[2] = 0x07;
3885 info.board_lane_delay[3] = 0x08;
3886 info.board_lane_delay[4] = 0x56;
3887 info.board_lane_delay[5] = 0x04;
3888 info.board_lane_delay[6] = 0x04;
3889 info.board_lane_delay[7] = 0x05;
3890 info.board_lane_delay[8] = 0x10;
3891
3892 info.training.reg_178 = 0;
3893 info.training.reg_10b = 0;
3894
3895 info.heci_bar = 0;
3896 info.memory_reserved_for_heci_mb = 0;
3897
3898 /* before SPD */
3899 timestamp_add_now(101);
3900
3901 if (!s3resume || REAL) {
3902 pcie_read_config8(SOUTHBRIDGE, GEN_PMCON_2); // = 0x80
3903
3904 collect_system_info(&info);
3905
3906#if REAL
3907 /* Enable SMBUS. */
3908 enable_smbus();
3909#endif
3910
3911 memset(&info.populated_ranks, 0, sizeof(info.populated_ranks));
3912
3913 info.use_ecc = 1;
3914 for (channel = 0; channel < NUM_CHANNELS; channel++)
3915 for (slot = 0; slot < NUM_CHANNELS; slot++) {
3916 int v;
3917 int try;
3918 int addr;
3919 const u8 useful_addresses[] = {
3920 DEVICE_TYPE,
3921 MODULE_TYPE,
3922 DENSITY,
3923 RANKS_AND_DQ,
3924 MEMORY_BUS_WIDTH,
3925 TIMEBASE_DIVIDEND,
3926 TIMEBASE_DIVISOR,
3927 CYCLETIME,
3928 CAS_LATENCIES_LSB,
3929 CAS_LATENCIES_MSB,
3930 CAS_LATENCY_TIME,
3931 0x11, 0x12, 0x13, 0x14, 0x15,
3932 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b,
3933 0x1c, 0x1d,
3934 THERMAL_AND_REFRESH,
3935 0x20,
3936 REFERENCE_RAW_CARD_USED,
3937 RANK1_ADDRESS_MAPPING,
3938 0x75, 0x76, 0x77, 0x78,
3939 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e,
3940 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84,
3941 0x85, 0x86, 0x87, 0x88,
3942 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e,
3943 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94,
3944 0x95
3945 };
3946 if (slot)
3947 continue;
3948 for (try = 0; try < 5; try++) {
3949 v = smbus_read_byte(0x50 + channel,
3950 DEVICE_TYPE);
3951 if (v >= 0)
3952 break;
3953 }
3954 if (v < 0)
3955 continue;
3956 for (addr = 0;
3957 addr <
3958 sizeof(useful_addresses) /
3959 sizeof(useful_addresses[0]); addr++)
3960 gav(info.
3961 spd[channel][0][useful_addresses
3962 [addr]] =
3963 smbus_read_byte(0x50 + channel,
3964 useful_addresses
3965 [addr]));
3966 if (info.spd[channel][0][DEVICE_TYPE] != 11)
3967 die("Only DDR3 is supported");
3968
3969 v = info.spd[channel][0][RANKS_AND_DQ];
3970 info.populated_ranks[channel][0][0] = 1;
3971 info.populated_ranks[channel][0][1] =
3972 ((v >> 3) & 7);
3973 if (((v >> 3) & 7) > 1)
3974 die("At most 2 ranks are supported");
3975 if ((v & 7) == 0 || (v & 7) > 2)
3976 die("Only x8 and x16 modules are supported");
3977 if ((info.
3978 spd[channel][slot][MODULE_TYPE] & 0xF) != 2
3979 && (info.
3980 spd[channel][slot][MODULE_TYPE] & 0xF)
3981 != 3)
3982 die("Registered memory is not supported");
3983 info.is_x16_module[channel][0] = (v & 7) - 1;
3984 info.density[channel][slot] =
3985 info.spd[channel][slot][DENSITY] & 0xF;
3986 if (!
3987 (info.
3988 spd[channel][slot][MEMORY_BUS_WIDTH] &
3989 0x18))
3990 info.use_ecc = 0;
3991 }
3992
3993 gav(0x55);
3994
3995 for (channel = 0; channel < NUM_CHANNELS; channel++) {
3996 int v = 0;
3997 for (slot = 0; slot < NUM_SLOTS; slot++)
3998 for (rank = 0; rank < NUM_RANKS; rank++)
3999 v |= info.
4000 populated_ranks[channel][slot][rank]
4001 << (2 * slot + rank);
4002 info.populated_ranks_mask[channel] = v;
4003 }
4004
4005 gav(0x55);
4006
4007 gav(pcie_read_config32(NORTHBRIDGE, D0F0_CAPID0 + 4));
4008 }
4009
4010 /* after SPD */
4011 timestamp_add_now(102);
4012
4013 write_mchbar8(0x2ca8, read_mchbar8(0x2ca8) & 0xfc);
4014#if !REAL
4015 rdmsr (MTRRphysMask_MSR (3));
4016#endif
4017
4018 collect_system_info(&info);
4019 calculate_timings(&info);
4020
4021#if !REAL
4022 pcie_write_config8(NORTHBRIDGE, 0xdf, 0x82);
4023#endif
4024
4025 if (!s3resume) {
4026 u8 reg8 = pcie_read_config8(SOUTHBRIDGE, GEN_PMCON_2);
4027 if (x2ca8 == 0 && (reg8 & 0x80)) {
4028 /* Don't enable S4-assertion stretch. Makes trouble on roda/rk9.
4029 reg8 = pci_read_config8(PCI_DEV(0, 0x1f, 0), 0xa4);
4030 pci_write_config8(PCI_DEV(0, 0x1f, 0), 0xa4, reg8 | 0x08);
4031 */
4032
4033 /* Clear bit7. */
4034
4035 pci_write_config8(SOUTHBRIDGE, GEN_PMCON_2,
4036 (reg8 & ~(1 << 7)));
4037
4038 printk(BIOS_INFO,
4039 "Interrupted RAM init, reset required.\n");
4040 outb(0x6, 0xcf9);
4041#if REAL
4042 while (1) {
4043 asm volatile ("hlt");
4044 }
4045#endif
4046 }
4047 }
4048#if !REAL
4049 gav(read_mchbar8(0x2ca8)); ///!!!!
4050#endif
4051
4052 if (!s3resume && x2ca8 == 0)
4053 pcie_write_config8(SOUTHBRIDGE, GEN_PMCON_2,
4054 pcie_read_config8(SOUTHBRIDGE, GEN_PMCON_2) | 0x80);
4055
4056 compute_derived_timings(&info);
4057
4058 if (x2ca8 == 0) {
4059 gav(read_mchbar8(0x164));
4060 write_mchbar8(0x164, 0x26);
4061 write_mchbar16(0x2c20, 0x10);
4062 }
4063
4064 write_mchbar32(0x18b4, read_mchbar32(0x18b4) | 0x210000); /* OK */
4065 write_mchbar32(0x1890, read_mchbar32(0x1890) | 0x2000000); /* OK */
4066 write_mchbar32(0x18b4, read_mchbar32(0x18b4) | 0x8000);
4067
4068 gav(pcie_read_config32(PCI_DEV(0xff, 2, 1), 0x50)); // !!!!
4069 pcie_write_config8(PCI_DEV(0xff, 2, 1), 0x54, 0x12);
4070
4071 gav(read_mchbar16(0x2c10)); // !!!!
4072 write_mchbar16(0x2c10, 0x412);
4073 gav(read_mchbar16(0x2c10)); // !!!!
4074 write_mchbar16(0x2c12, read_mchbar16(0x2c12) | 0x100); /* OK */
4075
4076 gav(read_mchbar8(0x2ca8)); // !!!!
4077 write_mchbar32(0x1804,
4078 (read_mchbar32(0x1804) & 0xfffffffc) | 0x8400080);
4079
4080 pcie_read_config32(PCI_DEV(0xff, 2, 1), 0x6c); // !!!!
4081 pcie_write_config32(PCI_DEV(0xff, 2, 1), 0x6c, 0x40a0a0);
4082 gav(read_mchbar32(0x1c04)); // !!!!
4083 gav(read_mchbar32(0x1804)); // !!!!
4084
4085 if (x2ca8 == 0) {
4086 write_mchbar8(0x2ca8, read_mchbar8(0x2ca8) | 1);
4087 }
4088
4089 write_mchbar32(0x18d8, 0x120000);
4090 write_mchbar32(0x18dc, 0x30a484a);
4091 pcie_write_config32(PCI_DEV(0xff, 2, 1), 0xe0, 0x0);
4092 pcie_write_config32(PCI_DEV(0xff, 2, 1), 0xf4, 0x9444a);
4093 write_mchbar32(0x18d8, 0x40000);
4094 write_mchbar32(0x18dc, 0xb000000);
4095 pcie_write_config32(PCI_DEV(0xff, 2, 1), 0xe0, 0x60000);
4096 pcie_write_config32(PCI_DEV(0xff, 2, 1), 0xf4, 0x0);
4097 write_mchbar32(0x18d8, 0x180000);
4098 write_mchbar32(0x18dc, 0xc0000142);
4099 pcie_write_config32(PCI_DEV(0xff, 2, 1), 0xe0, 0x20000);
4100 pcie_write_config32(PCI_DEV(0xff, 2, 1), 0xf4, 0x142);
4101 write_mchbar32(0x18d8, 0x1e0000);
4102
4103 gav(read_mchbar32(0x18dc)); // !!!!
4104 write_mchbar32(0x18dc, 0x3);
4105 gav(read_mchbar32(0x18dc)); // !!!!
4106
4107 if (x2ca8 == 0) {
4108 write_mchbar8(0x2ca8, read_mchbar8(0x2ca8) | 1); // guess
4109 }
4110
4111 write_mchbar32(0x188c, 0x20bc09);
4112 pcie_write_config32(PCI_DEV(0xff, 2, 1), 0xd0, 0x40b0c09);
4113 write_mchbar32(0x1a10, 0x4200010e);
4114 write_mchbar32(0x18b8, read_mchbar32(0x18b8) | 0x200);
4115 gav(read_mchbar32(0x1918)); // !!!!
4116 write_mchbar32(0x1918, 0x332);
4117
4118 gav(read_mchbar32(0x18b8)); // !!!!
4119 write_mchbar32(0x18b8, 0xe00);
4120 gav(read_mchbar32(0x182c)); // !!!!
4121 write_mchbar32(0x182c, 0x10202);
4122 gav(pcie_read_config32(PCI_DEV(0xff, 2, 1), 0x94)); // !!!!
4123 pcie_write_config32(PCI_DEV(0xff, 2, 1), 0x94, 0x10202);
4124 write_mchbar32(0x1a1c, read_mchbar32(0x1a1c) & 0x8fffffff);
4125 write_mchbar32(0x1a70, read_mchbar32(0x1a70) | 0x100000);
4126
4127 write_mchbar32(0x18b4, read_mchbar32(0x18b4) & 0xffff7fff);
4128 gav(read_mchbar32(0x1a68)); // !!!!
4129 write_mchbar32(0x1a68, 0x343800);
4130 gav(read_mchbar32(0x1e68)); // !!!!
4131 gav(read_mchbar32(0x1a68)); // !!!!
4132
4133 if (x2ca8 == 0) {
4134 write_mchbar8(0x2ca8, read_mchbar8(0x2ca8) | 1); // guess
4135 }
4136
4137 pcie_read_config32(PCI_DEV(0xff, 2, 0), 0x048); // !!!!
4138 pcie_write_config32(PCI_DEV(0xff, 2, 0), 0x048, 0x140000);
4139 pcie_read_config32(PCI_DEV(0xff, 2, 0), 0x058); // !!!!
4140 pcie_write_config32(PCI_DEV(0xff, 2, 0), 0x058, 0x64555);
4141 pcie_read_config32(PCI_DEV(0xff, 2, 0), 0x058); // !!!!
4142 pcie_read_config32(PCI_DEV (0xff, 0, 0), 0xd0); // !!!!
4143 pcie_write_config32(PCI_DEV (0xff, 0, 0), 0xd0, 0x180);
4144 gav(read_mchbar32(0x1af0)); // !!!!
4145 gav(read_mchbar32(0x1af0)); // !!!!
4146 write_mchbar32(0x1af0, 0x1f020003);
4147 gav(read_mchbar32(0x1af0)); // !!!!
4148
4149 if (((x2ca8 == 0))) {
4150 write_mchbar8(0x2ca8, read_mchbar8(0x2ca8) | 1); // guess
4151 }
4152
4153 gav(read_mchbar32(0x1890)); // !!!!
4154 write_mchbar32(0x1890, 0x80102);
4155 gav(read_mchbar32(0x18b4)); // !!!!
4156 write_mchbar32(0x18b4, 0x216000);
4157 write_mchbar32(0x18a4, 0x22222222);
4158 write_mchbar32(0x18a8, 0x22222222);
4159 write_mchbar32(0x18ac, 0x22222);
4160
4161 udelay(1000);
4162
4163 if (x2ca8 == 0) {
4164 if (s3resume) {
4165#if REAL && 0
4166 info.reg2ca9_bit0 = 0;
4167 info.reg274265[0][0] = 5;
4168 info.reg274265[0][1] = 5;
4169 info.reg274265[0][2] = 0xe;
4170 info.reg274265[1][0] = 5;
4171 info.reg274265[1][1] = 5;
4172 info.reg274265[1][2] = 0xe;
4173 info.delay46_ps[0] = 0xa86;
4174 info.delay46_ps[1] = 0xa86;
4175 info.delay54_ps[0] = 0xdc6;
4176 info.delay54_ps[1] = 0xdc6;
4177#else
4178 info.reg2ca9_bit0 = 0;
4179 info.reg274265[0][0] = 3;
4180 info.reg274265[0][1] = 5;
4181 info.reg274265[0][2] = 0xd;
4182 info.reg274265[1][0] = 4;
4183 info.reg274265[1][1] = 5;
4184 info.reg274265[1][2] = 0xd;
4185 info.delay46_ps[0] = 0x110a;
4186 info.delay46_ps[1] = 0xb58;
4187 info.delay54_ps[0] = 0x144a;
4188 info.delay54_ps[1] = 0xe98;
4189#endif
4190 restore_274265(&info);
4191 } else
4192 set_274265(&info);
4193 int j;
4194 printk(BIOS_DEBUG, "reg2ca9_bit0 = %x\n", info.reg2ca9_bit0);
4195 for (i = 0; i < 2; i++)
4196 for (j = 0; j < 3; j++)
4197 printk(BIOS_DEBUG, "reg274265[%d][%d] = %x\n",
4198 i, j, info.reg274265[i][j]);
4199 for (i = 0; i < 2; i++)
4200 printk(BIOS_DEBUG, "delay46_ps[%d] = %x\n", i,
4201 info.delay46_ps[i]);
4202 for (i = 0; i < 2; i++)
4203 printk(BIOS_DEBUG, "delay54_ps[%d] = %x\n", i,
4204 info.delay54_ps[i]);
4205
4206 set_2dxx_series(&info);
4207
4208 if (!(deven & 8)) {
4209 read_mchbar32(0x2cb0);
4210 write_mchbar32(0x2cb0, 0x40);
4211 }
4212
4213 udelay(1000);
4214
4215 if (deven & 8) {
4216 write_mchbar32(0xff8, 0x1800 | read_mchbar32(0xff8));
4217 read_mchbar32(0x2cb0);
4218 write_mchbar32(0x2cb0, 0x00);
4219 pcie_read_config8(PCI_DEV (0, 0x2, 0x0), 0x4c);
4220 pcie_read_config8(PCI_DEV (0, 0x2, 0x0), 0x4c);
4221 pcie_read_config8(PCI_DEV (0, 0x2, 0x0), 0x4e);
4222
4223 read_mchbar8(0x1150);
4224 read_mchbar8(0x1151);
4225 read_mchbar8(0x1022);
4226 read_mchbar8(0x16d0);
4227 write_mchbar32(0x1300, 0x60606060);
4228 write_mchbar32(0x1304, 0x60606060);
4229 write_mchbar32(0x1308, 0x78797a7b);
4230 write_mchbar32(0x130c, 0x7c7d7e7f);
4231 write_mchbar32(0x1310, 0x60606060);
4232 write_mchbar32(0x1314, 0x60606060);
4233 write_mchbar32(0x1318, 0x60606060);
4234 write_mchbar32(0x131c, 0x60606060);
4235 write_mchbar32(0x1320, 0x50515253);
4236 write_mchbar32(0x1324, 0x54555657);
4237 write_mchbar32(0x1328, 0x58595a5b);
4238 write_mchbar32(0x132c, 0x5c5d5e5f);
4239 write_mchbar32(0x1330, 0x40414243);
4240 write_mchbar32(0x1334, 0x44454647);
4241 write_mchbar32(0x1338, 0x48494a4b);
4242 write_mchbar32(0x133c, 0x4c4d4e4f);
4243 write_mchbar32(0x1340, 0x30313233);
4244 write_mchbar32(0x1344, 0x34353637);
4245 write_mchbar32(0x1348, 0x38393a3b);
4246 write_mchbar32(0x134c, 0x3c3d3e3f);
4247 write_mchbar32(0x1350, 0x20212223);
4248 write_mchbar32(0x1354, 0x24252627);
4249 write_mchbar32(0x1358, 0x28292a2b);
4250 write_mchbar32(0x135c, 0x2c2d2e2f);
4251 write_mchbar32(0x1360, 0x10111213);
4252 write_mchbar32(0x1364, 0x14151617);
4253 write_mchbar32(0x1368, 0x18191a1b);
4254 write_mchbar32(0x136c, 0x1c1d1e1f);
4255 write_mchbar32(0x1370, 0x10203);
4256 write_mchbar32(0x1374, 0x4050607);
4257 write_mchbar32(0x1378, 0x8090a0b);
4258 write_mchbar32(0x137c, 0xc0d0e0f);
4259 write_mchbar8(0x11cc, 0x4e);
4260 write_mchbar32(0x1110, 0x73970404);
4261 write_mchbar32(0x1114, 0x72960404);
4262 write_mchbar32(0x1118, 0x6f950404);
4263 write_mchbar32(0x111c, 0x6d940404);
4264 write_mchbar32(0x1120, 0x6a930404);
4265 write_mchbar32(0x1124, 0x68a41404);
4266 write_mchbar32(0x1128, 0x66a21404);
4267 write_mchbar32(0x112c, 0x63a01404);
4268 write_mchbar32(0x1130, 0x609e1404);
4269 write_mchbar32(0x1134, 0x5f9c1404);
4270 write_mchbar32(0x1138, 0x5c961404);
4271 write_mchbar32(0x113c, 0x58a02404);
4272 write_mchbar32(0x1140, 0x54942404);
4273 write_mchbar32(0x1190, 0x900080a);
4274 write_mchbar16(0x11c0, 0xc40b);
4275 write_mchbar16(0x11c2, 0x303);
4276 write_mchbar16(0x11c4, 0x301);
4277 read_mchbar32(0x1190);
4278 write_mchbar32(0x1190, 0x8900080a);
4279 write_mchbar32(0x11b8, 0x70c3000);
4280 write_mchbar8(0x11ec, 0xa);
4281 write_mchbar16(0x1100, 0x800);
4282 read_mchbar32(0x11bc);
4283 write_mchbar32(0x11bc, 0x1e84800);
4284 write_mchbar16(0x11ca, 0xfa);
4285 write_mchbar32(0x11e4, 0x4e20);
4286 write_mchbar8(0x11bc, 0xf);
4287 write_mchbar16(0x11da, 0x19);
4288 write_mchbar16(0x11ba, 0x470c);
4289 write_mchbar32(0x1680, 0xe6ffe4ff);
4290 write_mchbar32(0x1684, 0xdeffdaff);
4291 write_mchbar32(0x1688, 0xd4ffd0ff);
4292 write_mchbar32(0x168c, 0xccffc6ff);
4293 write_mchbar32(0x1690, 0xc0ffbeff);
4294 write_mchbar32(0x1694, 0xb8ffb0ff);
4295 write_mchbar32(0x1698, 0xa8ff0000);
4296 write_mchbar32(0x169c, 0xc00);
4297 write_mchbar32(0x1290, 0x5000000);
4298 }
4299
4300 write_mchbar32(0x124c, 0x15040d00);
4301 write_mchbar32(0x1250, 0x7f0000);
4302 write_mchbar32(0x1254, 0x1e220004);
4303 write_mchbar32(0x1258, 0x4000004);
4304 write_mchbar32(0x1278, 0x0);
4305 write_mchbar32(0x125c, 0x0);
4306 write_mchbar32(0x1260, 0x0);
4307 write_mchbar32(0x1264, 0x0);
4308 write_mchbar32(0x1268, 0x0);
4309 write_mchbar32(0x126c, 0x0);
4310 write_mchbar32(0x1270, 0x0);
4311 write_mchbar32(0x1274, 0x0);
4312 }
4313
4314 if ((deven & 8) && x2ca8 == 0) {
4315 write_mchbar16(0x1214, 0x320);
4316 write_mchbar32(0x1600, 0x40000000);
4317 read_mchbar32(0x11f4);
4318 write_mchbar32(0x11f4, 0x10000000);
4319 read_mchbar16(0x1230);
4320 write_mchbar16(0x1230, 0x8000);
4321 write_mchbar32(0x1400, 0x13040020);
4322 write_mchbar32(0x1404, 0xe090120);
4323 write_mchbar32(0x1408, 0x5120220);
4324 write_mchbar32(0x140c, 0x5120330);
4325 write_mchbar32(0x1410, 0xe090220);
4326 write_mchbar32(0x1414, 0x1010001);
4327 write_mchbar32(0x1418, 0x1110000);
4328 write_mchbar32(0x141c, 0x9020020);
4329 write_mchbar32(0x1420, 0xd090220);
4330 write_mchbar32(0x1424, 0x2090220);
4331 write_mchbar32(0x1428, 0x2090330);
4332 write_mchbar32(0x142c, 0xd090220);
4333 write_mchbar32(0x1430, 0x1010001);
4334 write_mchbar32(0x1434, 0x1110000);
4335 write_mchbar32(0x1438, 0x11040020);
4336 write_mchbar32(0x143c, 0x4030220);
4337 write_mchbar32(0x1440, 0x1060220);
4338 write_mchbar32(0x1444, 0x1060330);
4339 write_mchbar32(0x1448, 0x4030220);
4340 write_mchbar32(0x144c, 0x1010001);
4341 write_mchbar32(0x1450, 0x1110000);
4342 write_mchbar32(0x1454, 0x4010020);
4343 write_mchbar32(0x1458, 0xb090220);
4344 write_mchbar32(0x145c, 0x1090220);
4345 write_mchbar32(0x1460, 0x1090330);
4346 write_mchbar32(0x1464, 0xb090220);
4347 write_mchbar32(0x1468, 0x1010001);
4348 write_mchbar32(0x146c, 0x1110000);
4349 write_mchbar32(0x1470, 0xf040020);
4350 write_mchbar32(0x1474, 0xa090220);
4351 write_mchbar32(0x1478, 0x1120220);
4352 write_mchbar32(0x147c, 0x1120330);
4353 write_mchbar32(0x1480, 0xa090220);
4354 write_mchbar32(0x1484, 0x1010001);
4355 write_mchbar32(0x1488, 0x1110000);
4356 write_mchbar32(0x148c, 0x7020020);
4357 write_mchbar32(0x1490, 0x1010220);
4358 write_mchbar32(0x1494, 0x10210);
4359 write_mchbar32(0x1498, 0x10320);
4360 write_mchbar32(0x149c, 0x1010220);
4361 write_mchbar32(0x14a0, 0x1010001);
4362 write_mchbar32(0x14a4, 0x1110000);
4363 write_mchbar32(0x14a8, 0xd040020);
4364 write_mchbar32(0x14ac, 0x8090220);
4365 write_mchbar32(0x14b0, 0x1111310);
4366 write_mchbar32(0x14b4, 0x1111420);
4367 write_mchbar32(0x14b8, 0x8090220);
4368 write_mchbar32(0x14bc, 0x1010001);
4369 write_mchbar32(0x14c0, 0x1110000);
4370 write_mchbar32(0x14c4, 0x3010020);
4371 write_mchbar32(0x14c8, 0x7090220);
4372 write_mchbar32(0x14cc, 0x1081310);
4373 write_mchbar32(0x14d0, 0x1081420);
4374 write_mchbar32(0x14d4, 0x7090220);
4375 write_mchbar32(0x14d8, 0x1010001);
4376 write_mchbar32(0x14dc, 0x1110000);
4377 write_mchbar32(0x14e0, 0xb040020);
4378 write_mchbar32(0x14e4, 0x2030220);
4379 write_mchbar32(0x14e8, 0x1051310);
4380 write_mchbar32(0x14ec, 0x1051420);
4381 write_mchbar32(0x14f0, 0x2030220);
4382 write_mchbar32(0x14f4, 0x1010001);
4383 write_mchbar32(0x14f8, 0x1110000);
4384 write_mchbar32(0x14fc, 0x5020020);
4385 write_mchbar32(0x1500, 0x5090220);
4386 write_mchbar32(0x1504, 0x2071310);
4387 write_mchbar32(0x1508, 0x2071420);
4388 write_mchbar32(0x150c, 0x5090220);
4389 write_mchbar32(0x1510, 0x1010001);
4390 write_mchbar32(0x1514, 0x1110000);
4391 write_mchbar32(0x1518, 0x7040120);
4392 write_mchbar32(0x151c, 0x2090220);
4393 write_mchbar32(0x1520, 0x70b1210);
4394 write_mchbar32(0x1524, 0x70b1310);
4395 write_mchbar32(0x1528, 0x2090220);
4396 write_mchbar32(0x152c, 0x1010001);
4397 write_mchbar32(0x1530, 0x1110000);
4398 write_mchbar32(0x1534, 0x1010110);
4399 write_mchbar32(0x1538, 0x1081310);
4400 write_mchbar32(0x153c, 0x5041200);
4401 write_mchbar32(0x1540, 0x5041310);
4402 write_mchbar32(0x1544, 0x1081310);
4403 write_mchbar32(0x1548, 0x1010001);
4404 write_mchbar32(0x154c, 0x1110000);
4405 write_mchbar32(0x1550, 0x1040120);
4406 write_mchbar32(0x1554, 0x4051210);
4407 write_mchbar32(0x1558, 0xd051200);
4408 write_mchbar32(0x155c, 0xd051200);
4409 write_mchbar32(0x1560, 0x4051210);
4410 write_mchbar32(0x1564, 0x1010001);
4411 write_mchbar32(0x1568, 0x1110000);
4412 write_mchbar16(0x1222, 0x220a);
4413 write_mchbar16(0x123c, 0x1fc0);
4414 write_mchbar16(0x1220, 0x1388);
4415 }
4416
4417 read_mchbar32(0x2c80); // !!!!
4418 write_mchbar32(0x2c80, 0x1053688);
4419 read_mchbar32(0x1c04); // !!!!
4420 write_mchbar32(0x1804, 0x406080);
4421
4422 read_mchbar8(0x2ca8);
4423
4424 if (x2ca8 == 0) {
4425 write_mchbar8(0x2ca8, read_mchbar8(0x2ca8) & ~3);
4426 write_mchbar8(0x2ca8, read_mchbar8(0x2ca8) + 4);
4427 write_mchbar32(0x1af0, read_mchbar32(0x1af0) | 0x10);
4428#if REAL
4429 while (1) {
4430 asm volatile ("hlt");
4431 }
4432#else
4433 printf("CP5\n");
4434 exit(0);
4435#endif
4436 }
4437
4438 write_mchbar8(0x2ca8, read_mchbar8(0x2ca8));
4439 read_mchbar32(0x2c80); // !!!!
4440 write_mchbar32(0x2c80, 0x53688);
4441 pcie_write_config32(PCI_DEV (0xff, 0, 0), 0x60, 0x20220);
4442 read_mchbar16(0x2c20); // !!!!
4443 read_mchbar16(0x2c10); // !!!!
4444 read_mchbar16(0x2c00); // !!!!
4445 write_mchbar16(0x2c00, 0x8c0);
4446 udelay(1000);
4447 write_1d0(0, 0x33d, 0, 0);
4448 write_500(&info, 0, 0, 0xb61, 0, 0);
4449 write_500(&info, 1, 0, 0xb61, 0, 0);
4450 write_mchbar32(0x1a30, 0x0);
4451 write_mchbar32(0x1a34, 0x0);
4452 write_mchbar16(0x614,
4453 0xb5b | (info.populated_ranks[1][0][0] *
4454 0x404) | (info.populated_ranks[0][0][0] *
4455 0xa0));
4456 write_mchbar16(0x616, 0x26a);
4457 write_mchbar32(0x134, 0x856000);
4458 write_mchbar32(0x160, 0x5ffffff);
4459 read_mchbar32(0x114); // !!!!
4460 write_mchbar32(0x114, 0xc2024440);
4461 read_mchbar32(0x118); // !!!!
4462 write_mchbar32(0x118, 0x4);
4463 for (channel = 0; channel < NUM_CHANNELS; channel++)
4464 write_mchbar32(0x260 + (channel << 10),
4465 0x30809ff |
4466 ((info.
4467 populated_ranks_mask[channel] & 3) << 20));
4468 for (channel = 0; channel < NUM_CHANNELS; channel++) {
4469 write_mchbar16(0x31c + (channel << 10), 0x101);
4470 write_mchbar16(0x360 + (channel << 10), 0x909);
4471 write_mchbar16(0x3a4 + (channel << 10), 0x101);
4472 write_mchbar16(0x3e8 + (channel << 10), 0x101);
4473 write_mchbar32(0x320 + (channel << 10), 0x29002900);
4474 write_mchbar32(0x324 + (channel << 10), 0x0);
4475 write_mchbar32(0x368 + (channel << 10), 0x32003200);
4476 write_mchbar16(0x352 + (channel << 10), 0x505);
4477 write_mchbar16(0x354 + (channel << 10), 0x3c3c);
4478 write_mchbar16(0x356 + (channel << 10), 0x1040);
4479 write_mchbar16(0x39a + (channel << 10), 0x73e4);
4480 write_mchbar16(0x3de + (channel << 10), 0x77ed);
4481 write_mchbar16(0x422 + (channel << 10), 0x1040);
4482 }
4483
4484 write_1d0(0x4, 0x151, 4, 1);
4485 write_1d0(0, 0x142, 3, 1);
4486 rdmsr(0x1ac); // !!!!
4487 write_500(&info, 1, 1, 0x6b3, 4, 1);
4488 write_500(&info, 1, 1, 0x6cf, 4, 1);
4489
4490 rmw_1d0(0x21c, 0x38, 0, 6, 1);
4491
4492 write_1d0(((!info.populated_ranks[1][0][0]) << 1) | ((!info.
4493 populated_ranks[0]
4494 [0][0]) << 0),
4495 0x1d1, 3, 1);
4496 for (channel = 0; channel < NUM_CHANNELS; channel++) {
4497 write_mchbar16(0x38e + (channel << 10), 0x5f5f);
4498 write_mchbar16(0x3d2 + (channel << 10), 0x5f5f);
4499 }
4500
4501 set_334(0);
4502
4503 program_base_timings(&info);
4504
4505 write_mchbar8(0x5ff, read_mchbar8(0x5ff) | 0x80); /* OK */
4506
4507 write_1d0(0x2, 0x1d5, 2, 1);
4508 write_1d0(0x20, 0x166, 7, 1);
4509 write_1d0(0x0, 0xeb, 3, 1);
4510 write_1d0(0x0, 0xf3, 6, 1);
4511
4512 for (channel = 0; channel < NUM_CHANNELS; channel++)
4513 for (lane = 0; lane < 9; lane++) {
4514 u16 addr = 0x125 + get_lane_offset(0, 0, lane);
4515 u8 a;
4516 a = read_500(&info, channel, addr, 6); // = 0x20040080 //!!!!
4517 write_500(&info, channel, a, addr, 6, 1);
4518 }
4519
4520 udelay(1000);
4521
4522 info.cached_training = get_cached_training();
4523
4524 if (s3resume) {
4525 if (info.cached_training == NULL) {
4526 u32 reg32;
4527 printk(BIOS_ERR,
4528 "Couldn't find training data. Rebooting\n");
4529 reg32 = inl(DEFAULT_PMBASE + 0x04);
4530 outl(reg32 & ~(7 << 10), DEFAULT_PMBASE + 0x04);
4531 outb(0xe, 0xcf9);
4532
4533#if REAL
4534 while (1) {
4535 asm volatile ("hlt");
4536 }
4537#else
4538 printf("CP5\n");
4539 exit(0);
4540#endif
4541 }
4542 int tm;
4543 info.training = *info.cached_training;
4544 for (tm = 0; tm < 4; tm++)
4545 for (channel = 0; channel < NUM_CHANNELS; channel++)
4546 for (slot = 0; slot < NUM_SLOTS; slot++)
4547 for (rank = 0; rank < NUM_RANKS; rank++)
4548 for (lane = 0; lane < 9; lane++)
4549 write_500(&info,
4550 channel,
4551 info.training.
4552 lane_timings
4553 [tm][channel]
4554 [slot][rank]
4555 [lane],
4556 get_timing_register_addr
4557 (lane, tm,
4558 slot, rank),
4559 9, 0);
4560 write_1d0(info.cached_training->reg_178, 0x178, 7, 1);
4561 write_1d0(info.cached_training->reg_10b, 0x10b, 6, 1);
4562 }
4563
4564 read_mchbar32(0x1f4); // !!!!
4565 write_mchbar32(0x1f4, 0x20000);
4566 write_mchbar32(0x1f0, 0x1d000200);
4567 read_mchbar8(0x1f0); // !!!!
4568 write_mchbar8(0x1f0, 0x1);
4569 read_mchbar8(0x1f0); // !!!!
4570
4571 program_board_delay(&info);
4572
4573 write_mchbar8(0x5ff, 0x0); /* OK */
4574 write_mchbar8(0x5ff, 0x80); /* OK */
4575 write_mchbar8(0x5f4, 0x1); /* OK */
4576
4577 write_mchbar32(0x130, read_mchbar32(0x130) & 0xfffffffd); // | 2 when ?
4578 while (read_mchbar32(0x130) & 1) ;
4579 gav(read_1d0(0x14b, 7)); // = 0x81023100
4580 write_1d0(0x30, 0x14b, 7, 1);
4581 read_1d0(0xd6, 6); // = 0xfa008080 // !!!!
4582 write_1d0(7, 0xd6, 6, 1);
4583 read_1d0(0x328, 6); // = 0xfa018080 // !!!!
4584 write_1d0(7, 0x328, 6, 1);
4585
4586 for (channel = 0; channel < NUM_CHANNELS; channel++)
4587 set_4cf(&info, channel,
4588 info.populated_ranks[channel][0][0] ? 8 : 0);
4589
4590 read_1d0(0x116, 4); // = 0x4040432 // !!!!
4591 write_1d0(2, 0x116, 4, 1);
4592 read_1d0(0xae, 6); // = 0xe8088080 // !!!!
4593 write_1d0(0, 0xae, 6, 1);
4594 read_1d0(0x300, 4); // = 0x48088080 // !!!!
4595 write_1d0(0, 0x300, 6, 1);
4596 read_mchbar16(0x356); // !!!!
4597 write_mchbar16(0x356, 0x1040);
4598 read_mchbar16(0x756); // !!!!
4599 write_mchbar16(0x756, 0x1040);
4600 write_mchbar32(0x140, read_mchbar32(0x140) & ~0x07000000);
4601 write_mchbar32(0x138, read_mchbar32(0x138) & ~0x07000000);
4602 write_mchbar32(0x130, 0x31111301);
4603 while (read_mchbar32(0x130) & 1) ;
4604
4605 {
4606 u32 t;
4607 u8 val_a1;
4608 val_a1 = read_1d0(0xa1, 6); // = 0x1cf4040 // !!!!
4609 t = read_1d0(0x2f3, 6); // = 0x10a4040 // !!!!
4610 rmw_1d0(0x320, 0x07,
4611 (t & 4) | ((t & 8) >> 2) | ((t & 0x10) >> 4), 6, 1);
4612 rmw_1d0(0x14b, 0x78,
4613 ((((val_a1 >> 2) & 4) | (val_a1 & 8)) >> 2) | (val_a1 &
4614 4), 7,
4615 1);
4616 rmw_1d0(0xce, 0x38,
4617 ((((val_a1 >> 2) & 4) | (val_a1 & 8)) >> 2) | (val_a1 &
4618 4), 6,
4619 1);
4620 }
4621
4622 for (channel = 0; channel < NUM_CHANNELS; channel++)
4623 set_4cf(&info, channel,
4624 info.populated_ranks[channel][0][0] ? 9 : 1);
4625
4626 rmw_1d0(0x116, 0xe, 1, 4, 1); // = 0x4040432 // !!!!
4627 read_mchbar32(0x144); // !!!!
4628 write_1d0(2, 0xae, 6, 1);
4629 write_1d0(2, 0x300, 6, 1);
4630 write_1d0(2, 0x121, 3, 1);
4631 read_1d0(0xd6, 6); // = 0xfa00c0c7 // !!!!
4632 write_1d0(4, 0xd6, 6, 1);
4633 read_1d0(0x328, 6); // = 0xfa00c0c7 // !!!!
4634 write_1d0(4, 0x328, 6, 1);
4635
4636 for (channel = 0; channel < NUM_CHANNELS; channel++)
4637 set_4cf(&info, channel,
4638 info.populated_ranks[channel][0][0] ? 9 : 0);
4639
4640 write_mchbar32(0x130,
4641 0x11111301 | (info.
4642 populated_ranks[1][0][0] << 30) | (info.
4643 populated_ranks
4644 [0][0]
4645 [0] <<
4646 29));
4647 while (read_mchbar8(0x130) & 1) ; // !!!!
4648 read_1d0(0xa1, 6); // = 0x1cf4054 // !!!!
4649 read_1d0(0x2f3, 6); // = 0x10a4054 // !!!!
4650 read_1d0(0x21c, 6); // = 0xafa00c0 // !!!!
4651 write_1d0(0, 0x21c, 6, 1);
4652 read_1d0(0x14b, 7); // = 0x810231b0 // !!!!
4653 write_1d0(0x35, 0x14b, 7, 1);
4654
4655 for (channel = 0; channel < NUM_CHANNELS; channel++)
4656 set_4cf(&info, channel,
4657 info.populated_ranks[channel][0][0] ? 0xb : 0x2);
4658
4659 set_334(1);
4660
4661 write_mchbar8(0x1e8, 0x4); /* OK */
4662
4663 for (channel = 0; channel < NUM_CHANNELS; channel++) {
4664 write_500(&info, channel,
4665 0x3 & ~(info.populated_ranks_mask[channel]), 0x6b7, 2,
4666 1);
4667 write_500(&info, channel, 0x3, 0x69b, 2, 1);
4668 }
4669 write_mchbar32(0x2d0, (read_mchbar32(0x2d0) & 0xff2c01ff) | 0x200000); /* OK */
4670 write_mchbar16(0x6c0, 0x14a0); /* OK */
4671 write_mchbar32(0x6d0, (read_mchbar32(0x6d0) & 0xff0080ff) | 0x8000); /* OK */
4672 write_mchbar16(0x232, 0x8);
4673 write_mchbar32(0x234, (read_mchbar32(0x234) & 0xfffbfffb) | 0x40004); /* 0x40004 or 0 depending on ? */
4674 write_mchbar32(0x34, (read_mchbar32(0x34) & 0xfffffffd) | 5); /* OK */
4675 write_mchbar32(0x128, 0x2150d05);
4676 write_mchbar8(0x12c, 0x1f); /* OK */
4677 write_mchbar8(0x12d, 0x56); /* OK */
4678 write_mchbar8(0x12e, 0x31);
4679 write_mchbar8(0x12f, 0x0); /* OK */
4680 write_mchbar8(0x271, 0x2); /* OK */
4681 write_mchbar8(0x671, 0x2); /* OK */
4682 write_mchbar8(0x1e8, 0x4); /* OK */
4683 for (channel = 0; channel < NUM_CHANNELS; channel++)
4684 write_mchbar32(0x294 + (channel << 10),
4685 (info.populated_ranks_mask[channel] & 3) << 16);
4686 write_mchbar32(0x134, (read_mchbar32(0x134) & 0xfc01ffff) | 0x10000); /* OK */
4687 write_mchbar32(0x134, (read_mchbar32(0x134) & 0xfc85ffff) | 0x850000); /* OK */
4688 for (channel = 0; channel < NUM_CHANNELS; channel++)
4689 write_mchbar32(0x260 + (channel << 10),
4690 (read_mchbar32(0x260 + (channel << 10)) &
4691 ~0xf00000) | 0x8000000 | ((info.
4692 populated_ranks_mask
4693 [channel] & 3) <<
4694 20));
4695
4696 if (!s3resume)
4697 jedec_init(&info);
4698
4699 int totalrank = 0;
4700 for (channel = 0; channel < NUM_CHANNELS; channel++)
4701 for (slot = 0; slot < NUM_SLOTS; slot++)
4702 for (rank = 0; rank < NUM_RANKS; rank++)
4703 if (info.populated_ranks[channel][slot][rank]) {
4704 jedec_read(&info, channel, slot, rank,
4705 totalrank, 0xa, 0x400);
4706 totalrank++;
4707 }
4708
4709 write_mchbar8(0x12c, 0x9f);
4710
4711 read_mchbar8(0x271); // 2 // !!!!
4712 write_mchbar8(0x271, 0xe);
4713 read_mchbar8(0x671); // !!!!
4714 write_mchbar8(0x671, 0xe);
4715
4716 if (!s3resume) {
4717 for (channel = 0; channel < NUM_CHANNELS; channel++) {
4718 write_mchbar32(0x294 + (channel << 10),
4719 (info.
4720 populated_ranks_mask[channel] & 3) <<
4721 16);
4722 write_mchbar16(0x298 + (channel << 10),
4723 (info.
4724 populated_ranks[channel][0][0]) | (info.
4725 populated_ranks
4726 [channel]
4727 [0]
4728 [1]
4729 <<
4730 5));
4731 write_mchbar32(0x29c + (channel << 10), 0x77a);
4732 }
4733 read_mchbar32(0x2c0); /// !!!
4734 write_mchbar32(0x2c0, 0x6009cc00);
4735
4736 {
4737 u8 a, b;
4738 a = read_mchbar8(0x243); // !!!!
4739 b = read_mchbar8(0x643); // !!!!
4740 write_mchbar8(0x243, a | 2);
4741 write_mchbar8(0x643, b | 2);
4742 }
4743
4744 write_1d0(7, 0x19b, 3, 1);
4745 write_1d0(7, 0x1c0, 3, 1);
4746 write_1d0(4, 0x1c6, 4, 1);
4747 write_1d0(4, 0x1cc, 4, 1);
4748 read_1d0(0x151, 4); // = 0x408c6d74 // !!!!
4749 write_1d0(4, 0x151, 4, 1);
4750 write_mchbar32(0x584, 0xfffff);
4751 write_mchbar32(0x984, 0xfffff);
4752
4753 for (channel = 0; channel < NUM_CHANNELS; channel++)
4754 for (slot = 0; slot < NUM_SLOTS; slot++)
4755 for (rank = 0; rank < NUM_RANKS; rank++)
4756 if (info.
4757 populated_ranks[channel][slot]
4758 [rank])
4759 config_rank(&info, s3resume,
4760 channel, slot,
4761 rank);
4762
4763 write_mchbar8(0x243, 0x1);
4764 write_mchbar8(0x643, 0x1);
4765 }
4766
4767 /* was == 1 but is common */
4768 pcie_write_config16(NORTHBRIDGE, 0xc8, 3);
4769 write_26c(0, 0x820);
4770 write_26c(1, 0x820);
4771 write_mchbar32(0x130, read_mchbar32(0x130) | 2);
4772 /* end */
4773
4774 if (s3resume) {
4775 for (channel = 0; channel < NUM_CHANNELS; channel++) {
4776 write_mchbar32(0x294 + (channel << 10),
4777 (info.
4778 populated_ranks_mask[channel] & 3) <<
4779 16);
4780 write_mchbar16(0x298 + (channel << 10),
4781 (info.
4782 populated_ranks[channel][0][0]) | (info.
4783 populated_ranks
4784 [channel]
4785 [0]
4786 [1]
4787 <<
4788 5));
4789 write_mchbar32(0x29c + (channel << 10), 0x77a);
4790 }
4791 read_mchbar32(0x2c0); /// !!!
4792 write_mchbar32(0x2c0, 0x6009cc00);
4793 }
4794
4795 write_mchbar32(0xfa4, read_mchbar32(0xfa4) & ~0x01000002);
4796 write_mchbar32(0xfb0, 0x2000e019);
4797
4798#if !REAL
4799 printf("CP16\n");
4800#endif
4801
4802 /* Before training. */
4803 timestamp_add_now(103);
4804
4805 if (!s3resume)
4806 ram_training(&info);
4807
4808 /* After training. */
4809 timestamp_add_now (104);
4810
4811 dump_timings(&info);
4812
4813#if 0
4814 ram_check(0x100000, 0x200000);
4815#endif
4816 program_modules_memory_map(&info, 0);
4817 program_total_memory_map(&info);
4818
4819 if (info.non_interleaved_part_mb != 0 && info.interleaved_part_mb != 0)
4820 write_mchbar8(0x111, 0x20 | (0 << 2) | (1 << 6) | (0 << 7));
4821 else if (have_match_ranks(&info, 0, 4) && have_match_ranks(&info, 1, 4))
4822 write_mchbar8(0x111, 0x20 | (3 << 2) | (0 << 6) | (1 << 7));
4823 else if (have_match_ranks(&info, 0, 2) && have_match_ranks(&info, 1, 2))
4824 write_mchbar8(0x111, 0x20 | (3 << 2) | (0 << 6) | (0 << 7));
4825 else
4826 write_mchbar8(0x111, 0x20 | (3 << 2) | (1 << 6) | (0 << 7));
4827
4828 write_mchbar32(0xfac, read_mchbar32(0xfac) & ~0x80000000); // OK
4829 write_mchbar32(0xfb4, 0x4800); // OK
4830 write_mchbar32(0xfb8, (info.revision < 8) ? 0x20 : 0x0); // OK
4831 write_mchbar32(0xe94, 0x7ffff); // OK
4832 write_mchbar32(0xfc0, 0x80002040); // OK
4833 write_mchbar32(0xfc4, 0x701246); // OK
4834 write_mchbar8(0xfc8, read_mchbar8(0xfc8) & ~0x70); // OK
4835 write_mchbar32(0xe5c, 0x1000000 | read_mchbar32(0xe5c)); // OK
4836 write_mchbar32(0x1a70, (read_mchbar32(0x1a70) | 0x00200000) & ~0x00100000); // OK
4837 write_mchbar32(0x50, 0x700b0); // OK
4838 write_mchbar32(0x3c, 0x10); // OK
4839 write_mchbar8(0x1aa8, (read_mchbar8(0x1aa8) & ~0x35) | 0xa); // OK
4840 write_mchbar8(0xff4, read_mchbar8(0xff4) | 0x2); // OK
4841 write_mchbar32(0xff8, (read_mchbar32(0xff8) & ~0xe008) | 0x1020); // OK
4842
4843#if REAL
4844 write_mchbar32(0xd00, IOMMU_BASE2 | 1);
4845 write_mchbar32(0xd40, IOMMU_BASE1 | 1);
4846 write_mchbar32(0xdc0, IOMMU_BASE4 | 1);
4847
4848 write32(IOMMU_BASE1 | 0xffc, 0x80000000);
4849 write32(IOMMU_BASE2 | 0xffc, 0xc0000000);
4850 write32(IOMMU_BASE4 | 0xffc, 0x80000000);
4851
4852#else
4853 {
4854 u32 eax;
4855 eax = read32(0xffc + (read_mchbar32(0xd00) & ~1)) | 0x08000000; // = 0xe911714b// OK
4856 write32(0xffc + (read_mchbar32(0xd00) & ~1), eax); // OK
4857 eax = read32(0xffc + (read_mchbar32(0xdc0) & ~1)) | 0x40000000; // = 0xe911714b// OK
4858 write32(0xffc + (read_mchbar32(0xdc0) & ~1), eax); // OK
4859 }
4860#endif
4861
4862 {
4863 u32 eax;
4864
4865 eax = info.fsb_frequency / 9;
4866 write_mchbar32(0xfcc, (read_mchbar32(0xfcc) & 0xfffc0000) | (eax * 0x280) | (eax * 0x5000) | eax | 0x40000); // OK
4867 write_mchbar32(0x20, 0x33001); //OK
4868 }
4869
4870 for (channel = 0; channel < NUM_CHANNELS; channel++) {
4871 write_mchbar32(0x220 + (channel << 10), read_mchbar32(0x220 + (channel << 10)) & ~0x7770); //OK
4872 if (info.max_slots_used_in_channel == 1)
4873 write_mchbar16(0x237 + (channel << 10), (read_mchbar16(0x237 + (channel << 10)) | 0x0201)); //OK
4874 else
4875 write_mchbar16(0x237 + (channel << 10), (read_mchbar16(0x237 + (channel << 10)) & ~0x0201)); //OK
4876
4877 write_mchbar8(0x241 + (channel << 10), read_mchbar8(0x241 + (channel << 10)) | 1); // OK
4878
4879 if (info.clock_speed_index <= 1
4880 && (info.silicon_revision == 2
4881 || info.silicon_revision == 3))
4882 write_mchbar32(0x248 + (channel << 10), (read_mchbar32(0x248 + (channel << 10)) | 0x00102000)); // OK
4883 else
4884 write_mchbar32(0x248 + (channel << 10), (read_mchbar32(0x248 + (channel << 10)) & ~0x00102000)); // OK
4885 }
4886
4887 write_mchbar32(0x115, read_mchbar32(0x115) | 0x1000000); // OK
4888
4889 {
4890 u8 al;
4891 al = 0xd;
4892 if (!(info.silicon_revision == 0 || info.silicon_revision == 1))
4893 al += 2;
4894 al |= ((1 << (info.max_slots_used_in_channel - 1)) - 1) << 4;
4895 write_mchbar32(0x210, (al << 16) | 0x20); // OK
4896 }
4897
4898 for (channel = 0; channel < NUM_CHANNELS; channel++) {
4899 write_mchbar32(0x288 + (channel << 10), 0x70605040); // OK
4900 write_mchbar32(0x28c + (channel << 10), 0xfffec080); // OK
4901 write_mchbar32(0x290 + (channel << 10), 0x282091c | ((info.max_slots_used_in_channel - 1) << 0x16)); // OK
4902 }
4903 u32 reg1c;
4904 pcie_read_config32(NORTHBRIDGE, 0x40); // = DEFAULT_EPBAR | 0x001 // OK
4905 reg1c = read32(DEFAULT_EPBAR | 0x01c); // = 0x8001 // OK
4906 pcie_read_config32(NORTHBRIDGE, 0x40); // = DEFAULT_EPBAR | 0x001 // OK
4907 write32(DEFAULT_EPBAR | 0x01c, reg1c); // OK
4908 read_mchbar8(0xe08); // = 0x0
4909 pcie_read_config32(NORTHBRIDGE, 0xe4); // = 0x316126
4910 write_mchbar8(0x1210, read_mchbar8(0x1210) | 2); // OK
4911 write_mchbar32(0x1200, 0x8800440); // OK
4912 write_mchbar32(0x1204, 0x53ff0453); // OK
4913 write_mchbar32(0x1208, 0x19002043); // OK
4914 write_mchbar16(0x1214, 0x320); // OK
4915
4916 if (info.revision == 0x10 || info.revision == 0x11) {
4917 write_mchbar16(0x1214, 0x220); // OK
4918 write_mchbar8(0x1210, read_mchbar8(0x1210) | 0x40); // OK
4919 }
4920
4921 write_mchbar8(0x1214, read_mchbar8(0x1214) | 0x4); // OK
4922 write_mchbar8(0x120c, 0x1); // OK
4923 write_mchbar8(0x1218, 0x3); // OK
4924 write_mchbar8(0x121a, 0x3); // OK
4925 write_mchbar8(0x121c, 0x3); // OK
4926 write_mchbar16(0xc14, 0x0); // OK
4927 write_mchbar16(0xc20, 0x0); // OK
4928 write_mchbar32(0x1c, 0x0); // OK
4929
4930 /* revision dependent here. */
4931
4932 write_mchbar16(0x1230, read_mchbar16(0x1230) | 0x1f07); // OK
4933
4934 if (info.uma_enabled)
4935 write_mchbar32(0x11f4, read_mchbar32(0x11f4) | 0x10000000); // OK
4936
4937 write_mchbar16(0x1230, read_mchbar16(0x1230) | 0x8000); // OK
4938 write_mchbar8(0x1214, read_mchbar8(0x1214) | 1); // OK
4939
4940 u8 bl, ebpb;
4941 u16 reg_1020;
4942
4943 reg_1020 = read_mchbar32(0x1020); // = 0x6c733c // OK
4944 write_mchbar8(0x1070, 0x1); // OK
4945
4946 write_mchbar32(0x1000, 0x100); // OK
4947 write_mchbar8(0x1007, 0x0); // OK
4948
4949 if (reg_1020 != 0) {
4950 write_mchbar16(0x1018, 0x0); // OK
4951 bl = reg_1020 >> 8;
4952 ebpb = reg_1020 & 0xff;
4953 } else {
4954 ebpb = 0;
4955 bl = 8;
4956 }
4957
4958 rdmsr(0x1a2);
4959
4960 write_mchbar32(0x1014, 0xffffffff); // OK
4961
4962 write_mchbar32(0x1010, ((((ebpb + 0x7d) << 7) / bl) & 0xff) * (! !reg_1020)); // OK
4963
4964 write_mchbar8(0x101c, 0xb8); // OK
4965
4966 write_mchbar8(0x123e, (read_mchbar8(0x123e) & 0xf) | 0x60); // OK
4967 if (reg_1020 != 0) {
4968 write_mchbar32(0x123c, (read_mchbar32(0x123c) & ~0x00900000) | 0x600000); // OK
4969 write_mchbar8(0x101c, 0xb8); // OK
4970 }
4971
4972 setup_heci_uma(&info);
4973
4974 if (info.uma_enabled) {
4975 u16 ax;
4976 write_mchbar32(0x11b0, read_mchbar32(0x11b0) | 0x4000); // OK
4977 write_mchbar32(0x11b4, read_mchbar32(0x11b4) | 0x4000); // OK
4978 write_mchbar16(0x1190, read_mchbar16(0x1190) | 0x4000); // OK
4979
4980 ax = read_mchbar16(0x1190) & 0xf00; // = 0x480a // OK
4981 write_mchbar16(0x1170, ax | (read_mchbar16(0x1170) & 0x107f) | 0x4080); // OK
4982 write_mchbar16(0x1170, read_mchbar16(0x1170) | 0x1000); // OK
4983#if REAL
4984 udelay(1000);
4985#endif
4986 u16 ecx;
4987 for (ecx = 0xffff; ecx && (read_mchbar16(0x1170) & 0x1000); ecx--) ; // OK
4988 write_mchbar16(0x1190, read_mchbar16(0x1190) & ~0x4000); // OK
4989 }
4990
4991 pcie_write_config8(SOUTHBRIDGE, GEN_PMCON_2,
4992 pcie_read_config8(SOUTHBRIDGE, GEN_PMCON_2) & ~0x80);
4993 udelay(10000);
4994 write_mchbar16(0x2ca8, 0x0);
4995
4996#if REAL
4997 udelay(1000);
4998 dump_timings(&info);
4999 if (!s3resume)
5000 save_timings(&info);
5001#endif
5002}
5003
5004#if REAL
5005unsigned long get_top_of_ram(void)
5006{
5007 /* Base of TSEG is top of usable DRAM */
5008 u32 tom = pci_read_config32(PCI_DEV(0, 0, 0), TSEG);
5009 return (unsigned long)tom;
5010}
5011#endif
5012
5013#if !REAL
5014int main(void)
5015{
5016 raminit(0);
5017 return 0;
5018}
5019#endif