blob: 581bf5f0178ba910badde386727f565d5acf6b39 [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 */
Kyösti Mälkki2d8520b2014-01-06 17:20:31 +02001702 cbmem_recovery(0);
Vladimir Serbinenkoc6f6be02013-11-12 22:32:08 +01001703 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
Vladimir Serbinenkoc6f6be02013-11-12 22:32:08 +01001993static void read_4090(struct raminfo *info)
1994{
1995 int i, channel, slot, rank, lane;
1996 for (i = 0; i < 2; i++)
1997 for (slot = 0; slot < NUM_SLOTS; slot++)
1998 for (rank = 0; rank < NUM_RANKS; rank++)
1999 for (lane = 0; lane < 9; lane++)
2000 info->training.
2001 lane_timings[0][i][slot][rank][lane]
2002 = 32;
2003
2004 for (i = 1; i < 4; i++)
2005 for (channel = 0; channel < NUM_CHANNELS; channel++)
2006 for (slot = 0; slot < NUM_SLOTS; slot++)
2007 for (rank = 0; rank < NUM_RANKS; rank++)
2008 for (lane = 0; lane < 9; lane++) {
2009 info->training.
2010 lane_timings[i][channel]
2011 [slot][rank][lane] =
2012 read_500(info, channel,
2013 get_timing_register_addr
2014 (lane, i, slot,
2015 rank), 9)
2016 + (i == 1) * 11; // !!!!
2017 }
2018
2019}
2020
2021static u32 get_etalon2(int flip, u32 addr)
2022{
2023 const u16 invmask[] = {
2024 0xaaaa, 0x6db6, 0x4924, 0xeeee, 0xcccc, 0x8888, 0x7bde, 0x739c,
2025 0x6318, 0x4210, 0xefbe, 0xcf3c, 0x8e38, 0x0c30, 0x0820
2026 };
2027 u32 ret;
2028 u32 comp4 = addr / 480;
2029 addr %= 480;
2030 u32 comp1 = addr & 0xf;
2031 u32 comp2 = (addr >> 4) & 1;
2032 u32 comp3 = addr >> 5;
2033
2034 if (comp4)
2035 ret = 0x1010101 << (comp4 - 1);
2036 else
2037 ret = 0;
2038 if (flip ^ (((invmask[comp3] >> comp1) ^ comp2) & 1))
2039 ret = ~ret;
2040
2041 return ret;
2042}
2043
2044static void disable_cache(void)
2045{
2046 msr_t msr = {.lo = 0, .hi = 0 };
2047
2048 wrmsr(MTRRphysBase_MSR(3), msr);
2049 wrmsr(MTRRphysMask_MSR(3), msr);
2050}
2051
2052static void enable_cache(unsigned int base, unsigned int size)
2053{
2054 msr_t msr;
2055 msr.lo = base | MTRR_TYPE_WRPROT;
2056 msr.hi = 0;
2057 wrmsr(MTRRphysBase_MSR(3), msr);
2058 msr.lo = ((~(ALIGN_DOWN(size + 4096, 4096) - 1) | MTRRdefTypeEn)
2059 & 0xffffffff);
2060 msr.hi = 0x0000000f;
2061 wrmsr(MTRRphysMask_MSR(3), msr);
2062}
2063
2064static void flush_cache(u32 start, u32 size)
2065{
2066 u32 end;
2067 u32 addr;
2068
2069 end = start + (ALIGN_DOWN(size + 4096, 4096));
2070 for (addr = start; addr < end; addr += 64)
2071 clflush(addr);
2072}
2073
2074static void clear_errors(void)
2075{
2076 pcie_write_config8(NORTHBRIDGE, 0xc0, 0x01);
2077}
2078
2079static void write_testing(struct raminfo *info, int totalrank, int flip)
2080{
2081 int nwrites = 0;
2082 /* in 8-byte units. */
2083 u32 offset;
2084 u32 base;
2085
2086 base = totalrank << 28;
2087 for (offset = 0; offset < 9 * 480; offset += 2) {
2088 write32(base + offset * 8, get_etalon2(flip, offset));
2089 write32(base + offset * 8 + 4, get_etalon2(flip, offset));
2090 write32(base + offset * 8 + 8, get_etalon2(flip, offset + 1));
2091 write32(base + offset * 8 + 12, get_etalon2(flip, offset + 1));
2092 nwrites += 4;
2093 if (nwrites >= 320) {
2094 clear_errors();
2095 nwrites = 0;
2096 }
2097 }
2098}
2099
2100static u8 check_testing(struct raminfo *info, u8 total_rank, int flip)
2101{
2102 u8 failmask = 0;
2103 int i;
2104 int comp1, comp2, comp3;
2105 u32 failxor[2] = { 0, 0 };
2106
2107 enable_cache((total_rank << 28), 1728 * 5 * 4);
2108
2109 for (comp3 = 0; comp3 < 9 && failmask != 0xff; comp3++) {
2110 for (comp1 = 0; comp1 < 4; comp1++)
2111 for (comp2 = 0; comp2 < 60; comp2++) {
2112 u32 re[4];
2113 u32 curroffset =
2114 comp3 * 8 * 60 + 2 * comp1 + 8 * comp2;
2115 read128((total_rank << 28) | (curroffset << 3),
2116 (u64 *) re);
2117 failxor[0] |=
2118 get_etalon2(flip, curroffset) ^ re[0];
2119 failxor[1] |=
2120 get_etalon2(flip, curroffset) ^ re[1];
2121 failxor[0] |=
2122 get_etalon2(flip, curroffset | 1) ^ re[2];
2123 failxor[1] |=
2124 get_etalon2(flip, curroffset | 1) ^ re[3];
2125 }
2126 for (i = 0; i < 8; i++)
2127 if ((0xff << (8 * (i % 4))) & failxor[i / 4])
2128 failmask |= 1 << i;
2129 }
2130 disable_cache();
2131 flush_cache((total_rank << 28), 1728 * 5 * 4);
2132 return failmask;
2133}
2134
2135const u32 seed1[0x18] = {
2136 0x3a9d5ab5, 0x576cb65b, 0x555773b6, 0x2ab772ee,
2137 0x555556ee, 0x3a9d5ab5, 0x576cb65b, 0x555773b6,
2138 0x2ab772ee, 0x555556ee, 0x5155a555, 0x5155a555,
2139 0x5155a555, 0x5155a555, 0x3a9d5ab5, 0x576cb65b,
2140 0x555773b6, 0x2ab772ee, 0x555556ee, 0x55d6b4a5,
2141 0x366d6b3a, 0x2ae5ddbb, 0x3b9ddbb7, 0x55d6b4a5,
2142};
2143
2144static u32 get_seed2(int a, int b)
2145{
2146 const u32 seed2[5] = {
2147 0x55555555, 0x33333333, 0x2e555a55, 0x55555555,
2148 0x5b6db6db,
2149 };
2150 u32 r;
2151 r = seed2[(a + (a >= 10)) / 5];
2152 return b ? ~r : r;
2153}
2154
2155static int make_shift(int comp2, int comp5, int x)
2156{
2157 const u8 seed3[32] = {
2158 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2159 0x00, 0x00, 0x38, 0x1c, 0x3c, 0x18, 0x38, 0x38,
2160 0x38, 0x38, 0x38, 0x38, 0x0f, 0x0f, 0x0f, 0x0f,
2161 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
2162 };
2163
2164 return (comp2 - ((seed3[comp5] >> (x & 7)) & 1)) & 0x1f;
2165}
2166
2167static u32 get_etalon(int flip, u32 addr)
2168{
2169 u32 mask_byte = 0;
2170 int comp1 = (addr >> 1) & 1;
2171 int comp2 = (addr >> 3) & 0x1f;
2172 int comp3 = (addr >> 8) & 0xf;
2173 int comp4 = (addr >> 12) & 0xf;
2174 int comp5 = (addr >> 16) & 0x1f;
2175 u32 mask_bit = ~(0x10001 << comp3);
2176 u32 part1;
2177 u32 part2;
2178 int byte;
2179
2180 part2 =
2181 ((seed1[comp5] >>
2182 make_shift(comp2, comp5,
2183 (comp3 >> 3) | (comp1 << 2) | 2)) & 1) ^ flip;
2184 part1 =
2185 ((seed1[comp5] >>
2186 make_shift(comp2, comp5,
2187 (comp3 >> 3) | (comp1 << 2) | 0)) & 1) ^ flip;
2188
2189 for (byte = 0; byte < 4; byte++)
2190 if ((get_seed2(comp5, comp4) >>
2191 make_shift(comp2, comp5, (byte | (comp1 << 2)))) & 1)
2192 mask_byte |= 0xff << (8 * byte);
2193
2194 return (mask_bit & mask_byte) | (part1 << comp3) | (part2 <<
2195 (comp3 + 16));
2196}
2197
2198static void
2199write_testing_type2(struct raminfo *info, u8 totalrank, u8 region, u8 block,
2200 char flip)
2201{
2202 int i;
2203 for (i = 0; i < 2048; i++)
2204 write32((totalrank << 28) | (region << 25) | (block << 16) |
2205 (i << 2), get_etalon(flip, (block << 16) | (i << 2)));
2206}
2207
2208static u8
2209check_testing_type2(struct raminfo *info, u8 totalrank, u8 region, u8 block,
2210 char flip)
2211{
2212 u8 failmask = 0;
2213 u32 failxor[2];
2214 int i;
2215 int comp1, comp2, comp3;
2216
2217 failxor[0] = 0;
2218 failxor[1] = 0;
2219
2220 enable_cache(totalrank << 28, 134217728);
2221 for (comp3 = 0; comp3 < 2 && failmask != 0xff; comp3++) {
2222 for (comp1 = 0; comp1 < 16; comp1++)
2223 for (comp2 = 0; comp2 < 64; comp2++) {
2224 u32 addr =
2225 (totalrank << 28) | (region << 25) | (block
2226 << 16)
2227 | (comp3 << 12) | (comp2 << 6) | (comp1 <<
2228 2);
2229 failxor[comp1 & 1] |=
2230 read32(addr) ^ get_etalon(flip, addr);
2231 }
2232 for (i = 0; i < 8; i++)
2233 if ((0xff << (8 * (i % 4))) & failxor[i / 4])
2234 failmask |= 1 << i;
2235 }
2236 disable_cache();
2237 flush_cache((totalrank << 28) | (region << 25) | (block << 16), 16384);
2238 return failmask;
2239}
2240
2241static int check_bounded(unsigned short *vals, u16 bound)
2242{
2243 int i;
2244
2245 for (i = 0; i < 8; i++)
2246 if (vals[i] < bound)
2247 return 0;
2248 return 1;
2249}
2250
2251enum state {
2252 BEFORE_USABLE = 0, AT_USABLE = 1, AT_MARGIN = 2, COMPLETE = 3
2253};
2254
2255static int validate_state(enum state *in)
2256{
2257 int i;
2258 for (i = 0; i < 8; i++)
2259 if (in[i] != COMPLETE)
2260 return 0;
2261 return 1;
2262}
2263
2264static void
2265do_fsm(enum state *state, u16 * counter,
2266 u8 fail_mask, int margin, int uplimit,
2267 u8 * res_low, u8 * res_high, u8 val)
2268{
2269 int lane;
2270
2271 for (lane = 0; lane < 8; lane++) {
2272 int is_fail = (fail_mask >> lane) & 1;
2273 switch (state[lane]) {
2274 case BEFORE_USABLE:
2275 if (!is_fail) {
2276 counter[lane] = 1;
2277 state[lane] = AT_USABLE;
2278 break;
2279 }
2280 counter[lane] = 0;
2281 state[lane] = BEFORE_USABLE;
2282 break;
2283 case AT_USABLE:
2284 if (!is_fail) {
2285 ++counter[lane];
2286 if (counter[lane] >= margin) {
2287 state[lane] = AT_MARGIN;
2288 res_low[lane] = val - margin + 1;
2289 break;
2290 }
2291 state[lane] = 1;
2292 break;
2293 }
2294 counter[lane] = 0;
2295 state[lane] = BEFORE_USABLE;
2296 break;
2297 case AT_MARGIN:
2298 if (is_fail) {
2299 state[lane] = COMPLETE;
2300 res_high[lane] = val - 1;
2301 } else {
2302 counter[lane]++;
2303 state[lane] = AT_MARGIN;
2304 if (val == uplimit) {
2305 state[lane] = COMPLETE;
2306 res_high[lane] = uplimit;
2307 }
2308 }
2309 break;
2310 case COMPLETE:
2311 break;
2312 }
2313 }
2314}
2315
2316static void
2317train_ram_at_178(struct raminfo *info, u8 channel, int slot, int rank,
2318 u8 total_rank, u8 reg_178, int first_run, int niter,
2319 timing_bounds_t * timings)
2320{
2321 int lane;
2322 enum state state[8];
2323 u16 count[8];
2324 u8 lower_usable[8];
2325 u8 upper_usable[8];
2326 unsigned short num_sucessfully_checked[8];
2327 u8 secondary_total_rank;
2328 u8 reg1b3;
2329
2330 if (info->populated_ranks_mask[1]) {
2331 if (channel == 1)
2332 secondary_total_rank =
2333 info->populated_ranks[1][0][0] +
2334 info->populated_ranks[1][0][1]
2335 + info->populated_ranks[1][1][0] +
2336 info->populated_ranks[1][1][1];
2337 else
2338 secondary_total_rank = 0;
2339 } else
2340 secondary_total_rank = total_rank;
2341
2342 {
2343 int i;
2344 for (i = 0; i < 8; i++)
2345 state[i] = BEFORE_USABLE;
2346 }
2347
2348 if (!first_run) {
2349 int is_all_ok = 1;
2350 for (lane = 0; lane < 8; lane++)
2351 if (timings[reg_178][channel][slot][rank][lane].
2352 smallest ==
2353 timings[reg_178][channel][slot][rank][lane].
2354 largest) {
2355 timings[reg_178][channel][slot][rank][lane].
2356 smallest = 0;
2357 timings[reg_178][channel][slot][rank][lane].
2358 largest = 0;
2359 is_all_ok = 0;
2360 }
2361 if (is_all_ok) {
2362 int i;
2363 for (i = 0; i < 8; i++)
2364 state[i] = COMPLETE;
2365 }
2366 }
2367
2368 for (reg1b3 = 0; reg1b3 < 0x30 && !validate_state(state); reg1b3++) {
2369 u8 failmask = 0;
2370 write_1d0(reg1b3 ^ 32, 0x1b3, 6, 1);
2371 write_1d0(reg1b3 ^ 32, 0x1a3, 6, 1);
2372 failmask = check_testing(info, total_rank, 0);
2373 write_mchbar32(0xfb0, read_mchbar32(0xfb0) | 0x00030000);
2374 do_fsm(state, count, failmask, 5, 47, lower_usable,
2375 upper_usable, reg1b3);
2376 }
2377
2378 if (reg1b3) {
2379 write_1d0(0, 0x1b3, 6, 1);
2380 write_1d0(0, 0x1a3, 6, 1);
2381 for (lane = 0; lane < 8; lane++) {
2382 if (state[lane] == COMPLETE) {
2383 timings[reg_178][channel][slot][rank][lane].
2384 smallest =
2385 lower_usable[lane] +
2386 (info->training.
2387 lane_timings[0][channel][slot][rank][lane]
2388 & 0x3F) - 32;
2389 timings[reg_178][channel][slot][rank][lane].
2390 largest =
2391 upper_usable[lane] +
2392 (info->training.
2393 lane_timings[0][channel][slot][rank][lane]
2394 & 0x3F) - 32;
2395 }
2396 }
2397 }
2398
2399 if (!first_run) {
2400 for (lane = 0; lane < 8; lane++)
2401 if (state[lane] == COMPLETE) {
2402 write_500(info, channel,
2403 timings[reg_178][channel][slot][rank]
2404 [lane].smallest,
2405 get_timing_register_addr(lane, 0,
2406 slot, rank),
2407 9, 1);
2408 write_500(info, channel,
2409 timings[reg_178][channel][slot][rank]
2410 [lane].smallest +
2411 info->training.
2412 lane_timings[1][channel][slot][rank]
2413 [lane]
2414 -
2415 info->training.
2416 lane_timings[0][channel][slot][rank]
2417 [lane], get_timing_register_addr(lane,
2418 1,
2419 slot,
2420 rank),
2421 9, 1);
2422 num_sucessfully_checked[lane] = 0;
2423 } else
2424 num_sucessfully_checked[lane] = -1;
2425
2426 do {
2427 u8 failmask = 0;
2428 int i;
2429 for (i = 0; i < niter; i++) {
2430 if (failmask == 0xFF)
2431 break;
2432 failmask |=
2433 check_testing_type2(info, total_rank, 2, i,
2434 0);
2435 failmask |=
2436 check_testing_type2(info, total_rank, 3, i,
2437 1);
2438 }
2439 write_mchbar32(0xfb0,
2440 read_mchbar32(0xfb0) | 0x00030000);
2441 for (lane = 0; lane < 8; lane++)
2442 if (num_sucessfully_checked[lane] != 0xffff) {
2443 if ((1 << lane) & failmask) {
2444 if (timings[reg_178][channel]
2445 [slot][rank][lane].
2446 largest <=
2447 timings[reg_178][channel]
2448 [slot][rank][lane].smallest)
2449 num_sucessfully_checked
2450 [lane] = -1;
2451 else {
2452 num_sucessfully_checked
2453 [lane] = 0;
2454 timings[reg_178]
2455 [channel][slot]
2456 [rank][lane].
2457 smallest++;
2458 write_500(info, channel,
2459 timings
2460 [reg_178]
2461 [channel]
2462 [slot][rank]
2463 [lane].
2464 smallest,
2465 get_timing_register_addr
2466 (lane, 0,
2467 slot, rank),
2468 9, 1);
2469 write_500(info, channel,
2470 timings
2471 [reg_178]
2472 [channel]
2473 [slot][rank]
2474 [lane].
2475 smallest +
2476 info->
2477 training.
2478 lane_timings
2479 [1][channel]
2480 [slot][rank]
2481 [lane]
2482 -
2483 info->
2484 training.
2485 lane_timings
2486 [0][channel]
2487 [slot][rank]
2488 [lane],
2489 get_timing_register_addr
2490 (lane, 1,
2491 slot, rank),
2492 9, 1);
2493 }
2494 } else
2495 num_sucessfully_checked[lane]++;
2496 }
2497 }
2498 while (!check_bounded(num_sucessfully_checked, 2));
2499
2500 for (lane = 0; lane < 8; lane++)
2501 if (state[lane] == COMPLETE) {
2502 write_500(info, channel,
2503 timings[reg_178][channel][slot][rank]
2504 [lane].largest,
2505 get_timing_register_addr(lane, 0,
2506 slot, rank),
2507 9, 1);
2508 write_500(info, channel,
2509 timings[reg_178][channel][slot][rank]
2510 [lane].largest +
2511 info->training.
2512 lane_timings[1][channel][slot][rank]
2513 [lane]
2514 -
2515 info->training.
2516 lane_timings[0][channel][slot][rank]
2517 [lane], get_timing_register_addr(lane,
2518 1,
2519 slot,
2520 rank),
2521 9, 1);
2522 num_sucessfully_checked[lane] = 0;
2523 } else
2524 num_sucessfully_checked[lane] = -1;
2525
2526 do {
2527 int failmask = 0;
2528 int i;
2529 for (i = 0; i < niter; i++) {
2530 if (failmask == 0xFF)
2531 break;
2532 failmask |=
2533 check_testing_type2(info, total_rank, 2, i,
2534 0);
2535 failmask |=
2536 check_testing_type2(info, total_rank, 3, i,
2537 1);
2538 }
2539
2540 write_mchbar32(0xfb0,
2541 read_mchbar32(0xfb0) | 0x00030000);
2542 for (lane = 0; lane < 8; lane++) {
2543 if (num_sucessfully_checked[lane] != 0xffff) {
2544 if ((1 << lane) & failmask) {
2545 if (timings[reg_178][channel]
2546 [slot][rank][lane].
2547 largest <=
2548 timings[reg_178][channel]
2549 [slot][rank][lane].
2550 smallest) {
2551 num_sucessfully_checked
2552 [lane] = -1;
2553 } else {
2554 num_sucessfully_checked
2555 [lane] = 0;
2556 timings[reg_178]
2557 [channel][slot]
2558 [rank][lane].
2559 largest--;
2560 write_500(info, channel,
2561 timings
2562 [reg_178]
2563 [channel]
2564 [slot][rank]
2565 [lane].
2566 largest,
2567 get_timing_register_addr
2568 (lane, 0,
2569 slot, rank),
2570 9, 1);
2571 write_500(info, channel,
2572 timings
2573 [reg_178]
2574 [channel]
2575 [slot][rank]
2576 [lane].
2577 largest +
2578 info->
2579 training.
2580 lane_timings
2581 [1][channel]
2582 [slot][rank]
2583 [lane]
2584 -
2585 info->
2586 training.
2587 lane_timings
2588 [0][channel]
2589 [slot][rank]
2590 [lane],
2591 get_timing_register_addr
2592 (lane, 1,
2593 slot, rank),
2594 9, 1);
2595 }
2596 } else
2597 num_sucessfully_checked[lane]++;
2598 }
2599 }
2600 }
2601 while (!check_bounded(num_sucessfully_checked, 3));
2602
2603 for (lane = 0; lane < 8; lane++) {
2604 write_500(info, channel,
2605 info->training.
2606 lane_timings[0][channel][slot][rank][lane],
2607 get_timing_register_addr(lane, 0, slot, rank),
2608 9, 1);
2609 write_500(info, channel,
2610 info->training.
2611 lane_timings[1][channel][slot][rank][lane],
2612 get_timing_register_addr(lane, 1, slot, rank),
2613 9, 1);
2614 if (timings[reg_178][channel][slot][rank][lane].
2615 largest <=
2616 timings[reg_178][channel][slot][rank][lane].
2617 smallest) {
2618 timings[reg_178][channel][slot][rank][lane].
2619 largest = 0;
2620 timings[reg_178][channel][slot][rank][lane].
2621 smallest = 0;
2622 }
2623 }
2624 }
2625}
2626
2627static void set_10b(struct raminfo *info, u8 val)
2628{
2629 int channel;
2630 int slot, rank;
2631 int lane;
2632
2633 if (read_1d0(0x10b, 6) == val)
2634 return;
2635
2636 write_1d0(val, 0x10b, 6, 1);
2637
2638 FOR_POPULATED_RANKS_BACKWARDS for (lane = 0; lane < 9; lane++) {
2639 u16 reg_500;
2640 reg_500 = read_500(info, channel,
2641 get_timing_register_addr(lane, 0, slot,
2642 rank), 9);
2643 if (val == 1) {
2644 if (lut16[info->clock_speed_index] <= reg_500)
2645 reg_500 -= lut16[info->clock_speed_index];
2646 else
2647 reg_500 = 0;
2648 } else {
2649 reg_500 += lut16[info->clock_speed_index];
2650 }
2651 write_500(info, channel, reg_500,
2652 get_timing_register_addr(lane, 0, slot, rank), 9, 1);
2653 }
2654}
2655
2656static void set_ecc(int onoff)
2657{
2658 int channel;
2659 for (channel = 0; channel < NUM_CHANNELS; channel++) {
2660 u8 t;
2661 t = read_mchbar8((channel << 10) + 0x5f8);
2662 if (onoff)
2663 t |= 1;
2664 else
2665 t &= ~1;
2666 write_mchbar8((channel << 10) + 0x5f8, t);
2667 }
2668}
2669
2670static void set_178(u8 val)
2671{
2672 if (val >= 31)
2673 val = val - 31;
2674 else
2675 val = 63 - val;
2676
2677 write_1d0(2 * val, 0x178, 7, 1);
2678}
2679
2680static void
2681write_500_timings_type(struct raminfo *info, int channel, int slot, int rank,
2682 int type)
2683{
2684 int lane;
2685
2686 for (lane = 0; lane < 8; lane++)
2687 write_500(info, channel,
2688 info->training.
2689 lane_timings[type][channel][slot][rank][lane],
2690 get_timing_register_addr(lane, type, slot, rank), 9,
2691 0);
2692}
2693
2694static void
2695try_timing_offsets(struct raminfo *info, int channel,
2696 int slot, int rank, int totalrank)
2697{
2698 u16 count[8];
2699 enum state state[8];
2700 u8 lower_usable[8], upper_usable[8];
2701 int lane;
2702 int i;
2703 int flip = 1;
2704 int timing_offset;
2705
2706 for (i = 0; i < 8; i++)
2707 state[i] = BEFORE_USABLE;
2708
2709 memset(count, 0, sizeof(count));
2710
2711 for (lane = 0; lane < 8; lane++)
2712 write_500(info, channel,
2713 info->training.
2714 lane_timings[2][channel][slot][rank][lane] + 32,
2715 get_timing_register_addr(lane, 3, slot, rank), 9, 1);
2716
2717 for (timing_offset = 0; !validate_state(state) && timing_offset < 64;
2718 timing_offset++) {
2719 u8 failmask;
2720 write_1d0(timing_offset ^ 32, 0x1bb, 6, 1);
2721 failmask = 0;
2722 for (i = 0; i < 2 && failmask != 0xff; i++) {
2723 flip = !flip;
2724 write_testing(info, totalrank, flip);
2725 failmask |= check_testing(info, totalrank, flip);
2726 }
2727 do_fsm(state, count, failmask, 10, 63, lower_usable,
2728 upper_usable, timing_offset);
2729 }
2730 write_1d0(0, 0x1bb, 6, 1);
2731 dump_timings(info);
2732 if (!validate_state(state))
2733 die("Couldn't discover DRAM timings (1)\n");
2734
2735 for (lane = 0; lane < 8; lane++) {
2736 u8 bias = 0;
2737
2738 if (info->silicon_revision) {
2739 int usable_length;
2740
2741 usable_length = upper_usable[lane] - lower_usable[lane];
2742 if (usable_length >= 20) {
2743 bias = usable_length / 2 - 10;
2744 if (bias >= 2)
2745 bias = 2;
2746 }
2747 }
2748 write_500(info, channel,
2749 info->training.
2750 lane_timings[2][channel][slot][rank][lane] +
2751 (upper_usable[lane] + lower_usable[lane]) / 2 - bias,
2752 get_timing_register_addr(lane, 3, slot, rank), 9, 1);
2753 info->training.timing2_bounds[channel][slot][rank][lane][0] =
2754 info->training.lane_timings[2][channel][slot][rank][lane] +
2755 lower_usable[lane];
2756 info->training.timing2_bounds[channel][slot][rank][lane][1] =
2757 info->training.lane_timings[2][channel][slot][rank][lane] +
2758 upper_usable[lane];
2759 info->training.timing2_offset[channel][slot][rank][lane] =
2760 info->training.lane_timings[2][channel][slot][rank][lane];
2761 }
2762}
2763
2764static u8
2765choose_training(struct raminfo *info, int channel, int slot, int rank,
2766 int lane, timing_bounds_t * timings, u8 center_178)
2767{
2768 u16 central_weight;
2769 u16 side_weight;
2770 unsigned int sum = 0, count = 0;
2771 u8 span;
2772 u8 lower_margin, upper_margin;
2773 u8 reg_178;
2774 u8 result;
2775
2776 span = 12;
2777 central_weight = 20;
2778 side_weight = 20;
2779 if (info->silicon_revision == 1 && channel == 1) {
2780 central_weight = 5;
2781 side_weight = 20;
2782 if ((info->
2783 populated_ranks_mask[1] ^ (info->
2784 populated_ranks_mask[1] >> 2)) &
2785 1)
2786 span = 18;
2787 }
2788 if ((info->populated_ranks_mask[0] & 5) == 5) {
2789 central_weight = 20;
2790 side_weight = 20;
2791 }
2792 if (info->clock_speed_index >= 2
2793 && (info->populated_ranks_mask[0] & 5) == 5 && slot == 1) {
2794 if (info->silicon_revision == 1) {
2795 switch (channel) {
2796 case 0:
2797 if (lane == 1) {
2798 central_weight = 10;
2799 side_weight = 20;
2800 }
2801 break;
2802 case 1:
2803 if (lane == 6) {
2804 side_weight = 5;
2805 central_weight = 20;
2806 }
2807 break;
2808 }
2809 }
2810 if (info->silicon_revision == 0 && channel == 0 && lane == 0) {
2811 side_weight = 5;
2812 central_weight = 20;
2813 }
2814 }
2815 for (reg_178 = center_178 - span; reg_178 <= center_178 + span;
2816 reg_178 += span) {
2817 u8 smallest;
2818 u8 largest;
2819 largest = timings[reg_178][channel][slot][rank][lane].largest;
2820 smallest = timings[reg_178][channel][slot][rank][lane].smallest;
2821 if (largest - smallest + 1 >= 5) {
2822 unsigned int weight;
2823 if (reg_178 == center_178)
2824 weight = central_weight;
2825 else
2826 weight = side_weight;
2827 sum += weight * (largest + smallest);
2828 count += weight;
2829 }
2830 }
2831 dump_timings(info);
2832 if (count == 0)
2833 die("Couldn't discover DRAM timings (2)\n");
2834 result = sum / (2 * count);
2835 lower_margin =
2836 result - timings[center_178][channel][slot][rank][lane].smallest;
2837 upper_margin =
2838 timings[center_178][channel][slot][rank][lane].largest - result;
2839 if (upper_margin < 10 && lower_margin > 10)
2840 result -= min(lower_margin - 10, 10 - upper_margin);
2841 if (upper_margin > 10 && lower_margin < 10)
2842 result += min(upper_margin - 10, 10 - lower_margin);
2843 return result;
2844}
2845
2846#define STANDARD_MIN_MARGIN 5
2847
2848static u8 choose_reg178(struct raminfo *info, timing_bounds_t * timings)
2849{
2850 u16 margin[64];
2851 int lane, rank, slot, channel;
2852 u8 reg178;
2853 int count = 0, sum = 0;
2854
2855 for (reg178 = reg178_min[info->clock_speed_index];
2856 reg178 < reg178_max[info->clock_speed_index];
2857 reg178 += reg178_step[info->clock_speed_index]) {
2858 margin[reg178] = -1;
2859 FOR_POPULATED_RANKS_BACKWARDS for (lane = 0; lane < 8; lane++) {
2860 int curmargin =
2861 timings[reg178][channel][slot][rank][lane].largest -
2862 timings[reg178][channel][slot][rank][lane].
2863 smallest + 1;
2864 if (curmargin < margin[reg178])
2865 margin[reg178] = curmargin;
2866 }
2867 if (margin[reg178] >= STANDARD_MIN_MARGIN) {
2868 u16 weight;
2869 weight = margin[reg178] - STANDARD_MIN_MARGIN;
2870 sum += weight * reg178;
2871 count += weight;
2872 }
2873 }
2874 dump_timings(info);
2875 if (count == 0)
2876 die("Couldn't discover DRAM timings (3)\n");
2877
2878 u8 threshold;
2879
2880 for (threshold = 30; threshold >= 5; threshold--) {
2881 int usable_length = 0;
2882 int smallest_fount = 0;
2883 for (reg178 = reg178_min[info->clock_speed_index];
2884 reg178 < reg178_max[info->clock_speed_index];
2885 reg178 += reg178_step[info->clock_speed_index])
2886 if (margin[reg178] >= threshold) {
2887 usable_length +=
2888 reg178_step[info->clock_speed_index];
2889 info->training.reg178_largest =
2890 reg178 -
2891 2 * reg178_step[info->clock_speed_index];
2892
2893 if (!smallest_fount) {
2894 smallest_fount = 1;
2895 info->training.reg178_smallest =
2896 reg178 +
2897 reg178_step[info->
2898 clock_speed_index];
2899 }
2900 }
2901 if (usable_length >= 0x21)
2902 break;
2903 }
2904
2905 return sum / count;
2906}
2907
2908static int check_cached_sanity(struct raminfo *info)
2909{
2910 int lane;
2911 int slot, rank;
2912 int channel;
2913
2914 if (!info->cached_training)
2915 return 0;
2916
2917 for (channel = 0; channel < NUM_CHANNELS; channel++)
2918 for (slot = 0; slot < NUM_SLOTS; slot++)
2919 for (rank = 0; rank < NUM_RANKS; rank++)
2920 for (lane = 0; lane < 8 + info->use_ecc; lane++) {
2921 u16 cached_value, estimation_value;
2922 cached_value =
2923 info->cached_training->
2924 lane_timings[1][channel][slot][rank]
2925 [lane];
2926 if (cached_value >= 0x18
2927 && cached_value <= 0x1E7) {
2928 estimation_value =
2929 info->training.
2930 lane_timings[1][channel]
2931 [slot][rank][lane];
2932 if (estimation_value <
2933 cached_value - 24)
2934 return 0;
2935 if (estimation_value >
2936 cached_value + 24)
2937 return 0;
2938 }
2939 }
2940 return 1;
2941}
2942
2943static int try_cached_training(struct raminfo *info)
2944{
2945 u8 saved_243[2];
2946 u8 tm;
2947
2948 int channel, slot, rank, lane;
2949 int flip = 1;
2950 int i, j;
2951
2952 if (!check_cached_sanity(info))
2953 return 0;
2954
2955 info->training.reg178_center = info->cached_training->reg178_center;
2956 info->training.reg178_smallest = info->cached_training->reg178_smallest;
2957 info->training.reg178_largest = info->cached_training->reg178_largest;
2958 memcpy(&info->training.timing_bounds,
2959 &info->cached_training->timing_bounds,
2960 sizeof(info->training.timing_bounds));
2961 memcpy(&info->training.timing_offset,
2962 &info->cached_training->timing_offset,
2963 sizeof(info->training.timing_offset));
2964
2965 write_1d0(2, 0x142, 3, 1);
2966 saved_243[0] = read_mchbar8(0x243);
2967 saved_243[1] = read_mchbar8(0x643);
2968 write_mchbar8(0x243, saved_243[0] | 2);
2969 write_mchbar8(0x643, saved_243[1] | 2);
2970 set_ecc(0);
2971 pcie_write_config16(NORTHBRIDGE, 0xc8, 3);
2972 if (read_1d0(0x10b, 6) & 1)
2973 set_10b(info, 0);
2974 for (tm = 0; tm < 2; tm++) {
2975 int totalrank;
2976
2977 set_178(tm ? info->cached_training->reg178_largest : info->
2978 cached_training->reg178_smallest);
2979
2980 totalrank = 0;
2981 /* Check timing ranges. With i == 0 we check smallest one and with
2982 i == 1 the largest bound. With j == 0 we check that on the bound
2983 it still works whereas with j == 1 we check that just outside of
2984 bound we fail.
2985 */
2986 FOR_POPULATED_RANKS_BACKWARDS {
2987 for (i = 0; i < 2; i++) {
2988 for (lane = 0; lane < 8; lane++) {
2989 write_500(info, channel,
2990 info->cached_training->
2991 timing2_bounds[channel][slot]
2992 [rank][lane][i],
2993 get_timing_register_addr(lane,
2994 3,
2995 slot,
2996 rank),
2997 9, 1);
2998
2999 if (!i)
3000 write_500(info, channel,
3001 info->
3002 cached_training->
3003 timing2_offset
3004 [channel][slot][rank]
3005 [lane],
3006 get_timing_register_addr
3007 (lane, 2, slot, rank),
3008 9, 1);
3009 write_500(info, channel,
3010 i ? info->cached_training->
3011 timing_bounds[tm][channel]
3012 [slot][rank][lane].
3013 largest : info->
3014 cached_training->
3015 timing_bounds[tm][channel]
3016 [slot][rank][lane].smallest,
3017 get_timing_register_addr(lane,
3018 0,
3019 slot,
3020 rank),
3021 9, 1);
3022 write_500(info, channel,
3023 info->cached_training->
3024 timing_offset[channel][slot]
3025 [rank][lane] +
3026 (i ? info->cached_training->
3027 timing_bounds[tm][channel]
3028 [slot][rank][lane].
3029 largest : info->
3030 cached_training->
3031 timing_bounds[tm][channel]
3032 [slot][rank][lane].
3033 smallest) - 64,
3034 get_timing_register_addr(lane,
3035 1,
3036 slot,
3037 rank),
3038 9, 1);
3039 }
3040 for (j = 0; j < 2; j++) {
3041 u8 failmask;
3042 u8 expected_failmask;
3043 char reg1b3;
3044
3045 reg1b3 = (j == 1) + 4;
3046 reg1b3 =
3047 j == i ? reg1b3 : (-reg1b3) & 0x3f;
3048 write_1d0(reg1b3, 0x1bb, 6, 1);
3049 write_1d0(reg1b3, 0x1b3, 6, 1);
3050 write_1d0(reg1b3, 0x1a3, 6, 1);
3051
3052 flip = !flip;
3053 write_testing(info, totalrank, flip);
3054 failmask =
3055 check_testing(info, totalrank,
3056 flip);
3057 expected_failmask =
3058 j == 0 ? 0x00 : 0xff;
3059 if (failmask != expected_failmask)
3060 goto fail;
3061 }
3062 }
3063 totalrank++;
3064 }
3065 }
3066
3067 set_178(info->cached_training->reg178_center);
3068 if (info->use_ecc)
3069 set_ecc(1);
3070 write_training_data(info);
3071 write_1d0(0, 322, 3, 1);
3072 info->training = *info->cached_training;
3073
3074 write_1d0(0, 0x1bb, 6, 1);
3075 write_1d0(0, 0x1b3, 6, 1);
3076 write_1d0(0, 0x1a3, 6, 1);
3077 write_mchbar8(0x243, saved_243[0]);
3078 write_mchbar8(0x643, saved_243[1]);
3079
3080 return 1;
3081
3082fail:
3083 FOR_POPULATED_RANKS {
3084 write_500_timings_type(info, channel, slot, rank, 1);
3085 write_500_timings_type(info, channel, slot, rank, 2);
3086 write_500_timings_type(info, channel, slot, rank, 3);
3087 }
3088
3089 write_1d0(0, 0x1bb, 6, 1);
3090 write_1d0(0, 0x1b3, 6, 1);
3091 write_1d0(0, 0x1a3, 6, 1);
3092 write_mchbar8(0x243, saved_243[0]);
3093 write_mchbar8(0x643, saved_243[1]);
3094
3095 return 0;
3096}
3097
3098static void do_ram_training(struct raminfo *info)
3099{
3100 u8 saved_243[2];
3101 int totalrank = 0;
3102 u8 reg_178;
3103 int niter;
3104
3105 timing_bounds_t timings[64];
3106 int lane, rank, slot, channel;
3107 u8 reg178_center;
3108
3109 write_1d0(2, 0x142, 3, 1);
3110 saved_243[0] = read_mchbar8(0x243);
3111 saved_243[1] = read_mchbar8(0x643);
3112 write_mchbar8(0x243, saved_243[0] | 2);
3113 write_mchbar8(0x643, saved_243[1] | 2);
3114 switch (info->clock_speed_index) {
3115 case 0:
3116 niter = 5;
3117 break;
3118 case 1:
3119 niter = 10;
3120 break;
3121 default:
3122 niter = 19;
3123 break;
3124 }
3125 set_ecc(0);
3126
3127 FOR_POPULATED_RANKS_BACKWARDS {
3128 int i;
3129
3130 write_500_timings_type(info, channel, slot, rank, 0);
3131
3132 write_testing(info, totalrank, 0);
3133 for (i = 0; i < niter; i++) {
3134 write_testing_type2(info, totalrank, 2, i, 0);
3135 write_testing_type2(info, totalrank, 3, i, 1);
3136 }
3137 pcie_write_config8(NORTHBRIDGE, 0xc0, 0x01);
3138 totalrank++;
3139 }
3140
3141 if (reg178_min[info->clock_speed_index] <
3142 reg178_max[info->clock_speed_index])
3143 memset(timings[reg178_min[info->clock_speed_index]], 0,
3144 sizeof(timings[0]) *
3145 (reg178_max[info->clock_speed_index] -
3146 reg178_min[info->clock_speed_index]));
3147 for (reg_178 = reg178_min[info->clock_speed_index];
3148 reg_178 < reg178_max[info->clock_speed_index];
3149 reg_178 += reg178_step[info->clock_speed_index]) {
3150 totalrank = 0;
3151 set_178(reg_178);
3152 for (channel = NUM_CHANNELS - 1; channel >= 0; channel--)
3153 for (slot = 0; slot < NUM_SLOTS; slot++)
3154 for (rank = 0; rank < NUM_RANKS; rank++) {
3155 memset(&timings[reg_178][channel][slot]
3156 [rank][0].smallest, 0, 16);
3157 if (info->
3158 populated_ranks[channel][slot]
3159 [rank]) {
3160 train_ram_at_178(info, channel,
3161 slot, rank,
3162 totalrank,
3163 reg_178, 1,
3164 niter,
3165 timings);
3166 totalrank++;
3167 }
3168 }
3169 }
3170
3171 reg178_center = choose_reg178(info, timings);
3172
3173 FOR_POPULATED_RANKS_BACKWARDS for (lane = 0; lane < 8; lane++) {
3174 info->training.timing_bounds[0][channel][slot][rank][lane].
3175 smallest =
3176 timings[info->training.
3177 reg178_smallest][channel][slot][rank][lane].
3178 smallest;
3179 info->training.timing_bounds[0][channel][slot][rank][lane].
3180 largest =
3181 timings[info->training.
3182 reg178_smallest][channel][slot][rank][lane].largest;
3183 info->training.timing_bounds[1][channel][slot][rank][lane].
3184 smallest =
3185 timings[info->training.
3186 reg178_largest][channel][slot][rank][lane].smallest;
3187 info->training.timing_bounds[1][channel][slot][rank][lane].
3188 largest =
3189 timings[info->training.
3190 reg178_largest][channel][slot][rank][lane].largest;
3191 info->training.timing_offset[channel][slot][rank][lane] =
3192 info->training.lane_timings[1][channel][slot][rank][lane]
3193 -
3194 info->training.lane_timings[0][channel][slot][rank][lane] +
3195 64;
3196 }
3197
3198 if (info->silicon_revision == 1
3199 && (info->
3200 populated_ranks_mask[1] ^ (info->
3201 populated_ranks_mask[1] >> 2)) & 1) {
3202 int ranks_after_channel1;
3203
3204 totalrank = 0;
3205 for (reg_178 = reg178_center - 18;
3206 reg_178 <= reg178_center + 18; reg_178 += 18) {
3207 totalrank = 0;
3208 set_178(reg_178);
3209 for (slot = 0; slot < NUM_SLOTS; slot++)
3210 for (rank = 0; rank < NUM_RANKS; rank++) {
3211 if (info->
3212 populated_ranks[1][slot][rank]) {
3213 train_ram_at_178(info, 1, slot,
3214 rank,
3215 totalrank,
3216 reg_178, 0,
3217 niter,
3218 timings);
3219 totalrank++;
3220 }
3221 }
3222 }
3223 ranks_after_channel1 = totalrank;
3224
3225 for (reg_178 = reg178_center - 12;
3226 reg_178 <= reg178_center + 12; reg_178 += 12) {
3227 totalrank = ranks_after_channel1;
3228 set_178(reg_178);
3229 for (slot = 0; slot < NUM_SLOTS; slot++)
3230 for (rank = 0; rank < NUM_RANKS; rank++)
3231 if (info->
3232 populated_ranks[0][slot][rank]) {
3233 train_ram_at_178(info, 0, slot,
3234 rank,
3235 totalrank,
3236 reg_178, 0,
3237 niter,
3238 timings);
3239 totalrank++;
3240 }
3241
3242 }
3243 } else {
3244 for (reg_178 = reg178_center - 12;
3245 reg_178 <= reg178_center + 12; reg_178 += 12) {
3246 totalrank = 0;
3247 set_178(reg_178);
3248 FOR_POPULATED_RANKS_BACKWARDS {
3249 train_ram_at_178(info, channel, slot, rank,
3250 totalrank, reg_178, 0, niter,
3251 timings);
3252 totalrank++;
3253 }
3254 }
3255 }
3256
3257 set_178(reg178_center);
3258 FOR_POPULATED_RANKS_BACKWARDS for (lane = 0; lane < 8; lane++) {
3259 u16 tm0;
3260
3261 tm0 =
3262 choose_training(info, channel, slot, rank, lane, timings,
3263 reg178_center);
3264 write_500(info, channel, tm0,
3265 get_timing_register_addr(lane, 0, slot, rank), 9, 1);
3266 write_500(info, channel,
3267 tm0 +
3268 info->training.
3269 lane_timings[1][channel][slot][rank][lane] -
3270 info->training.
3271 lane_timings[0][channel][slot][rank][lane],
3272 get_timing_register_addr(lane, 1, slot, rank), 9, 1);
3273 }
3274
3275 totalrank = 0;
3276 FOR_POPULATED_RANKS_BACKWARDS {
3277 try_timing_offsets(info, channel, slot, rank, totalrank);
3278 totalrank++;
3279 }
3280 write_mchbar8(0x243, saved_243[0]);
3281 write_mchbar8(0x643, saved_243[1]);
3282 write_1d0(0, 0x142, 3, 1);
3283 info->training.reg178_center = reg178_center;
3284}
3285
3286static void ram_training(struct raminfo *info)
3287{
3288 u16 saved_fc4;
3289
3290 saved_fc4 = read_mchbar16(0xfc4);
3291 write_mchbar16(0xfc4, 0xffff);
3292
3293 if (info->revision >= 8)
3294 read_4090(info);
3295
3296 if (!try_cached_training(info))
3297 do_ram_training(info);
3298 if ((info->silicon_revision == 2 || info->silicon_revision == 3)
3299 && info->clock_speed_index < 2)
3300 set_10b(info, 1);
3301 write_mchbar16(0xfc4, saved_fc4);
3302}
3303
3304static unsigned gcd(unsigned a, unsigned b)
3305{
3306 unsigned t;
3307 if (a > b) {
3308 t = a;
3309 a = b;
3310 b = t;
3311 }
3312 /* invariant a < b. */
3313 while (a) {
3314 t = b % a;
3315 b = a;
3316 a = t;
3317 }
3318 return b;
3319}
3320
3321static inline int div_roundup(int a, int b)
3322{
3323 return (a + b - 1) / b;
3324}
3325
3326static unsigned lcm(unsigned a, unsigned b)
3327{
3328 return (a * b) / gcd(a, b);
3329}
3330
3331struct stru1 {
3332 u8 freqs_reversed;
3333 u8 freq_diff_reduced;
3334 u8 freq_min_reduced;
3335 u8 divisor_f4_to_fmax;
3336 u8 divisor_f3_to_fmax;
3337 u8 freq4_to_max_remainder;
3338 u8 freq3_to_2_remainder;
3339 u8 freq3_to_2_remaindera;
3340 u8 freq4_to_2_remainder;
3341 int divisor_f3_to_f1, divisor_f4_to_f2;
3342 int common_time_unit_ps;
3343 int freq_max_reduced;
3344};
3345
3346static void
3347compute_frequence_ratios(struct raminfo *info, u16 freq1, u16 freq2,
3348 int num_cycles_2, int num_cycles_1, int round_it,
3349 int add_freqs, struct stru1 *result)
3350{
3351 int g;
3352 int common_time_unit_ps;
3353 int freq1_reduced, freq2_reduced;
3354 int freq_min_reduced;
3355 int freq_max_reduced;
3356 int freq3, freq4;
3357
3358 g = gcd(freq1, freq2);
3359 freq1_reduced = freq1 / g;
3360 freq2_reduced = freq2 / g;
3361 freq_min_reduced = min(freq1_reduced, freq2_reduced);
3362 freq_max_reduced = max(freq1_reduced, freq2_reduced);
3363
3364 common_time_unit_ps = div_roundup(900000, lcm(freq1, freq2));
3365 freq3 = div_roundup(num_cycles_2, common_time_unit_ps) - 1;
3366 freq4 = div_roundup(num_cycles_1, common_time_unit_ps) - 1;
3367 if (add_freqs) {
3368 freq3 += freq2_reduced;
3369 freq4 += freq1_reduced;
3370 }
3371
3372 if (round_it) {
3373 result->freq3_to_2_remainder = 0;
3374 result->freq3_to_2_remaindera = 0;
3375 result->freq4_to_max_remainder = 0;
3376 result->divisor_f4_to_f2 = 0;
3377 result->divisor_f3_to_f1 = 0;
3378 } else {
3379 if (freq2_reduced < freq1_reduced) {
3380 result->freq3_to_2_remainder =
3381 result->freq3_to_2_remaindera =
3382 freq3 % freq1_reduced - freq1_reduced + 1;
3383 result->freq4_to_max_remainder =
3384 -(freq4 % freq1_reduced);
3385 result->divisor_f3_to_f1 = freq3 / freq1_reduced;
3386 result->divisor_f4_to_f2 =
3387 (freq4 -
3388 (freq1_reduced - freq2_reduced)) / freq2_reduced;
3389 result->freq4_to_2_remainder =
3390 -(char)((freq1_reduced - freq2_reduced) +
3391 ((u8) freq4 -
3392 (freq1_reduced -
3393 freq2_reduced)) % (u8) freq2_reduced);
3394 } else {
3395 if (freq2_reduced > freq1_reduced) {
3396 result->freq4_to_max_remainder =
3397 (freq4 % freq2_reduced) - freq2_reduced + 1;
3398 result->freq4_to_2_remainder =
3399 freq4 % freq_max_reduced -
3400 freq_max_reduced + 1;
3401 } else {
3402 result->freq4_to_max_remainder =
3403 -(freq4 % freq2_reduced);
3404 result->freq4_to_2_remainder =
3405 -(char)(freq4 % freq_max_reduced);
3406 }
3407 result->divisor_f4_to_f2 = freq4 / freq2_reduced;
3408 result->divisor_f3_to_f1 =
3409 (freq3 -
3410 (freq2_reduced - freq1_reduced)) / freq1_reduced;
3411 result->freq3_to_2_remainder = -(freq3 % freq2_reduced);
3412 result->freq3_to_2_remaindera =
3413 -(char)((freq_max_reduced - freq_min_reduced) +
3414 (freq3 -
3415 (freq_max_reduced -
3416 freq_min_reduced)) % freq1_reduced);
3417 }
3418 }
3419 result->divisor_f3_to_fmax = freq3 / freq_max_reduced;
3420 result->divisor_f4_to_fmax = freq4 / freq_max_reduced;
3421 if (round_it) {
3422 if (freq2_reduced > freq1_reduced) {
3423 if (freq3 % freq_max_reduced)
3424 result->divisor_f3_to_fmax++;
3425 }
3426 if (freq2_reduced < freq1_reduced) {
3427 if (freq4 % freq_max_reduced)
3428 result->divisor_f4_to_fmax++;
3429 }
3430 }
3431 result->freqs_reversed = (freq2_reduced < freq1_reduced);
3432 result->freq_diff_reduced = freq_max_reduced - freq_min_reduced;
3433 result->freq_min_reduced = freq_min_reduced;
3434 result->common_time_unit_ps = common_time_unit_ps;
3435 result->freq_max_reduced = freq_max_reduced;
3436}
3437
3438static void
3439set_2d5x_reg(struct raminfo *info, u16 reg, u16 freq1, u16 freq2,
3440 int num_cycles_2, int num_cycles_1, int num_cycles_3,
3441 int num_cycles_4, int reverse)
3442{
3443 struct stru1 vv;
3444 char multiplier;
3445
3446 compute_frequence_ratios(info, freq1, freq2, num_cycles_2, num_cycles_1,
3447 0, 1, &vv);
3448
3449 multiplier =
3450 div_roundup(max
3451 (div_roundup(num_cycles_2, vv.common_time_unit_ps) +
3452 div_roundup(num_cycles_3, vv.common_time_unit_ps),
3453 div_roundup(num_cycles_1,
3454 vv.common_time_unit_ps) +
3455 div_roundup(num_cycles_4, vv.common_time_unit_ps))
3456 + vv.freq_min_reduced - 1, vv.freq_max_reduced) - 1;
3457
3458 u32 y =
3459 (u8) ((vv.freq_max_reduced - vv.freq_min_reduced) +
3460 vv.freq_max_reduced * multiplier)
3461 | (vv.
3462 freqs_reversed << 8) | ((u8) (vv.freq_min_reduced *
3463 multiplier) << 16) | ((u8) (vv.
3464 freq_min_reduced
3465 *
3466 multiplier)
3467 << 24);
3468 u32 x =
3469 vv.freq3_to_2_remaindera | (vv.freq4_to_2_remainder << 8) | (vv.
3470 divisor_f3_to_f1
3471 << 16)
3472 | (vv.divisor_f4_to_f2 << 20) | (vv.freq_min_reduced << 24);
3473 if (reverse) {
3474 write_mchbar32(reg, y);
3475 write_mchbar32(reg + 4, x);
3476 } else {
3477 write_mchbar32(reg + 4, y);
3478 write_mchbar32(reg, x);
3479 }
3480}
3481
3482static void
3483set_6d_reg(struct raminfo *info, u16 reg, u16 freq1, u16 freq2,
3484 int num_cycles_1, int num_cycles_2, int num_cycles_3,
3485 int num_cycles_4)
3486{
3487 struct stru1 ratios1;
3488 struct stru1 ratios2;
3489
3490 compute_frequence_ratios(info, freq1, freq2, num_cycles_1, num_cycles_2,
3491 0, 1, &ratios2);
3492 compute_frequence_ratios(info, freq1, freq2, num_cycles_3, num_cycles_4,
3493 0, 1, &ratios1);
3494 write_mchbar32(reg,
3495 ratios1.freq4_to_max_remainder | (ratios2.
3496 freq4_to_max_remainder
3497 << 8)
3498 | (ratios1.divisor_f4_to_fmax << 16) | (ratios2.
3499 divisor_f4_to_fmax
3500 << 20));
3501}
3502
3503static void
3504set_2dx8_reg(struct raminfo *info, u16 reg, u8 mode, u16 freq1, u16 freq2,
3505 int num_cycles_2, int num_cycles_1, int round_it, int add_freqs)
3506{
3507 struct stru1 ratios;
3508
3509 compute_frequence_ratios(info, freq1, freq2, num_cycles_2, num_cycles_1,
3510 round_it, add_freqs, &ratios);
3511 switch (mode) {
3512 case 0:
3513 write_mchbar32(reg + 4,
3514 ratios.freq_diff_reduced | (ratios.
3515 freqs_reversed <<
3516 8));
3517 write_mchbar32(reg,
3518 ratios.freq3_to_2_remainder | (ratios.
3519 freq4_to_max_remainder
3520 << 8)
3521 | (ratios.divisor_f3_to_fmax << 16) | (ratios.
3522 divisor_f4_to_fmax
3523 << 20) |
3524 (ratios.freq_min_reduced << 24));
3525 break;
3526
3527 case 1:
3528 write_mchbar32(reg,
3529 ratios.freq3_to_2_remainder | (ratios.
3530 divisor_f3_to_fmax
3531 << 16));
3532 break;
3533
3534 case 2:
3535 write_mchbar32(reg,
3536 ratios.freq3_to_2_remainder | (ratios.
3537 freq4_to_max_remainder
3538 << 8) | (ratios.
3539 divisor_f3_to_fmax
3540 << 16) |
3541 (ratios.divisor_f4_to_fmax << 20));
3542 break;
3543
3544 case 4:
3545 write_mchbar32(reg, (ratios.divisor_f3_to_fmax << 4)
3546 | (ratios.divisor_f4_to_fmax << 8) | (ratios.
3547 freqs_reversed
3548 << 12) |
3549 (ratios.freq_min_reduced << 16) | (ratios.
3550 freq_diff_reduced
3551 << 24));
3552 break;
3553 }
3554}
3555
3556static void set_2dxx_series(struct raminfo *info)
3557{
3558 set_2dx8_reg(info, 0x2d00, 0, 0x78, frequency_11(info) / 2, 1359, 1005,
3559 0, 1);
3560 set_2dx8_reg(info, 0x2d08, 0, 0x78, 0x78, 3273, 5033, 1, 1);
3561 set_2dx8_reg(info, 0x2d10, 0, 0x78, info->fsb_frequency, 1475, 1131, 0,
3562 1);
3563 set_2dx8_reg(info, 0x2d18, 0, 2 * info->fsb_frequency,
3564 frequency_11(info), 1231, 1524, 0, 1);
3565 set_2dx8_reg(info, 0x2d20, 0, 2 * info->fsb_frequency,
3566 frequency_11(info) / 2, 1278, 2008, 0, 1);
3567 set_2dx8_reg(info, 0x2d28, 0, info->fsb_frequency, frequency_11(info),
3568 1167, 1539, 0, 1);
3569 set_2dx8_reg(info, 0x2d30, 0, info->fsb_frequency,
3570 frequency_11(info) / 2, 1403, 1318, 0, 1);
3571 set_2dx8_reg(info, 0x2d38, 0, info->fsb_frequency, 0x78, 3460, 5363, 1,
3572 1);
3573 set_2dx8_reg(info, 0x2d40, 0, info->fsb_frequency, 0x3c, 2792, 5178, 1,
3574 1);
3575 set_2dx8_reg(info, 0x2d48, 0, 2 * info->fsb_frequency, 0x78, 2738, 4610,
3576 1, 1);
3577 set_2dx8_reg(info, 0x2d50, 0, info->fsb_frequency, 0x78, 2819, 5932, 1,
3578 1);
3579 set_2dx8_reg(info, 0x6d4, 1, info->fsb_frequency,
3580 frequency_11(info) / 2, 4000, 0, 0, 0);
3581 set_2dx8_reg(info, 0x6d8, 2, info->fsb_frequency,
3582 frequency_11(info) / 2, 4000, 4000, 0, 0);
3583
3584 set_6d_reg(info, 0x6dc, 2 * info->fsb_frequency, frequency_11(info), 0,
3585 info->delay46_ps[0], 0, info->delay54_ps[0]);
3586 set_2dx8_reg(info, 0x6e0, 1, 2 * info->fsb_frequency,
3587 frequency_11(info), 2500, 0, 0, 0);
3588 set_2dx8_reg(info, 0x6e4, 1, 2 * info->fsb_frequency,
3589 frequency_11(info) / 2, 3500, 0, 0, 0);
3590 set_6d_reg(info, 0x6e8, 2 * info->fsb_frequency, frequency_11(info), 0,
3591 info->delay46_ps[1], 0, info->delay54_ps[1]);
3592 set_2d5x_reg(info, 0x2d58, 0x78, 0x78, 864, 1195, 762, 786, 0);
3593 set_2d5x_reg(info, 0x2d60, 0x195, info->fsb_frequency, 1352, 725, 455,
3594 470, 0);
3595 set_2d5x_reg(info, 0x2d68, 0x195, 0x3c, 2707, 5632, 3277, 2207, 0);
3596 set_2d5x_reg(info, 0x2d70, 0x195, frequency_11(info) / 2, 1276, 758,
3597 454, 459, 0);
3598 set_2d5x_reg(info, 0x2d78, 0x195, 0x78, 1021, 799, 510, 513, 0);
3599 set_2d5x_reg(info, 0x2d80, info->fsb_frequency, 0xe1, 0, 2862, 2579,
3600 2588, 0);
3601 set_2d5x_reg(info, 0x2d88, info->fsb_frequency, 0xe1, 0, 2690, 2405,
3602 2405, 0);
3603 set_2d5x_reg(info, 0x2da0, 0x78, 0xe1, 0, 2560, 2264, 2251, 0);
3604 set_2d5x_reg(info, 0x2da8, 0x195, frequency_11(info), 1060, 775, 484,
3605 480, 0);
3606 set_2d5x_reg(info, 0x2db0, 0x195, 0x78, 4183, 6023, 2217, 2048, 0);
3607 write_mchbar32(0x2dbc, ((frequency_11(info) / 2) - 1) | 0xe00000);
3608 write_mchbar32(0x2db8, ((info->fsb_frequency - 1) << 16) | 0x77);
3609}
3610
3611static u16 get_max_timing(struct raminfo *info, int channel)
3612{
3613 int slot, rank, lane;
3614 u16 ret = 0;
3615
3616 if ((read_mchbar8(0x2ca8) >> 2) < 1)
3617 return 384;
3618
3619 if (info->revision < 8)
3620 return 256;
3621
3622 for (slot = 0; slot < NUM_SLOTS; slot++)
3623 for (rank = 0; rank < NUM_RANKS; rank++)
3624 if (info->populated_ranks[channel][slot][rank])
3625 for (lane = 0; lane < 8 + info->use_ecc; lane++)
3626 ret = max(ret, read_500(info, channel,
3627 get_timing_register_addr
3628 (lane, 0, slot,
3629 rank), 9));
3630 return ret;
3631}
3632
3633static void set_274265(struct raminfo *info)
3634{
3635 int delay_a_ps, delay_b_ps, delay_c_ps, delay_d_ps;
3636 int delay_e_ps, delay_e_cycles, delay_f_cycles;
3637 int delay_e_over_cycle_ps;
3638 int cycletime_ps;
3639 int channel;
3640
3641 delay_a_ps = 4 * halfcycle_ps(info) + 6 * fsbcycle_ps(info);
3642 info->reg2ca9_bit0 = 0;
3643 for (channel = 0; channel < NUM_CHANNELS; channel++) {
3644 cycletime_ps =
3645 900000 / lcm(2 * info->fsb_frequency, frequency_11(info));
3646 delay_d_ps =
3647 (halfcycle_ps(info) * get_max_timing(info, channel) >> 6)
3648 - info->some_delay_3_ps_rounded + 200;
3649 if (!
3650 ((info->silicon_revision == 0
3651 || info->silicon_revision == 1)
3652 && (info->revision >= 8)))
3653 delay_d_ps += halfcycle_ps(info) * 2;
3654 delay_d_ps +=
3655 halfcycle_ps(info) * (!info->revision_flag_1 +
3656 info->some_delay_2_halfcycles_ceil +
3657 2 * info->some_delay_1_cycle_floor +
3658 info->clock_speed_index +
3659 2 * info->cas_latency - 7 + 11);
3660 delay_d_ps += info->revision >= 8 ? 2758 : 4428;
3661
3662 write_mchbar32(0x140,
3663 (read_mchbar32(0x140) & 0xfaffffff) | 0x2000000);
3664 write_mchbar32(0x138,
3665 (read_mchbar32(0x138) & 0xfaffffff) | 0x2000000);
3666 if ((read_mchbar8(0x144) & 0x1f) > 0x13)
3667 delay_d_ps += 650;
3668 delay_c_ps = delay_d_ps + 1800;
3669 if (delay_c_ps <= delay_a_ps)
3670 delay_e_ps = 0;
3671 else
3672 delay_e_ps =
3673 cycletime_ps * div_roundup(delay_c_ps - delay_a_ps,
3674 cycletime_ps);
3675
3676 delay_e_over_cycle_ps = delay_e_ps % (2 * halfcycle_ps(info));
3677 delay_e_cycles = delay_e_ps / (2 * halfcycle_ps(info));
3678 delay_f_cycles =
3679 div_roundup(2500 - delay_e_over_cycle_ps,
3680 2 * halfcycle_ps(info));
3681 if (delay_f_cycles > delay_e_cycles) {
3682 info->delay46_ps[channel] = delay_e_ps;
3683 delay_e_cycles = 0;
3684 } else {
3685 info->delay46_ps[channel] =
3686 delay_e_over_cycle_ps +
3687 2 * halfcycle_ps(info) * delay_f_cycles;
3688 delay_e_cycles -= delay_f_cycles;
3689 }
3690
3691 if (info->delay46_ps[channel] < 2500) {
3692 info->delay46_ps[channel] = 2500;
3693 info->reg2ca9_bit0 = 1;
3694 }
3695 delay_b_ps = halfcycle_ps(info) + delay_c_ps;
3696 if (delay_b_ps <= delay_a_ps)
3697 delay_b_ps = 0;
3698 else
3699 delay_b_ps -= delay_a_ps;
3700 info->delay54_ps[channel] =
3701 cycletime_ps * div_roundup(delay_b_ps,
3702 cycletime_ps) -
3703 2 * halfcycle_ps(info) * delay_e_cycles;
3704 if (info->delay54_ps[channel] < 2500)
3705 info->delay54_ps[channel] = 2500;
3706 info->reg274265[channel][0] = delay_e_cycles;
3707 if (delay_d_ps + 7 * halfcycle_ps(info) <=
3708 24 * halfcycle_ps(info))
3709 info->reg274265[channel][1] = 0;
3710 else
3711 info->reg274265[channel][1] =
3712 div_roundup(delay_d_ps + 7 * halfcycle_ps(info),
3713 4 * halfcycle_ps(info)) - 6;
3714 write_mchbar32((channel << 10) + 0x274,
3715 info->reg274265[channel][1] | (info->
3716 reg274265[channel]
3717 [0] << 16));
3718 info->reg274265[channel][2] =
3719 div_roundup(delay_c_ps + 3 * fsbcycle_ps(info),
3720 4 * halfcycle_ps(info)) + 1;
3721 write_mchbar16((channel << 10) + 0x265,
3722 info->reg274265[channel][2] << 8);
3723 }
3724 if (info->reg2ca9_bit0)
3725 write_mchbar8(0x2ca9, read_mchbar8(0x2ca9) | 1);
3726 else
3727 write_mchbar8(0x2ca9, read_mchbar8(0x2ca9) & ~1);
3728}
3729
3730static void restore_274265(struct raminfo *info)
3731{
3732 int channel;
3733
3734 for (channel = 0; channel < NUM_CHANNELS; channel++) {
3735 write_mchbar32((channel << 10) + 0x274,
3736 (info->reg274265[channel][0] << 16) | info->
3737 reg274265[channel][1]);
3738 write_mchbar16((channel << 10) + 0x265,
3739 info->reg274265[channel][2] << 8);
3740 }
3741 if (info->reg2ca9_bit0)
3742 write_mchbar8(0x2ca9, read_mchbar8(0x2ca9) | 1);
3743 else
3744 write_mchbar8(0x2ca9, read_mchbar8(0x2ca9) & ~1);
3745}
3746
3747#if REAL
3748static void dmi_setup(void)
3749{
3750 gav(read8(DEFAULT_DMIBAR | 0x254));
3751 write8(DEFAULT_DMIBAR | 0x254, 0x1);
3752 write16(DEFAULT_DMIBAR | 0x1b8, 0x18f2);
3753 read_mchbar16(0x48);
3754 write_mchbar16(0x48, 0x2);
3755
3756 write32(DEFAULT_DMIBAR | 0xd68, read32(DEFAULT_DMIBAR | 0xd68) | 0x08000000);
3757
3758 outl((gav(inl(DEFAULT_GPIOBASE | 0x38)) & ~0x140000) | 0x400000,
3759 DEFAULT_GPIOBASE | 0x38);
3760 gav(inb(DEFAULT_GPIOBASE | 0xe)); // = 0xfdcaff6e
3761}
3762#endif
3763
Vladimir Serbinenkof62669c2014-01-09 10:59:38 +01003764#if REAL
Vladimir Serbinenkoc6f6be02013-11-12 22:32:08 +01003765static void
3766set_fsb_frequency (void)
3767{
3768 u8 block[5];
3769 u16 fsbfreq = 62879;
3770 smbus_block_read(0x69, 0, 5, block);
3771 block[0] = fsbfreq;
3772 block[1] = fsbfreq >> 8;
3773
3774 smbus_block_write(0x69, 0, 5, block);
3775}
Vladimir Serbinenkoc6f6be02013-11-12 22:32:08 +01003776#endif
Vladimir Serbinenkof62669c2014-01-09 10:59:38 +01003777
3778void raminit(const int s3resume)
Vladimir Serbinenkoc6f6be02013-11-12 22:32:08 +01003779{
3780 unsigned channel, slot, lane, rank;
3781 int i;
3782 struct raminfo info;
Vladimir Serbinenkoc6f6be02013-11-12 22:32:08 +01003783 if (s3resume) {
3784 read_mchbar32(0x1e8);
3785 write_mchbar32(0x1e8, 0x6);
3786 read_mchbar32(0x1e8);
3787 write_mchbar32(0x1e8, 0x4);
3788 }
3789
Vladimir Serbinenkoc6f6be02013-11-12 22:32:08 +01003790 u8 x2ca8;
3791
3792 gav(x2ca8 = read_mchbar8(0x2ca8));
3793 if ((x2ca8 & 1) || (x2ca8 == 8 && !s3resume)) {
3794 printk(BIOS_DEBUG, "soft reset detected, rebooting properly\n");
3795 write_mchbar8(0x2ca8, 0);
3796 outb(0xe, 0xcf9);
3797#if REAL
3798 while (1) {
3799 asm volatile ("hlt");
3800 }
3801#else
3802 printf("CP5\n");
3803 exit(0);
3804#endif
3805 }
3806#if !REAL
3807 if (!s3resume) {
3808 pre_raminit_3(x2ca8);
3809 }
Vladimir Serbinenkof62669c2014-01-09 10:59:38 +01003810 pre_raminit_4a(x2ca8);
Vladimir Serbinenkoc6f6be02013-11-12 22:32:08 +01003811#endif
3812
3813 dmi_setup();
3814
3815 write_mchbar16(0x1170, 0xa880);
3816 write_mchbar8(0x11c1, 0x1);
3817 write_mchbar16(0x1170, 0xb880);
3818 read_mchbar8(0x1210);
3819 write_mchbar8(0x1210, 0x84);
3820 pcie_read_config8(NORTHBRIDGE, D0F0_GGC); // = 0x52
3821 pcie_write_config8(NORTHBRIDGE, D0F0_GGC, 0x2);
3822 pcie_read_config8(NORTHBRIDGE, D0F0_GGC); // = 0x2
3823 pcie_write_config8(NORTHBRIDGE, D0F0_GGC, 0x52);
3824 pcie_read_config16(NORTHBRIDGE, D0F0_GGC); // = 0xb52
3825
3826 pcie_write_config16(NORTHBRIDGE, D0F0_GGC, 0xb52);
3827
3828 u16 deven;
3829 deven = pcie_read_config16(NORTHBRIDGE, D0F0_DEVEN); // = 0x3
3830
3831 if (deven & 8) {
3832 write_mchbar8(0x2c30, 0x20);
3833 pcie_read_config8(NORTHBRIDGE, 0x8); // = 0x18
3834 write_mchbar16(0x2c30, read_mchbar16(0x2c30) | 0x200);
3835 write_mchbar16(0x2c32, 0x434);
3836 read_mchbar32(0x2c44);
3837 write_mchbar32(0x2c44, 0x1053687);
3838 pcie_read_config8(GMA, 0x62); // = 0x2
3839 pcie_write_config8(GMA, 0x62, 0x2);
3840 read8(DEFAULT_RCBA | 0x2318);
3841 write8(DEFAULT_RCBA | 0x2318, 0x47);
3842 read8(DEFAULT_RCBA | 0x2320);
3843 write8(DEFAULT_RCBA | 0x2320, 0xfc);
3844 }
3845
3846 read_mchbar32(0x30);
3847 write_mchbar32(0x30, 0x40);
3848
3849 pcie_read_config8(SOUTHBRIDGE, 0x8); // = 0x6
3850 pcie_read_config16(NORTHBRIDGE, D0F0_GGC); // = 0xb52
3851 pcie_write_config16(NORTHBRIDGE, D0F0_GGC, 0xb50);
3852 gav(read32(DEFAULT_RCBA | 0x3428));
3853 write32(DEFAULT_RCBA | 0x3428, 0x1d);
3854
3855#if !REAL
3856 pre_raminit_5(s3resume);
3857#else
3858 set_fsb_frequency();
3859#endif
3860
3861 memset(&info, 0x5a, sizeof(info));
3862
3863 info.last_500_command[0] = 0;
3864 info.last_500_command[1] = 0;
3865
3866 info.fsb_frequency = 135 * 2;
3867 info.board_lane_delay[0] = 0x14;
3868 info.board_lane_delay[1] = 0x07;
3869 info.board_lane_delay[2] = 0x07;
3870 info.board_lane_delay[3] = 0x08;
3871 info.board_lane_delay[4] = 0x56;
3872 info.board_lane_delay[5] = 0x04;
3873 info.board_lane_delay[6] = 0x04;
3874 info.board_lane_delay[7] = 0x05;
3875 info.board_lane_delay[8] = 0x10;
3876
3877 info.training.reg_178 = 0;
3878 info.training.reg_10b = 0;
3879
3880 info.heci_bar = 0;
3881 info.memory_reserved_for_heci_mb = 0;
3882
3883 /* before SPD */
3884 timestamp_add_now(101);
3885
3886 if (!s3resume || REAL) {
3887 pcie_read_config8(SOUTHBRIDGE, GEN_PMCON_2); // = 0x80
3888
3889 collect_system_info(&info);
3890
3891#if REAL
3892 /* Enable SMBUS. */
3893 enable_smbus();
3894#endif
3895
3896 memset(&info.populated_ranks, 0, sizeof(info.populated_ranks));
3897
3898 info.use_ecc = 1;
3899 for (channel = 0; channel < NUM_CHANNELS; channel++)
3900 for (slot = 0; slot < NUM_CHANNELS; slot++) {
3901 int v;
3902 int try;
3903 int addr;
3904 const u8 useful_addresses[] = {
3905 DEVICE_TYPE,
3906 MODULE_TYPE,
3907 DENSITY,
3908 RANKS_AND_DQ,
3909 MEMORY_BUS_WIDTH,
3910 TIMEBASE_DIVIDEND,
3911 TIMEBASE_DIVISOR,
3912 CYCLETIME,
3913 CAS_LATENCIES_LSB,
3914 CAS_LATENCIES_MSB,
3915 CAS_LATENCY_TIME,
3916 0x11, 0x12, 0x13, 0x14, 0x15,
3917 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b,
3918 0x1c, 0x1d,
3919 THERMAL_AND_REFRESH,
3920 0x20,
3921 REFERENCE_RAW_CARD_USED,
3922 RANK1_ADDRESS_MAPPING,
3923 0x75, 0x76, 0x77, 0x78,
3924 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e,
3925 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84,
3926 0x85, 0x86, 0x87, 0x88,
3927 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e,
3928 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94,
3929 0x95
3930 };
3931 if (slot)
3932 continue;
3933 for (try = 0; try < 5; try++) {
3934 v = smbus_read_byte(0x50 + channel,
3935 DEVICE_TYPE);
3936 if (v >= 0)
3937 break;
3938 }
3939 if (v < 0)
3940 continue;
3941 for (addr = 0;
3942 addr <
3943 sizeof(useful_addresses) /
3944 sizeof(useful_addresses[0]); addr++)
3945 gav(info.
3946 spd[channel][0][useful_addresses
3947 [addr]] =
3948 smbus_read_byte(0x50 + channel,
3949 useful_addresses
3950 [addr]));
3951 if (info.spd[channel][0][DEVICE_TYPE] != 11)
3952 die("Only DDR3 is supported");
3953
3954 v = info.spd[channel][0][RANKS_AND_DQ];
3955 info.populated_ranks[channel][0][0] = 1;
3956 info.populated_ranks[channel][0][1] =
3957 ((v >> 3) & 7);
3958 if (((v >> 3) & 7) > 1)
3959 die("At most 2 ranks are supported");
3960 if ((v & 7) == 0 || (v & 7) > 2)
3961 die("Only x8 and x16 modules are supported");
3962 if ((info.
3963 spd[channel][slot][MODULE_TYPE] & 0xF) != 2
3964 && (info.
3965 spd[channel][slot][MODULE_TYPE] & 0xF)
3966 != 3)
3967 die("Registered memory is not supported");
3968 info.is_x16_module[channel][0] = (v & 7) - 1;
3969 info.density[channel][slot] =
3970 info.spd[channel][slot][DENSITY] & 0xF;
3971 if (!
3972 (info.
3973 spd[channel][slot][MEMORY_BUS_WIDTH] &
3974 0x18))
3975 info.use_ecc = 0;
3976 }
3977
3978 gav(0x55);
3979
3980 for (channel = 0; channel < NUM_CHANNELS; channel++) {
3981 int v = 0;
3982 for (slot = 0; slot < NUM_SLOTS; slot++)
3983 for (rank = 0; rank < NUM_RANKS; rank++)
3984 v |= info.
3985 populated_ranks[channel][slot][rank]
3986 << (2 * slot + rank);
3987 info.populated_ranks_mask[channel] = v;
3988 }
3989
3990 gav(0x55);
3991
3992 gav(pcie_read_config32(NORTHBRIDGE, D0F0_CAPID0 + 4));
3993 }
3994
3995 /* after SPD */
3996 timestamp_add_now(102);
3997
3998 write_mchbar8(0x2ca8, read_mchbar8(0x2ca8) & 0xfc);
3999#if !REAL
4000 rdmsr (MTRRphysMask_MSR (3));
4001#endif
4002
4003 collect_system_info(&info);
4004 calculate_timings(&info);
4005
4006#if !REAL
4007 pcie_write_config8(NORTHBRIDGE, 0xdf, 0x82);
4008#endif
4009
4010 if (!s3resume) {
4011 u8 reg8 = pcie_read_config8(SOUTHBRIDGE, GEN_PMCON_2);
4012 if (x2ca8 == 0 && (reg8 & 0x80)) {
4013 /* Don't enable S4-assertion stretch. Makes trouble on roda/rk9.
4014 reg8 = pci_read_config8(PCI_DEV(0, 0x1f, 0), 0xa4);
4015 pci_write_config8(PCI_DEV(0, 0x1f, 0), 0xa4, reg8 | 0x08);
4016 */
4017
4018 /* Clear bit7. */
4019
4020 pci_write_config8(SOUTHBRIDGE, GEN_PMCON_2,
4021 (reg8 & ~(1 << 7)));
4022
4023 printk(BIOS_INFO,
4024 "Interrupted RAM init, reset required.\n");
4025 outb(0x6, 0xcf9);
4026#if REAL
4027 while (1) {
4028 asm volatile ("hlt");
4029 }
4030#endif
4031 }
4032 }
4033#if !REAL
4034 gav(read_mchbar8(0x2ca8)); ///!!!!
4035#endif
4036
4037 if (!s3resume && x2ca8 == 0)
4038 pcie_write_config8(SOUTHBRIDGE, GEN_PMCON_2,
4039 pcie_read_config8(SOUTHBRIDGE, GEN_PMCON_2) | 0x80);
4040
4041 compute_derived_timings(&info);
4042
4043 if (x2ca8 == 0) {
4044 gav(read_mchbar8(0x164));
4045 write_mchbar8(0x164, 0x26);
4046 write_mchbar16(0x2c20, 0x10);
4047 }
4048
4049 write_mchbar32(0x18b4, read_mchbar32(0x18b4) | 0x210000); /* OK */
4050 write_mchbar32(0x1890, read_mchbar32(0x1890) | 0x2000000); /* OK */
4051 write_mchbar32(0x18b4, read_mchbar32(0x18b4) | 0x8000);
4052
4053 gav(pcie_read_config32(PCI_DEV(0xff, 2, 1), 0x50)); // !!!!
4054 pcie_write_config8(PCI_DEV(0xff, 2, 1), 0x54, 0x12);
4055
4056 gav(read_mchbar16(0x2c10)); // !!!!
4057 write_mchbar16(0x2c10, 0x412);
4058 gav(read_mchbar16(0x2c10)); // !!!!
4059 write_mchbar16(0x2c12, read_mchbar16(0x2c12) | 0x100); /* OK */
4060
4061 gav(read_mchbar8(0x2ca8)); // !!!!
4062 write_mchbar32(0x1804,
4063 (read_mchbar32(0x1804) & 0xfffffffc) | 0x8400080);
4064
4065 pcie_read_config32(PCI_DEV(0xff, 2, 1), 0x6c); // !!!!
4066 pcie_write_config32(PCI_DEV(0xff, 2, 1), 0x6c, 0x40a0a0);
4067 gav(read_mchbar32(0x1c04)); // !!!!
4068 gav(read_mchbar32(0x1804)); // !!!!
4069
4070 if (x2ca8 == 0) {
4071 write_mchbar8(0x2ca8, read_mchbar8(0x2ca8) | 1);
4072 }
4073
4074 write_mchbar32(0x18d8, 0x120000);
4075 write_mchbar32(0x18dc, 0x30a484a);
4076 pcie_write_config32(PCI_DEV(0xff, 2, 1), 0xe0, 0x0);
4077 pcie_write_config32(PCI_DEV(0xff, 2, 1), 0xf4, 0x9444a);
4078 write_mchbar32(0x18d8, 0x40000);
4079 write_mchbar32(0x18dc, 0xb000000);
4080 pcie_write_config32(PCI_DEV(0xff, 2, 1), 0xe0, 0x60000);
4081 pcie_write_config32(PCI_DEV(0xff, 2, 1), 0xf4, 0x0);
4082 write_mchbar32(0x18d8, 0x180000);
4083 write_mchbar32(0x18dc, 0xc0000142);
4084 pcie_write_config32(PCI_DEV(0xff, 2, 1), 0xe0, 0x20000);
4085 pcie_write_config32(PCI_DEV(0xff, 2, 1), 0xf4, 0x142);
4086 write_mchbar32(0x18d8, 0x1e0000);
4087
4088 gav(read_mchbar32(0x18dc)); // !!!!
4089 write_mchbar32(0x18dc, 0x3);
4090 gav(read_mchbar32(0x18dc)); // !!!!
4091
4092 if (x2ca8 == 0) {
4093 write_mchbar8(0x2ca8, read_mchbar8(0x2ca8) | 1); // guess
4094 }
4095
4096 write_mchbar32(0x188c, 0x20bc09);
4097 pcie_write_config32(PCI_DEV(0xff, 2, 1), 0xd0, 0x40b0c09);
4098 write_mchbar32(0x1a10, 0x4200010e);
4099 write_mchbar32(0x18b8, read_mchbar32(0x18b8) | 0x200);
4100 gav(read_mchbar32(0x1918)); // !!!!
4101 write_mchbar32(0x1918, 0x332);
4102
4103 gav(read_mchbar32(0x18b8)); // !!!!
4104 write_mchbar32(0x18b8, 0xe00);
4105 gav(read_mchbar32(0x182c)); // !!!!
4106 write_mchbar32(0x182c, 0x10202);
4107 gav(pcie_read_config32(PCI_DEV(0xff, 2, 1), 0x94)); // !!!!
4108 pcie_write_config32(PCI_DEV(0xff, 2, 1), 0x94, 0x10202);
4109 write_mchbar32(0x1a1c, read_mchbar32(0x1a1c) & 0x8fffffff);
4110 write_mchbar32(0x1a70, read_mchbar32(0x1a70) | 0x100000);
4111
4112 write_mchbar32(0x18b4, read_mchbar32(0x18b4) & 0xffff7fff);
4113 gav(read_mchbar32(0x1a68)); // !!!!
4114 write_mchbar32(0x1a68, 0x343800);
4115 gav(read_mchbar32(0x1e68)); // !!!!
4116 gav(read_mchbar32(0x1a68)); // !!!!
4117
4118 if (x2ca8 == 0) {
4119 write_mchbar8(0x2ca8, read_mchbar8(0x2ca8) | 1); // guess
4120 }
4121
4122 pcie_read_config32(PCI_DEV(0xff, 2, 0), 0x048); // !!!!
4123 pcie_write_config32(PCI_DEV(0xff, 2, 0), 0x048, 0x140000);
4124 pcie_read_config32(PCI_DEV(0xff, 2, 0), 0x058); // !!!!
4125 pcie_write_config32(PCI_DEV(0xff, 2, 0), 0x058, 0x64555);
4126 pcie_read_config32(PCI_DEV(0xff, 2, 0), 0x058); // !!!!
4127 pcie_read_config32(PCI_DEV (0xff, 0, 0), 0xd0); // !!!!
4128 pcie_write_config32(PCI_DEV (0xff, 0, 0), 0xd0, 0x180);
4129 gav(read_mchbar32(0x1af0)); // !!!!
4130 gav(read_mchbar32(0x1af0)); // !!!!
4131 write_mchbar32(0x1af0, 0x1f020003);
4132 gav(read_mchbar32(0x1af0)); // !!!!
4133
4134 if (((x2ca8 == 0))) {
4135 write_mchbar8(0x2ca8, read_mchbar8(0x2ca8) | 1); // guess
4136 }
4137
4138 gav(read_mchbar32(0x1890)); // !!!!
4139 write_mchbar32(0x1890, 0x80102);
4140 gav(read_mchbar32(0x18b4)); // !!!!
4141 write_mchbar32(0x18b4, 0x216000);
4142 write_mchbar32(0x18a4, 0x22222222);
4143 write_mchbar32(0x18a8, 0x22222222);
4144 write_mchbar32(0x18ac, 0x22222);
4145
4146 udelay(1000);
4147
4148 if (x2ca8 == 0) {
4149 if (s3resume) {
4150#if REAL && 0
4151 info.reg2ca9_bit0 = 0;
4152 info.reg274265[0][0] = 5;
4153 info.reg274265[0][1] = 5;
4154 info.reg274265[0][2] = 0xe;
4155 info.reg274265[1][0] = 5;
4156 info.reg274265[1][1] = 5;
4157 info.reg274265[1][2] = 0xe;
4158 info.delay46_ps[0] = 0xa86;
4159 info.delay46_ps[1] = 0xa86;
4160 info.delay54_ps[0] = 0xdc6;
4161 info.delay54_ps[1] = 0xdc6;
4162#else
4163 info.reg2ca9_bit0 = 0;
4164 info.reg274265[0][0] = 3;
4165 info.reg274265[0][1] = 5;
4166 info.reg274265[0][2] = 0xd;
4167 info.reg274265[1][0] = 4;
4168 info.reg274265[1][1] = 5;
4169 info.reg274265[1][2] = 0xd;
4170 info.delay46_ps[0] = 0x110a;
4171 info.delay46_ps[1] = 0xb58;
4172 info.delay54_ps[0] = 0x144a;
4173 info.delay54_ps[1] = 0xe98;
4174#endif
4175 restore_274265(&info);
4176 } else
4177 set_274265(&info);
4178 int j;
4179 printk(BIOS_DEBUG, "reg2ca9_bit0 = %x\n", info.reg2ca9_bit0);
4180 for (i = 0; i < 2; i++)
4181 for (j = 0; j < 3; j++)
4182 printk(BIOS_DEBUG, "reg274265[%d][%d] = %x\n",
4183 i, j, info.reg274265[i][j]);
4184 for (i = 0; i < 2; i++)
4185 printk(BIOS_DEBUG, "delay46_ps[%d] = %x\n", i,
4186 info.delay46_ps[i]);
4187 for (i = 0; i < 2; i++)
4188 printk(BIOS_DEBUG, "delay54_ps[%d] = %x\n", i,
4189 info.delay54_ps[i]);
4190
4191 set_2dxx_series(&info);
4192
4193 if (!(deven & 8)) {
4194 read_mchbar32(0x2cb0);
4195 write_mchbar32(0x2cb0, 0x40);
4196 }
4197
4198 udelay(1000);
4199
4200 if (deven & 8) {
4201 write_mchbar32(0xff8, 0x1800 | read_mchbar32(0xff8));
4202 read_mchbar32(0x2cb0);
4203 write_mchbar32(0x2cb0, 0x00);
4204 pcie_read_config8(PCI_DEV (0, 0x2, 0x0), 0x4c);
4205 pcie_read_config8(PCI_DEV (0, 0x2, 0x0), 0x4c);
4206 pcie_read_config8(PCI_DEV (0, 0x2, 0x0), 0x4e);
4207
4208 read_mchbar8(0x1150);
4209 read_mchbar8(0x1151);
4210 read_mchbar8(0x1022);
4211 read_mchbar8(0x16d0);
4212 write_mchbar32(0x1300, 0x60606060);
4213 write_mchbar32(0x1304, 0x60606060);
4214 write_mchbar32(0x1308, 0x78797a7b);
4215 write_mchbar32(0x130c, 0x7c7d7e7f);
4216 write_mchbar32(0x1310, 0x60606060);
4217 write_mchbar32(0x1314, 0x60606060);
4218 write_mchbar32(0x1318, 0x60606060);
4219 write_mchbar32(0x131c, 0x60606060);
4220 write_mchbar32(0x1320, 0x50515253);
4221 write_mchbar32(0x1324, 0x54555657);
4222 write_mchbar32(0x1328, 0x58595a5b);
4223 write_mchbar32(0x132c, 0x5c5d5e5f);
4224 write_mchbar32(0x1330, 0x40414243);
4225 write_mchbar32(0x1334, 0x44454647);
4226 write_mchbar32(0x1338, 0x48494a4b);
4227 write_mchbar32(0x133c, 0x4c4d4e4f);
4228 write_mchbar32(0x1340, 0x30313233);
4229 write_mchbar32(0x1344, 0x34353637);
4230 write_mchbar32(0x1348, 0x38393a3b);
4231 write_mchbar32(0x134c, 0x3c3d3e3f);
4232 write_mchbar32(0x1350, 0x20212223);
4233 write_mchbar32(0x1354, 0x24252627);
4234 write_mchbar32(0x1358, 0x28292a2b);
4235 write_mchbar32(0x135c, 0x2c2d2e2f);
4236 write_mchbar32(0x1360, 0x10111213);
4237 write_mchbar32(0x1364, 0x14151617);
4238 write_mchbar32(0x1368, 0x18191a1b);
4239 write_mchbar32(0x136c, 0x1c1d1e1f);
4240 write_mchbar32(0x1370, 0x10203);
4241 write_mchbar32(0x1374, 0x4050607);
4242 write_mchbar32(0x1378, 0x8090a0b);
4243 write_mchbar32(0x137c, 0xc0d0e0f);
4244 write_mchbar8(0x11cc, 0x4e);
4245 write_mchbar32(0x1110, 0x73970404);
4246 write_mchbar32(0x1114, 0x72960404);
4247 write_mchbar32(0x1118, 0x6f950404);
4248 write_mchbar32(0x111c, 0x6d940404);
4249 write_mchbar32(0x1120, 0x6a930404);
4250 write_mchbar32(0x1124, 0x68a41404);
4251 write_mchbar32(0x1128, 0x66a21404);
4252 write_mchbar32(0x112c, 0x63a01404);
4253 write_mchbar32(0x1130, 0x609e1404);
4254 write_mchbar32(0x1134, 0x5f9c1404);
4255 write_mchbar32(0x1138, 0x5c961404);
4256 write_mchbar32(0x113c, 0x58a02404);
4257 write_mchbar32(0x1140, 0x54942404);
4258 write_mchbar32(0x1190, 0x900080a);
4259 write_mchbar16(0x11c0, 0xc40b);
4260 write_mchbar16(0x11c2, 0x303);
4261 write_mchbar16(0x11c4, 0x301);
4262 read_mchbar32(0x1190);
4263 write_mchbar32(0x1190, 0x8900080a);
4264 write_mchbar32(0x11b8, 0x70c3000);
4265 write_mchbar8(0x11ec, 0xa);
4266 write_mchbar16(0x1100, 0x800);
4267 read_mchbar32(0x11bc);
4268 write_mchbar32(0x11bc, 0x1e84800);
4269 write_mchbar16(0x11ca, 0xfa);
4270 write_mchbar32(0x11e4, 0x4e20);
4271 write_mchbar8(0x11bc, 0xf);
4272 write_mchbar16(0x11da, 0x19);
4273 write_mchbar16(0x11ba, 0x470c);
4274 write_mchbar32(0x1680, 0xe6ffe4ff);
4275 write_mchbar32(0x1684, 0xdeffdaff);
4276 write_mchbar32(0x1688, 0xd4ffd0ff);
4277 write_mchbar32(0x168c, 0xccffc6ff);
4278 write_mchbar32(0x1690, 0xc0ffbeff);
4279 write_mchbar32(0x1694, 0xb8ffb0ff);
4280 write_mchbar32(0x1698, 0xa8ff0000);
4281 write_mchbar32(0x169c, 0xc00);
4282 write_mchbar32(0x1290, 0x5000000);
4283 }
4284
4285 write_mchbar32(0x124c, 0x15040d00);
4286 write_mchbar32(0x1250, 0x7f0000);
4287 write_mchbar32(0x1254, 0x1e220004);
4288 write_mchbar32(0x1258, 0x4000004);
4289 write_mchbar32(0x1278, 0x0);
4290 write_mchbar32(0x125c, 0x0);
4291 write_mchbar32(0x1260, 0x0);
4292 write_mchbar32(0x1264, 0x0);
4293 write_mchbar32(0x1268, 0x0);
4294 write_mchbar32(0x126c, 0x0);
4295 write_mchbar32(0x1270, 0x0);
4296 write_mchbar32(0x1274, 0x0);
4297 }
4298
4299 if ((deven & 8) && x2ca8 == 0) {
4300 write_mchbar16(0x1214, 0x320);
4301 write_mchbar32(0x1600, 0x40000000);
4302 read_mchbar32(0x11f4);
4303 write_mchbar32(0x11f4, 0x10000000);
4304 read_mchbar16(0x1230);
4305 write_mchbar16(0x1230, 0x8000);
4306 write_mchbar32(0x1400, 0x13040020);
4307 write_mchbar32(0x1404, 0xe090120);
4308 write_mchbar32(0x1408, 0x5120220);
4309 write_mchbar32(0x140c, 0x5120330);
4310 write_mchbar32(0x1410, 0xe090220);
4311 write_mchbar32(0x1414, 0x1010001);
4312 write_mchbar32(0x1418, 0x1110000);
4313 write_mchbar32(0x141c, 0x9020020);
4314 write_mchbar32(0x1420, 0xd090220);
4315 write_mchbar32(0x1424, 0x2090220);
4316 write_mchbar32(0x1428, 0x2090330);
4317 write_mchbar32(0x142c, 0xd090220);
4318 write_mchbar32(0x1430, 0x1010001);
4319 write_mchbar32(0x1434, 0x1110000);
4320 write_mchbar32(0x1438, 0x11040020);
4321 write_mchbar32(0x143c, 0x4030220);
4322 write_mchbar32(0x1440, 0x1060220);
4323 write_mchbar32(0x1444, 0x1060330);
4324 write_mchbar32(0x1448, 0x4030220);
4325 write_mchbar32(0x144c, 0x1010001);
4326 write_mchbar32(0x1450, 0x1110000);
4327 write_mchbar32(0x1454, 0x4010020);
4328 write_mchbar32(0x1458, 0xb090220);
4329 write_mchbar32(0x145c, 0x1090220);
4330 write_mchbar32(0x1460, 0x1090330);
4331 write_mchbar32(0x1464, 0xb090220);
4332 write_mchbar32(0x1468, 0x1010001);
4333 write_mchbar32(0x146c, 0x1110000);
4334 write_mchbar32(0x1470, 0xf040020);
4335 write_mchbar32(0x1474, 0xa090220);
4336 write_mchbar32(0x1478, 0x1120220);
4337 write_mchbar32(0x147c, 0x1120330);
4338 write_mchbar32(0x1480, 0xa090220);
4339 write_mchbar32(0x1484, 0x1010001);
4340 write_mchbar32(0x1488, 0x1110000);
4341 write_mchbar32(0x148c, 0x7020020);
4342 write_mchbar32(0x1490, 0x1010220);
4343 write_mchbar32(0x1494, 0x10210);
4344 write_mchbar32(0x1498, 0x10320);
4345 write_mchbar32(0x149c, 0x1010220);
4346 write_mchbar32(0x14a0, 0x1010001);
4347 write_mchbar32(0x14a4, 0x1110000);
4348 write_mchbar32(0x14a8, 0xd040020);
4349 write_mchbar32(0x14ac, 0x8090220);
4350 write_mchbar32(0x14b0, 0x1111310);
4351 write_mchbar32(0x14b4, 0x1111420);
4352 write_mchbar32(0x14b8, 0x8090220);
4353 write_mchbar32(0x14bc, 0x1010001);
4354 write_mchbar32(0x14c0, 0x1110000);
4355 write_mchbar32(0x14c4, 0x3010020);
4356 write_mchbar32(0x14c8, 0x7090220);
4357 write_mchbar32(0x14cc, 0x1081310);
4358 write_mchbar32(0x14d0, 0x1081420);
4359 write_mchbar32(0x14d4, 0x7090220);
4360 write_mchbar32(0x14d8, 0x1010001);
4361 write_mchbar32(0x14dc, 0x1110000);
4362 write_mchbar32(0x14e0, 0xb040020);
4363 write_mchbar32(0x14e4, 0x2030220);
4364 write_mchbar32(0x14e8, 0x1051310);
4365 write_mchbar32(0x14ec, 0x1051420);
4366 write_mchbar32(0x14f0, 0x2030220);
4367 write_mchbar32(0x14f4, 0x1010001);
4368 write_mchbar32(0x14f8, 0x1110000);
4369 write_mchbar32(0x14fc, 0x5020020);
4370 write_mchbar32(0x1500, 0x5090220);
4371 write_mchbar32(0x1504, 0x2071310);
4372 write_mchbar32(0x1508, 0x2071420);
4373 write_mchbar32(0x150c, 0x5090220);
4374 write_mchbar32(0x1510, 0x1010001);
4375 write_mchbar32(0x1514, 0x1110000);
4376 write_mchbar32(0x1518, 0x7040120);
4377 write_mchbar32(0x151c, 0x2090220);
4378 write_mchbar32(0x1520, 0x70b1210);
4379 write_mchbar32(0x1524, 0x70b1310);
4380 write_mchbar32(0x1528, 0x2090220);
4381 write_mchbar32(0x152c, 0x1010001);
4382 write_mchbar32(0x1530, 0x1110000);
4383 write_mchbar32(0x1534, 0x1010110);
4384 write_mchbar32(0x1538, 0x1081310);
4385 write_mchbar32(0x153c, 0x5041200);
4386 write_mchbar32(0x1540, 0x5041310);
4387 write_mchbar32(0x1544, 0x1081310);
4388 write_mchbar32(0x1548, 0x1010001);
4389 write_mchbar32(0x154c, 0x1110000);
4390 write_mchbar32(0x1550, 0x1040120);
4391 write_mchbar32(0x1554, 0x4051210);
4392 write_mchbar32(0x1558, 0xd051200);
4393 write_mchbar32(0x155c, 0xd051200);
4394 write_mchbar32(0x1560, 0x4051210);
4395 write_mchbar32(0x1564, 0x1010001);
4396 write_mchbar32(0x1568, 0x1110000);
4397 write_mchbar16(0x1222, 0x220a);
4398 write_mchbar16(0x123c, 0x1fc0);
4399 write_mchbar16(0x1220, 0x1388);
4400 }
4401
4402 read_mchbar32(0x2c80); // !!!!
4403 write_mchbar32(0x2c80, 0x1053688);
4404 read_mchbar32(0x1c04); // !!!!
4405 write_mchbar32(0x1804, 0x406080);
4406
4407 read_mchbar8(0x2ca8);
4408
4409 if (x2ca8 == 0) {
4410 write_mchbar8(0x2ca8, read_mchbar8(0x2ca8) & ~3);
4411 write_mchbar8(0x2ca8, read_mchbar8(0x2ca8) + 4);
4412 write_mchbar32(0x1af0, read_mchbar32(0x1af0) | 0x10);
4413#if REAL
4414 while (1) {
4415 asm volatile ("hlt");
4416 }
4417#else
4418 printf("CP5\n");
4419 exit(0);
4420#endif
4421 }
4422
4423 write_mchbar8(0x2ca8, read_mchbar8(0x2ca8));
4424 read_mchbar32(0x2c80); // !!!!
4425 write_mchbar32(0x2c80, 0x53688);
4426 pcie_write_config32(PCI_DEV (0xff, 0, 0), 0x60, 0x20220);
4427 read_mchbar16(0x2c20); // !!!!
4428 read_mchbar16(0x2c10); // !!!!
4429 read_mchbar16(0x2c00); // !!!!
4430 write_mchbar16(0x2c00, 0x8c0);
4431 udelay(1000);
4432 write_1d0(0, 0x33d, 0, 0);
4433 write_500(&info, 0, 0, 0xb61, 0, 0);
4434 write_500(&info, 1, 0, 0xb61, 0, 0);
4435 write_mchbar32(0x1a30, 0x0);
4436 write_mchbar32(0x1a34, 0x0);
4437 write_mchbar16(0x614,
4438 0xb5b | (info.populated_ranks[1][0][0] *
4439 0x404) | (info.populated_ranks[0][0][0] *
4440 0xa0));
4441 write_mchbar16(0x616, 0x26a);
4442 write_mchbar32(0x134, 0x856000);
4443 write_mchbar32(0x160, 0x5ffffff);
4444 read_mchbar32(0x114); // !!!!
4445 write_mchbar32(0x114, 0xc2024440);
4446 read_mchbar32(0x118); // !!!!
4447 write_mchbar32(0x118, 0x4);
4448 for (channel = 0; channel < NUM_CHANNELS; channel++)
4449 write_mchbar32(0x260 + (channel << 10),
4450 0x30809ff |
4451 ((info.
4452 populated_ranks_mask[channel] & 3) << 20));
4453 for (channel = 0; channel < NUM_CHANNELS; channel++) {
4454 write_mchbar16(0x31c + (channel << 10), 0x101);
4455 write_mchbar16(0x360 + (channel << 10), 0x909);
4456 write_mchbar16(0x3a4 + (channel << 10), 0x101);
4457 write_mchbar16(0x3e8 + (channel << 10), 0x101);
4458 write_mchbar32(0x320 + (channel << 10), 0x29002900);
4459 write_mchbar32(0x324 + (channel << 10), 0x0);
4460 write_mchbar32(0x368 + (channel << 10), 0x32003200);
4461 write_mchbar16(0x352 + (channel << 10), 0x505);
4462 write_mchbar16(0x354 + (channel << 10), 0x3c3c);
4463 write_mchbar16(0x356 + (channel << 10), 0x1040);
4464 write_mchbar16(0x39a + (channel << 10), 0x73e4);
4465 write_mchbar16(0x3de + (channel << 10), 0x77ed);
4466 write_mchbar16(0x422 + (channel << 10), 0x1040);
4467 }
4468
4469 write_1d0(0x4, 0x151, 4, 1);
4470 write_1d0(0, 0x142, 3, 1);
4471 rdmsr(0x1ac); // !!!!
4472 write_500(&info, 1, 1, 0x6b3, 4, 1);
4473 write_500(&info, 1, 1, 0x6cf, 4, 1);
4474
4475 rmw_1d0(0x21c, 0x38, 0, 6, 1);
4476
4477 write_1d0(((!info.populated_ranks[1][0][0]) << 1) | ((!info.
4478 populated_ranks[0]
4479 [0][0]) << 0),
4480 0x1d1, 3, 1);
4481 for (channel = 0; channel < NUM_CHANNELS; channel++) {
4482 write_mchbar16(0x38e + (channel << 10), 0x5f5f);
4483 write_mchbar16(0x3d2 + (channel << 10), 0x5f5f);
4484 }
4485
4486 set_334(0);
4487
4488 program_base_timings(&info);
4489
4490 write_mchbar8(0x5ff, read_mchbar8(0x5ff) | 0x80); /* OK */
4491
4492 write_1d0(0x2, 0x1d5, 2, 1);
4493 write_1d0(0x20, 0x166, 7, 1);
4494 write_1d0(0x0, 0xeb, 3, 1);
4495 write_1d0(0x0, 0xf3, 6, 1);
4496
4497 for (channel = 0; channel < NUM_CHANNELS; channel++)
4498 for (lane = 0; lane < 9; lane++) {
4499 u16 addr = 0x125 + get_lane_offset(0, 0, lane);
4500 u8 a;
4501 a = read_500(&info, channel, addr, 6); // = 0x20040080 //!!!!
4502 write_500(&info, channel, a, addr, 6, 1);
4503 }
4504
4505 udelay(1000);
4506
4507 info.cached_training = get_cached_training();
4508
4509 if (s3resume) {
4510 if (info.cached_training == NULL) {
4511 u32 reg32;
4512 printk(BIOS_ERR,
4513 "Couldn't find training data. Rebooting\n");
4514 reg32 = inl(DEFAULT_PMBASE + 0x04);
4515 outl(reg32 & ~(7 << 10), DEFAULT_PMBASE + 0x04);
4516 outb(0xe, 0xcf9);
4517
4518#if REAL
4519 while (1) {
4520 asm volatile ("hlt");
4521 }
4522#else
4523 printf("CP5\n");
4524 exit(0);
4525#endif
4526 }
4527 int tm;
4528 info.training = *info.cached_training;
4529 for (tm = 0; tm < 4; tm++)
4530 for (channel = 0; channel < NUM_CHANNELS; channel++)
4531 for (slot = 0; slot < NUM_SLOTS; slot++)
4532 for (rank = 0; rank < NUM_RANKS; rank++)
4533 for (lane = 0; lane < 9; lane++)
4534 write_500(&info,
4535 channel,
4536 info.training.
4537 lane_timings
4538 [tm][channel]
4539 [slot][rank]
4540 [lane],
4541 get_timing_register_addr
4542 (lane, tm,
4543 slot, rank),
4544 9, 0);
4545 write_1d0(info.cached_training->reg_178, 0x178, 7, 1);
4546 write_1d0(info.cached_training->reg_10b, 0x10b, 6, 1);
4547 }
4548
4549 read_mchbar32(0x1f4); // !!!!
4550 write_mchbar32(0x1f4, 0x20000);
4551 write_mchbar32(0x1f0, 0x1d000200);
4552 read_mchbar8(0x1f0); // !!!!
4553 write_mchbar8(0x1f0, 0x1);
4554 read_mchbar8(0x1f0); // !!!!
4555
4556 program_board_delay(&info);
4557
4558 write_mchbar8(0x5ff, 0x0); /* OK */
4559 write_mchbar8(0x5ff, 0x80); /* OK */
4560 write_mchbar8(0x5f4, 0x1); /* OK */
4561
4562 write_mchbar32(0x130, read_mchbar32(0x130) & 0xfffffffd); // | 2 when ?
4563 while (read_mchbar32(0x130) & 1) ;
4564 gav(read_1d0(0x14b, 7)); // = 0x81023100
4565 write_1d0(0x30, 0x14b, 7, 1);
4566 read_1d0(0xd6, 6); // = 0xfa008080 // !!!!
4567 write_1d0(7, 0xd6, 6, 1);
4568 read_1d0(0x328, 6); // = 0xfa018080 // !!!!
4569 write_1d0(7, 0x328, 6, 1);
4570
4571 for (channel = 0; channel < NUM_CHANNELS; channel++)
4572 set_4cf(&info, channel,
4573 info.populated_ranks[channel][0][0] ? 8 : 0);
4574
4575 read_1d0(0x116, 4); // = 0x4040432 // !!!!
4576 write_1d0(2, 0x116, 4, 1);
4577 read_1d0(0xae, 6); // = 0xe8088080 // !!!!
4578 write_1d0(0, 0xae, 6, 1);
4579 read_1d0(0x300, 4); // = 0x48088080 // !!!!
4580 write_1d0(0, 0x300, 6, 1);
4581 read_mchbar16(0x356); // !!!!
4582 write_mchbar16(0x356, 0x1040);
4583 read_mchbar16(0x756); // !!!!
4584 write_mchbar16(0x756, 0x1040);
4585 write_mchbar32(0x140, read_mchbar32(0x140) & ~0x07000000);
4586 write_mchbar32(0x138, read_mchbar32(0x138) & ~0x07000000);
4587 write_mchbar32(0x130, 0x31111301);
4588 while (read_mchbar32(0x130) & 1) ;
4589
4590 {
4591 u32 t;
4592 u8 val_a1;
4593 val_a1 = read_1d0(0xa1, 6); // = 0x1cf4040 // !!!!
4594 t = read_1d0(0x2f3, 6); // = 0x10a4040 // !!!!
4595 rmw_1d0(0x320, 0x07,
4596 (t & 4) | ((t & 8) >> 2) | ((t & 0x10) >> 4), 6, 1);
4597 rmw_1d0(0x14b, 0x78,
4598 ((((val_a1 >> 2) & 4) | (val_a1 & 8)) >> 2) | (val_a1 &
4599 4), 7,
4600 1);
4601 rmw_1d0(0xce, 0x38,
4602 ((((val_a1 >> 2) & 4) | (val_a1 & 8)) >> 2) | (val_a1 &
4603 4), 6,
4604 1);
4605 }
4606
4607 for (channel = 0; channel < NUM_CHANNELS; channel++)
4608 set_4cf(&info, channel,
4609 info.populated_ranks[channel][0][0] ? 9 : 1);
4610
4611 rmw_1d0(0x116, 0xe, 1, 4, 1); // = 0x4040432 // !!!!
4612 read_mchbar32(0x144); // !!!!
4613 write_1d0(2, 0xae, 6, 1);
4614 write_1d0(2, 0x300, 6, 1);
4615 write_1d0(2, 0x121, 3, 1);
4616 read_1d0(0xd6, 6); // = 0xfa00c0c7 // !!!!
4617 write_1d0(4, 0xd6, 6, 1);
4618 read_1d0(0x328, 6); // = 0xfa00c0c7 // !!!!
4619 write_1d0(4, 0x328, 6, 1);
4620
4621 for (channel = 0; channel < NUM_CHANNELS; channel++)
4622 set_4cf(&info, channel,
4623 info.populated_ranks[channel][0][0] ? 9 : 0);
4624
4625 write_mchbar32(0x130,
4626 0x11111301 | (info.
4627 populated_ranks[1][0][0] << 30) | (info.
4628 populated_ranks
4629 [0][0]
4630 [0] <<
4631 29));
4632 while (read_mchbar8(0x130) & 1) ; // !!!!
4633 read_1d0(0xa1, 6); // = 0x1cf4054 // !!!!
4634 read_1d0(0x2f3, 6); // = 0x10a4054 // !!!!
4635 read_1d0(0x21c, 6); // = 0xafa00c0 // !!!!
4636 write_1d0(0, 0x21c, 6, 1);
4637 read_1d0(0x14b, 7); // = 0x810231b0 // !!!!
4638 write_1d0(0x35, 0x14b, 7, 1);
4639
4640 for (channel = 0; channel < NUM_CHANNELS; channel++)
4641 set_4cf(&info, channel,
4642 info.populated_ranks[channel][0][0] ? 0xb : 0x2);
4643
4644 set_334(1);
4645
4646 write_mchbar8(0x1e8, 0x4); /* OK */
4647
4648 for (channel = 0; channel < NUM_CHANNELS; channel++) {
4649 write_500(&info, channel,
4650 0x3 & ~(info.populated_ranks_mask[channel]), 0x6b7, 2,
4651 1);
4652 write_500(&info, channel, 0x3, 0x69b, 2, 1);
4653 }
4654 write_mchbar32(0x2d0, (read_mchbar32(0x2d0) & 0xff2c01ff) | 0x200000); /* OK */
4655 write_mchbar16(0x6c0, 0x14a0); /* OK */
4656 write_mchbar32(0x6d0, (read_mchbar32(0x6d0) & 0xff0080ff) | 0x8000); /* OK */
4657 write_mchbar16(0x232, 0x8);
4658 write_mchbar32(0x234, (read_mchbar32(0x234) & 0xfffbfffb) | 0x40004); /* 0x40004 or 0 depending on ? */
4659 write_mchbar32(0x34, (read_mchbar32(0x34) & 0xfffffffd) | 5); /* OK */
4660 write_mchbar32(0x128, 0x2150d05);
4661 write_mchbar8(0x12c, 0x1f); /* OK */
4662 write_mchbar8(0x12d, 0x56); /* OK */
4663 write_mchbar8(0x12e, 0x31);
4664 write_mchbar8(0x12f, 0x0); /* OK */
4665 write_mchbar8(0x271, 0x2); /* OK */
4666 write_mchbar8(0x671, 0x2); /* OK */
4667 write_mchbar8(0x1e8, 0x4); /* OK */
4668 for (channel = 0; channel < NUM_CHANNELS; channel++)
4669 write_mchbar32(0x294 + (channel << 10),
4670 (info.populated_ranks_mask[channel] & 3) << 16);
4671 write_mchbar32(0x134, (read_mchbar32(0x134) & 0xfc01ffff) | 0x10000); /* OK */
4672 write_mchbar32(0x134, (read_mchbar32(0x134) & 0xfc85ffff) | 0x850000); /* OK */
4673 for (channel = 0; channel < NUM_CHANNELS; channel++)
4674 write_mchbar32(0x260 + (channel << 10),
4675 (read_mchbar32(0x260 + (channel << 10)) &
4676 ~0xf00000) | 0x8000000 | ((info.
4677 populated_ranks_mask
4678 [channel] & 3) <<
4679 20));
4680
4681 if (!s3resume)
4682 jedec_init(&info);
4683
4684 int totalrank = 0;
4685 for (channel = 0; channel < NUM_CHANNELS; channel++)
4686 for (slot = 0; slot < NUM_SLOTS; slot++)
4687 for (rank = 0; rank < NUM_RANKS; rank++)
4688 if (info.populated_ranks[channel][slot][rank]) {
4689 jedec_read(&info, channel, slot, rank,
4690 totalrank, 0xa, 0x400);
4691 totalrank++;
4692 }
4693
4694 write_mchbar8(0x12c, 0x9f);
4695
4696 read_mchbar8(0x271); // 2 // !!!!
4697 write_mchbar8(0x271, 0xe);
4698 read_mchbar8(0x671); // !!!!
4699 write_mchbar8(0x671, 0xe);
4700
4701 if (!s3resume) {
4702 for (channel = 0; channel < NUM_CHANNELS; channel++) {
4703 write_mchbar32(0x294 + (channel << 10),
4704 (info.
4705 populated_ranks_mask[channel] & 3) <<
4706 16);
4707 write_mchbar16(0x298 + (channel << 10),
4708 (info.
4709 populated_ranks[channel][0][0]) | (info.
4710 populated_ranks
4711 [channel]
4712 [0]
4713 [1]
4714 <<
4715 5));
4716 write_mchbar32(0x29c + (channel << 10), 0x77a);
4717 }
4718 read_mchbar32(0x2c0); /// !!!
4719 write_mchbar32(0x2c0, 0x6009cc00);
4720
4721 {
4722 u8 a, b;
4723 a = read_mchbar8(0x243); // !!!!
4724 b = read_mchbar8(0x643); // !!!!
4725 write_mchbar8(0x243, a | 2);
4726 write_mchbar8(0x643, b | 2);
4727 }
4728
4729 write_1d0(7, 0x19b, 3, 1);
4730 write_1d0(7, 0x1c0, 3, 1);
4731 write_1d0(4, 0x1c6, 4, 1);
4732 write_1d0(4, 0x1cc, 4, 1);
4733 read_1d0(0x151, 4); // = 0x408c6d74 // !!!!
4734 write_1d0(4, 0x151, 4, 1);
4735 write_mchbar32(0x584, 0xfffff);
4736 write_mchbar32(0x984, 0xfffff);
4737
4738 for (channel = 0; channel < NUM_CHANNELS; channel++)
4739 for (slot = 0; slot < NUM_SLOTS; slot++)
4740 for (rank = 0; rank < NUM_RANKS; rank++)
4741 if (info.
4742 populated_ranks[channel][slot]
4743 [rank])
4744 config_rank(&info, s3resume,
4745 channel, slot,
4746 rank);
4747
4748 write_mchbar8(0x243, 0x1);
4749 write_mchbar8(0x643, 0x1);
4750 }
4751
4752 /* was == 1 but is common */
4753 pcie_write_config16(NORTHBRIDGE, 0xc8, 3);
4754 write_26c(0, 0x820);
4755 write_26c(1, 0x820);
4756 write_mchbar32(0x130, read_mchbar32(0x130) | 2);
4757 /* end */
4758
4759 if (s3resume) {
4760 for (channel = 0; channel < NUM_CHANNELS; channel++) {
4761 write_mchbar32(0x294 + (channel << 10),
4762 (info.
4763 populated_ranks_mask[channel] & 3) <<
4764 16);
4765 write_mchbar16(0x298 + (channel << 10),
4766 (info.
4767 populated_ranks[channel][0][0]) | (info.
4768 populated_ranks
4769 [channel]
4770 [0]
4771 [1]
4772 <<
4773 5));
4774 write_mchbar32(0x29c + (channel << 10), 0x77a);
4775 }
4776 read_mchbar32(0x2c0); /// !!!
4777 write_mchbar32(0x2c0, 0x6009cc00);
4778 }
4779
4780 write_mchbar32(0xfa4, read_mchbar32(0xfa4) & ~0x01000002);
4781 write_mchbar32(0xfb0, 0x2000e019);
4782
4783#if !REAL
4784 printf("CP16\n");
4785#endif
4786
4787 /* Before training. */
4788 timestamp_add_now(103);
4789
4790 if (!s3resume)
4791 ram_training(&info);
4792
4793 /* After training. */
4794 timestamp_add_now (104);
4795
4796 dump_timings(&info);
4797
4798#if 0
4799 ram_check(0x100000, 0x200000);
4800#endif
4801 program_modules_memory_map(&info, 0);
4802 program_total_memory_map(&info);
4803
4804 if (info.non_interleaved_part_mb != 0 && info.interleaved_part_mb != 0)
4805 write_mchbar8(0x111, 0x20 | (0 << 2) | (1 << 6) | (0 << 7));
4806 else if (have_match_ranks(&info, 0, 4) && have_match_ranks(&info, 1, 4))
4807 write_mchbar8(0x111, 0x20 | (3 << 2) | (0 << 6) | (1 << 7));
4808 else if (have_match_ranks(&info, 0, 2) && have_match_ranks(&info, 1, 2))
4809 write_mchbar8(0x111, 0x20 | (3 << 2) | (0 << 6) | (0 << 7));
4810 else
4811 write_mchbar8(0x111, 0x20 | (3 << 2) | (1 << 6) | (0 << 7));
4812
4813 write_mchbar32(0xfac, read_mchbar32(0xfac) & ~0x80000000); // OK
4814 write_mchbar32(0xfb4, 0x4800); // OK
4815 write_mchbar32(0xfb8, (info.revision < 8) ? 0x20 : 0x0); // OK
4816 write_mchbar32(0xe94, 0x7ffff); // OK
4817 write_mchbar32(0xfc0, 0x80002040); // OK
4818 write_mchbar32(0xfc4, 0x701246); // OK
4819 write_mchbar8(0xfc8, read_mchbar8(0xfc8) & ~0x70); // OK
4820 write_mchbar32(0xe5c, 0x1000000 | read_mchbar32(0xe5c)); // OK
4821 write_mchbar32(0x1a70, (read_mchbar32(0x1a70) | 0x00200000) & ~0x00100000); // OK
4822 write_mchbar32(0x50, 0x700b0); // OK
4823 write_mchbar32(0x3c, 0x10); // OK
4824 write_mchbar8(0x1aa8, (read_mchbar8(0x1aa8) & ~0x35) | 0xa); // OK
4825 write_mchbar8(0xff4, read_mchbar8(0xff4) | 0x2); // OK
4826 write_mchbar32(0xff8, (read_mchbar32(0xff8) & ~0xe008) | 0x1020); // OK
4827
4828#if REAL
4829 write_mchbar32(0xd00, IOMMU_BASE2 | 1);
4830 write_mchbar32(0xd40, IOMMU_BASE1 | 1);
4831 write_mchbar32(0xdc0, IOMMU_BASE4 | 1);
4832
4833 write32(IOMMU_BASE1 | 0xffc, 0x80000000);
4834 write32(IOMMU_BASE2 | 0xffc, 0xc0000000);
4835 write32(IOMMU_BASE4 | 0xffc, 0x80000000);
4836
4837#else
4838 {
4839 u32 eax;
4840 eax = read32(0xffc + (read_mchbar32(0xd00) & ~1)) | 0x08000000; // = 0xe911714b// OK
4841 write32(0xffc + (read_mchbar32(0xd00) & ~1), eax); // OK
4842 eax = read32(0xffc + (read_mchbar32(0xdc0) & ~1)) | 0x40000000; // = 0xe911714b// OK
4843 write32(0xffc + (read_mchbar32(0xdc0) & ~1), eax); // OK
4844 }
4845#endif
4846
4847 {
4848 u32 eax;
4849
4850 eax = info.fsb_frequency / 9;
4851 write_mchbar32(0xfcc, (read_mchbar32(0xfcc) & 0xfffc0000) | (eax * 0x280) | (eax * 0x5000) | eax | 0x40000); // OK
4852 write_mchbar32(0x20, 0x33001); //OK
4853 }
4854
4855 for (channel = 0; channel < NUM_CHANNELS; channel++) {
4856 write_mchbar32(0x220 + (channel << 10), read_mchbar32(0x220 + (channel << 10)) & ~0x7770); //OK
4857 if (info.max_slots_used_in_channel == 1)
4858 write_mchbar16(0x237 + (channel << 10), (read_mchbar16(0x237 + (channel << 10)) | 0x0201)); //OK
4859 else
4860 write_mchbar16(0x237 + (channel << 10), (read_mchbar16(0x237 + (channel << 10)) & ~0x0201)); //OK
4861
4862 write_mchbar8(0x241 + (channel << 10), read_mchbar8(0x241 + (channel << 10)) | 1); // OK
4863
4864 if (info.clock_speed_index <= 1
4865 && (info.silicon_revision == 2
4866 || info.silicon_revision == 3))
4867 write_mchbar32(0x248 + (channel << 10), (read_mchbar32(0x248 + (channel << 10)) | 0x00102000)); // OK
4868 else
4869 write_mchbar32(0x248 + (channel << 10), (read_mchbar32(0x248 + (channel << 10)) & ~0x00102000)); // OK
4870 }
4871
4872 write_mchbar32(0x115, read_mchbar32(0x115) | 0x1000000); // OK
4873
4874 {
4875 u8 al;
4876 al = 0xd;
4877 if (!(info.silicon_revision == 0 || info.silicon_revision == 1))
4878 al += 2;
4879 al |= ((1 << (info.max_slots_used_in_channel - 1)) - 1) << 4;
4880 write_mchbar32(0x210, (al << 16) | 0x20); // OK
4881 }
4882
4883 for (channel = 0; channel < NUM_CHANNELS; channel++) {
4884 write_mchbar32(0x288 + (channel << 10), 0x70605040); // OK
4885 write_mchbar32(0x28c + (channel << 10), 0xfffec080); // OK
4886 write_mchbar32(0x290 + (channel << 10), 0x282091c | ((info.max_slots_used_in_channel - 1) << 0x16)); // OK
4887 }
4888 u32 reg1c;
4889 pcie_read_config32(NORTHBRIDGE, 0x40); // = DEFAULT_EPBAR | 0x001 // OK
4890 reg1c = read32(DEFAULT_EPBAR | 0x01c); // = 0x8001 // OK
4891 pcie_read_config32(NORTHBRIDGE, 0x40); // = DEFAULT_EPBAR | 0x001 // OK
4892 write32(DEFAULT_EPBAR | 0x01c, reg1c); // OK
4893 read_mchbar8(0xe08); // = 0x0
4894 pcie_read_config32(NORTHBRIDGE, 0xe4); // = 0x316126
4895 write_mchbar8(0x1210, read_mchbar8(0x1210) | 2); // OK
4896 write_mchbar32(0x1200, 0x8800440); // OK
4897 write_mchbar32(0x1204, 0x53ff0453); // OK
4898 write_mchbar32(0x1208, 0x19002043); // OK
4899 write_mchbar16(0x1214, 0x320); // OK
4900
4901 if (info.revision == 0x10 || info.revision == 0x11) {
4902 write_mchbar16(0x1214, 0x220); // OK
4903 write_mchbar8(0x1210, read_mchbar8(0x1210) | 0x40); // OK
4904 }
4905
4906 write_mchbar8(0x1214, read_mchbar8(0x1214) | 0x4); // OK
4907 write_mchbar8(0x120c, 0x1); // OK
4908 write_mchbar8(0x1218, 0x3); // OK
4909 write_mchbar8(0x121a, 0x3); // OK
4910 write_mchbar8(0x121c, 0x3); // OK
4911 write_mchbar16(0xc14, 0x0); // OK
4912 write_mchbar16(0xc20, 0x0); // OK
4913 write_mchbar32(0x1c, 0x0); // OK
4914
4915 /* revision dependent here. */
4916
4917 write_mchbar16(0x1230, read_mchbar16(0x1230) | 0x1f07); // OK
4918
4919 if (info.uma_enabled)
4920 write_mchbar32(0x11f4, read_mchbar32(0x11f4) | 0x10000000); // OK
4921
4922 write_mchbar16(0x1230, read_mchbar16(0x1230) | 0x8000); // OK
4923 write_mchbar8(0x1214, read_mchbar8(0x1214) | 1); // OK
4924
4925 u8 bl, ebpb;
4926 u16 reg_1020;
4927
4928 reg_1020 = read_mchbar32(0x1020); // = 0x6c733c // OK
4929 write_mchbar8(0x1070, 0x1); // OK
4930
4931 write_mchbar32(0x1000, 0x100); // OK
4932 write_mchbar8(0x1007, 0x0); // OK
4933
4934 if (reg_1020 != 0) {
4935 write_mchbar16(0x1018, 0x0); // OK
4936 bl = reg_1020 >> 8;
4937 ebpb = reg_1020 & 0xff;
4938 } else {
4939 ebpb = 0;
4940 bl = 8;
4941 }
4942
4943 rdmsr(0x1a2);
4944
4945 write_mchbar32(0x1014, 0xffffffff); // OK
4946
4947 write_mchbar32(0x1010, ((((ebpb + 0x7d) << 7) / bl) & 0xff) * (! !reg_1020)); // OK
4948
4949 write_mchbar8(0x101c, 0xb8); // OK
4950
4951 write_mchbar8(0x123e, (read_mchbar8(0x123e) & 0xf) | 0x60); // OK
4952 if (reg_1020 != 0) {
4953 write_mchbar32(0x123c, (read_mchbar32(0x123c) & ~0x00900000) | 0x600000); // OK
4954 write_mchbar8(0x101c, 0xb8); // OK
4955 }
4956
4957 setup_heci_uma(&info);
4958
4959 if (info.uma_enabled) {
4960 u16 ax;
4961 write_mchbar32(0x11b0, read_mchbar32(0x11b0) | 0x4000); // OK
4962 write_mchbar32(0x11b4, read_mchbar32(0x11b4) | 0x4000); // OK
4963 write_mchbar16(0x1190, read_mchbar16(0x1190) | 0x4000); // OK
4964
4965 ax = read_mchbar16(0x1190) & 0xf00; // = 0x480a // OK
4966 write_mchbar16(0x1170, ax | (read_mchbar16(0x1170) & 0x107f) | 0x4080); // OK
4967 write_mchbar16(0x1170, read_mchbar16(0x1170) | 0x1000); // OK
4968#if REAL
4969 udelay(1000);
4970#endif
4971 u16 ecx;
4972 for (ecx = 0xffff; ecx && (read_mchbar16(0x1170) & 0x1000); ecx--) ; // OK
4973 write_mchbar16(0x1190, read_mchbar16(0x1190) & ~0x4000); // OK
4974 }
4975
4976 pcie_write_config8(SOUTHBRIDGE, GEN_PMCON_2,
4977 pcie_read_config8(SOUTHBRIDGE, GEN_PMCON_2) & ~0x80);
4978 udelay(10000);
4979 write_mchbar16(0x2ca8, 0x0);
4980
4981#if REAL
4982 udelay(1000);
4983 dump_timings(&info);
4984 if (!s3resume)
4985 save_timings(&info);
4986#endif
4987}
4988
4989#if REAL
4990unsigned long get_top_of_ram(void)
4991{
4992 /* Base of TSEG is top of usable DRAM */
4993 u32 tom = pci_read_config32(PCI_DEV(0, 0, 0), TSEG);
4994 return (unsigned long)tom;
4995}
4996#endif