blob: 25ba6c25bff8f38be1107b5dcdbbe2db81a969da [file] [log] [blame]
Stefan Reinauer278534d2008-10-29 04:51:07 +00001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2007-2008 coresystems GmbH
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; version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20
21#include <cpu/x86/mem.h>
22#include <cpu/x86/mtrr.h>
23#include <cpu/x86/cache.h>
24#include <spd.h>
25#include "raminit.h"
26#include "i945.h"
27
28#include "lib/memset.c"
29
30#define DEBUG_RAM_SETUP
31
32/* Debugging macros. */
33#if defined(DEBUG_RAM_SETUP)
34#define PRINTK_DEBUG(x...) printk_debug(x)
35#else
36#define PRINTK_DEBUG(x...)
37#endif
38
39
40#define RAM_INITIALIZATION_COMPLETE (1 << 19)
41
42#define RAM_COMMAND_SELF_REFRESH (0x0 << 16)
43#define RAM_COMMAND_NOP (0x1 << 16)
44#define RAM_COMMAND_PRECHARGE (0x2 << 16)
45#define RAM_COMMAND_MRS (0x3 << 16)
46#define RAM_COMMAND_EMRS (0x4 << 16)
47#define RAM_COMMAND_CBR (0x6 << 16)
48#define RAM_COMMAND_NORMAL (0x7 << 16)
49
50#define RAM_EMRS_1 (0x0 << 21)
51#define RAM_EMRS_2 (0x1 << 21)
52#define RAM_EMRS_3 (0x2 << 21)
53
54static void do_ram_command(u32 command)
55{
56 u32 reg32;
57
58 reg32 = MCHBAR32(DCC);
59 reg32 &= ~( (3<<21) | (1<<20) | (1<<19) | (7 << 16) );
60 reg32 |= command;
61
62 /* Also set Init Complete */
63 if (command == RAM_COMMAND_NORMAL)
64 reg32 |= RAM_INITIALIZATION_COMPLETE;
65
66 PRINTK_DEBUG(" Sending RAM command 0x%08x", reg32);
67
68 MCHBAR32(DCC) = reg32; /* This is the actual magic */
69
Stefan Reinauer779b3e32008-11-10 15:43:37 +000070 PRINTK_DEBUG("...done\n");
Stefan Reinauer278534d2008-10-29 04:51:07 +000071}
72
73
74static void ram_read32(u32 offset)
75{
Stefan Reinauer779b3e32008-11-10 15:43:37 +000076 PRINTK_DEBUG(" ram read: %08x\n", offset);
Stefan Reinauer278534d2008-10-29 04:51:07 +000077
78 read32(offset);
79}
80
81#ifdef DEBUG_RAM_SETUP
82static void sdram_dump_mchbar_registers(void)
83{
84 int i;
Stefan Reinauer779b3e32008-11-10 15:43:37 +000085 printk_debug("Dumping MCHBAR Registers\n");
Stefan Reinauer278534d2008-10-29 04:51:07 +000086
87 for (i=0; i<0xfff; i+=4) {
88 if (MCHBAR32(i) == 0)
89 continue;
Stefan Reinauer779b3e32008-11-10 15:43:37 +000090 printk_debug("0x%04x: 0x%08x\n", i, MCHBAR32(i));
Stefan Reinauer278534d2008-10-29 04:51:07 +000091 }
92}
93#endif
94
95static int sdram_capabilities_max_supported_memory_frequency(void)
96{
97 u32 reg32;
98
99 reg32 = pci_read_config32(PCI_DEV(0, 0x00, 0), 0xe4);
100 reg32 &= (7 << 0);
101
102 switch (reg32) {
103 case 4: return 400;
104 case 3: return 533;
105 case 2: return 667;
106 }
107 /* Newer revisions of this chipset rather support faster memory clocks,
108 * so if it's a reserved value, return the fastest memory clock that we
109 * know of and can handle
110 */
111 return 667;
112}
113
114/**
115 * @brief determine whether chipset is capable of dual channel interleaved mode
116 *
117 * @return 1 if interleaving is supported, 0 otherwise
118 */
119static int sdram_capabilities_interleave(void)
120{
121 u32 reg32;
122
123 reg32 = pci_read_config8(PCI_DEV(0, 0x00,0), 0xe4);
124 reg32 >>= 25;
125 reg32 &= 1;
126
127 return (!reg32);
128}
129
130/**
131 * @brief determine whether chipset is capable of two memory channels
132 *
133 * @return 1 if dual channel operation is supported, 0 otherwise
134 */
135static int sdram_capabilities_dual_channel(void)
136{
137 u32 reg32;
138
139 reg32 = pci_read_config8(PCI_DEV(0, 0x00,0), 0xe4);
140 reg32 >>= 24;
141 reg32 &= 1;
142
143 return (!reg32);
144}
145
146static int sdram_capabilities_enhanced_addressing_xor(void)
147{
148 u8 reg8;
149
150 reg8 = pci_read_config8(PCI_DEV(0, 0x00, 0), 0xe5); /* CAPID0 + 5 */
151 reg8 &= (1 << 7);
152
153 return (!reg8);
154}
155
156static int sdram_capabilities_two_dimms_per_channel(void)
157{
158 u8 reg8;
159
160 reg8 = pci_read_config8(PCI_DEV(0, 0x00, 0), 0xe8); /* CAPID0 + 8 */
161 reg8 &= (1 << 0);
162
163 return (reg8 != 0);
164}
165
166static int sdram_capabilities_MEM4G_disable(void)
167{
168 u8 reg8;
169
170 reg8 = pci_read_config8(PCI_DEV(0, 0x00, 0), 0xe5);
171 reg8 &= (1 << 0);
172
173 return (reg8 != 0);
174}
175
176static void sdram_detect_errors(void)
177{
178 u8 reg8;
179
180 reg8 = pci_read_config8(PCI_DEV(0, 0x1f, 0), 0xa2);
181
182 if (reg8 & ((1<<7)|(1<<2))) {
183 if (reg8 & (1<<2)) {
Stefan Reinauer779b3e32008-11-10 15:43:37 +0000184 printk_debug("SLP S4# Assertion Width Violation.\n");
Stefan Reinauer278534d2008-10-29 04:51:07 +0000185
186 pci_write_config8(PCI_DEV(0, 0x1f, 0), 0xa2, reg8);
187 }
188
189 if (reg8 & (1<<7)) {
Stefan Reinauer779b3e32008-11-10 15:43:37 +0000190 printk_debug("DRAM initialization was interrupted.\n");
Stefan Reinauer278534d2008-10-29 04:51:07 +0000191 reg8 &= ~(1<<7);
192 pci_write_config8(PCI_DEV(0, 0x1f, 0), 0xa2, reg8);
193 }
194
195 /* Set SLP_S3# Assertion Stretch Enable */
196 reg8 = pci_read_config8(PCI_DEV(0, 0x1f, 0), 0xa4); /* GEN_PMCON_3 */
197 reg8 |= (1 << 3);
198 pci_write_config8(PCI_DEV(0, 0x1f, 0), 0xa4, reg8);
199
Stefan Reinauer779b3e32008-11-10 15:43:37 +0000200 printk_debug("Reset required.\n");
Stefan Reinauer278534d2008-10-29 04:51:07 +0000201 outb(0x00, 0xcf9);
202 outb(0x0e, 0xcf9);
203 for (;;) ; /* Wait for reset! */
204 }
205
206 /* Set DRAM initialization bit in ICH7 */
207 reg8 = pci_read_config8(PCI_DEV(0, 0x1f, 0), 0xa2);
208 reg8 |= (1<<7);
209 pci_write_config8(PCI_DEV(0, 0x1f, 0), 0xa2, reg8);
210
211}
212
213
214/**
215 * @brief Get generic DIMM parameters.
216 * @param sysinfo Central memory controller information structure
217 *
218 * This function gathers several pieces of information for each system DIMM:
219 * o DIMM width (x8 / x16)
220 * o DIMM sides (single sided / dual sided)
221 *
222 * Also, some non-supported scenarios are detected.
223 */
224
225static void sdram_get_dram_configuration(struct sys_info *sysinfo)
226{
227 u32 dimm_mask = 0;
228 int i;
229
230 /**
231 * i945 supports two DIMMs, in two configurations:
232 *
233 * - single channel with two dimms
234 * - dual channel with one dimm per channel
235 *
236 * In practice dual channel mainboards have their spd at 0x50, 0x52
237 * whereas single channel configurations have their spd at 0x50/x51
238 *
239 * The capability register knows a lot about the channel configuration
240 * but for now we stick with the information we gather from the SPD
241 * ROMs
242 */
243
244 if (sdram_capabilities_dual_channel()) {
245 sysinfo->dual_channel = 1;
246 printk_debug("This mainboard supports Dual Channel Operation.\n");
247 } else {
248 sysinfo->dual_channel = 0;
249 printk_debug("This mainboard supports only Single Channel Operation.\n");
250 }
251
252 /**
253 * Since we only support two DIMMs in total, there is a limited number
254 * of combinations. This function returns the type of DIMMs.
255 * return value:
256 * [0:7] lower DIMM population
257 * [8-15] higher DIMM population
258 * [16] dual channel?
259 *
260 * There are 5 different possible populations for a DIMM socket:
261 * 1. x16 double sided (X16DS)
262 * 2. x8 double sided (X8DS)
263 * 3. x16 single sided (X16SS)
264 * 4. x8 double stacked (X8DDS)
265 * 5. not populated (NC)
266 *
267 * For the return value we start counting at zero.
268 *
269 */
270
271 for (i=0; i<(2 * DIMM_SOCKETS); i++) {
272 u8 reg8, device = DIMM_SPD_BASE + i;
273
274 /* Initialize the socket information with a sane value */
275 sysinfo->dimm[i] = SYSINFO_DIMM_NOT_POPULATED;
276
277 if (!sdram_capabilities_dual_channel() && (i >> 1))
278 continue;
279 if (!sdram_capabilities_two_dimms_per_channel() && (i& 1))
280 continue;
281
282 printk_debug("DDR II Channel %d Socket %d: ", (i >> 1), (i & 1));
283
284 if (spd_read_byte(device, SPD_MEMORY_TYPE) != SPD_MEMORY_TYPE_SDRAM_DDR2) {
285 printk_debug("N/A\n");
286 continue;
287 }
288
289 reg8 = spd_read_byte(device, SPD_DIMM_CONFIG_TYPE);
290 if (reg8 == ERROR_SCHEME_ECC)
Stefan Reinauer779b3e32008-11-10 15:43:37 +0000291 die("Error: ECC memory not supported by this chipset\n");
Stefan Reinauer278534d2008-10-29 04:51:07 +0000292
293 reg8 = spd_read_byte(device, SPD_MODULE_ATTRIBUTES);
294 if (reg8 & MODULE_BUFFERED)
Stefan Reinauer779b3e32008-11-10 15:43:37 +0000295 die("Error: Buffered memory not supported by this chipset\n");
Stefan Reinauer278534d2008-10-29 04:51:07 +0000296 if (reg8 & MODULE_REGISTERED)
Stefan Reinauer779b3e32008-11-10 15:43:37 +0000297 die("Error: Registered memory not supported by this chipset\n");
Stefan Reinauer278534d2008-10-29 04:51:07 +0000298
299 switch (spd_read_byte(device, SPD_PRIMARY_SDRAM_WIDTH)) {
300 case 0x08:
301 switch (spd_read_byte(device, SPD_NUM_DIMM_BANKS) & 0x0f) {
302 case 1:
Stefan Reinauer779b3e32008-11-10 15:43:37 +0000303 printk_debug("x8DDS\n");
Stefan Reinauer278534d2008-10-29 04:51:07 +0000304 sysinfo->dimm[i] = SYSINFO_DIMM_X8DDS;
305 break;
306 case 0:
Stefan Reinauer779b3e32008-11-10 15:43:37 +0000307 printk_debug("x8DS\n");
Stefan Reinauer278534d2008-10-29 04:51:07 +0000308 sysinfo->dimm[i] = SYSINFO_DIMM_X8DS;
309 break;
310 default:
Stefan Reinauer779b3e32008-11-10 15:43:37 +0000311 printk_debug ("Unsupported.\n");
Stefan Reinauer278534d2008-10-29 04:51:07 +0000312 }
313 break;
314 case 0x10:
315 switch (spd_read_byte(device, SPD_NUM_DIMM_BANKS) & 0x0f) {
316 case 1:
Stefan Reinauer779b3e32008-11-10 15:43:37 +0000317 printk_debug("x16DS\n");
Stefan Reinauer278534d2008-10-29 04:51:07 +0000318 sysinfo->dimm[i] = SYSINFO_DIMM_X16DS;
319 break;
320 case 0:
Stefan Reinauer779b3e32008-11-10 15:43:37 +0000321 printk_debug("x16SS\n");
Stefan Reinauer278534d2008-10-29 04:51:07 +0000322 sysinfo->dimm[i] = SYSINFO_DIMM_X16SS;
323 break;
324 default:
Stefan Reinauer779b3e32008-11-10 15:43:37 +0000325 printk_debug ("Unsupported.\n");
Stefan Reinauer278534d2008-10-29 04:51:07 +0000326 }
327 break;
328 default:
Stefan Reinauer779b3e32008-11-10 15:43:37 +0000329 die("Unsupported DDR-II memory width.\n");
Stefan Reinauer278534d2008-10-29 04:51:07 +0000330 }
331
332 dimm_mask |= (1 << i);
333 }
334
335 if (!dimm_mask) {
Stefan Reinauer779b3e32008-11-10 15:43:37 +0000336 die("No memory installed.\n");
Stefan Reinauer278534d2008-10-29 04:51:07 +0000337 }
338
339 /* The chipset might be able to do this. What the heck, legacy bios
340 * just beeps when a single DIMM is in the Channel 1 socket. So let's
341 * not bother until someone needs this enough to cope with it.
342 */
343 if (!(dimm_mask & ((1 << DIMM_SOCKETS) - 1))) {
Stefan Reinauer779b3e32008-11-10 15:43:37 +0000344 printk_err("Channel 0 has no memory populated. This setup is not usable. Please move the DIMM.\n");
Stefan Reinauer278534d2008-10-29 04:51:07 +0000345 }
346}
347
348/**
349 * @brief determine if any DIMMs are stacked
350 *
351 * @param sysinfo central sysinfo data structure.
352 */
353static void sdram_verify_package_type(struct sys_info * sysinfo)
354{
355 int i;
356
357 /* Assume no stacked DIMMs are available until we find one */
358 sysinfo->package = 0;
359 for (i=0; i<2*DIMM_SOCKETS; i++) {
360 if (sysinfo->dimm[i] == SYSINFO_DIMM_NOT_POPULATED)
361 continue;
362
363 /* Is the current DIMM a stacked DIMM? */
364 if (spd_read_byte(DIMM_SPD_BASE + i, SPD_NUM_DIMM_BANKS) & (1 << 4))
365 sysinfo->package = 1;
366 }
367}
368
369static u8 sdram_possible_cas_latencies(struct sys_info * sysinfo)
370{
371 int i;
372 u8 cas_mask;
373
374 /* Setup CAS mask with all supported CAS Latencies */
375 cas_mask = SPD_CAS_LATENCY_DDR2_3 |
376 SPD_CAS_LATENCY_DDR2_4 |
377 SPD_CAS_LATENCY_DDR2_5;
378
379 for (i=0; i<2*DIMM_SOCKETS; i++) {
380 if (sysinfo->dimm[i] != SYSINFO_DIMM_NOT_POPULATED)
381 cas_mask &= spd_read_byte(DIMM_SPD_BASE + i, SPD_ACCEPTABLE_CAS_LATENCIES);
382 }
383
384 if(!cas_mask) {
385 die("No DDR-II modules with accepted CAS latencies found.\n");
386 }
387
388 return cas_mask;
389}
390
391static void sdram_detect_cas_latency_and_ram_speed(struct sys_info * sysinfo, u8 cas_mask)
392{
393 int i, j, idx;
394 int lowest_common_cas = 0;
395 int max_ram_speed;
396
397 const u8 ddr2_speeds_table[] = {
398 0x50, 0x60, /* DDR2 400: tCLK = 5.0ns tAC = 0.6ns */
399 0x3d, 0x50, /* DDR2 533: tCLK = 3.75ns tAC = 0.5ns */
400 0x30, 0x45, /* DDR2 667: tCLK = 3.0ns tAC = 0.45ns */
401 };
402
403 const u8 spd_lookup_table[] = {
404 SPD_MIN_CYCLE_TIME_AT_CAS_MAX, SPD_ACCESS_TIME_FROM_CLOCK,
405 SPD_SDRAM_CYCLE_TIME_2ND, SPD_ACCESS_TIME_FROM_CLOCK_2ND,
406 SPD_SDRAM_CYCLE_TIME_3RD, SPD_ACCESS_TIME_FROM_CLOCK_3RD
407 };
408
409 switch (sdram_capabilities_max_supported_memory_frequency()) {
410 case 400: max_ram_speed = 0; break;
411 case 533: max_ram_speed = 1; break;
412 case 667: max_ram_speed = 2; break;
413 }
414
415 sysinfo->memory_frequency = 0;
416 sysinfo->cas = 0;
417
418 if (cas_mask & SPD_CAS_LATENCY_DDR2_3) {
419 lowest_common_cas = 3;
420 } else if (cas_mask & SPD_CAS_LATENCY_DDR2_4) {
421 lowest_common_cas = 4;
422 } else if (cas_mask & SPD_CAS_LATENCY_DDR2_5) {
423 lowest_common_cas = 5;
424 }
425 PRINTK_DEBUG("lowest common cas = %d\n", lowest_common_cas);
426
427 for (j = max_ram_speed; j>=0; j--) {
428 int freq_cas_mask = cas_mask;
429
430 PRINTK_DEBUG("Probing Speed %d\n", j);
431 for (i=0; i<2*DIMM_SOCKETS; i++) {
432 int current_cas_mask;
433
434 PRINTK_DEBUG(" DIMM: %d\n", i);
435 if (sysinfo->dimm[i] == SYSINFO_DIMM_NOT_POPULATED) {
436 continue;
437 }
438
439 current_cas_mask = spd_read_byte(DIMM_SPD_BASE + i, SPD_ACCEPTABLE_CAS_LATENCIES);
440
441 while (current_cas_mask) {
442 int highest_supported_cas = 0, current_cas = 0;
443 PRINTK_DEBUG(" Current CAS mask: %04x; ", current_cas_mask);
444 if (current_cas_mask & SPD_CAS_LATENCY_DDR2_5) {
445 highest_supported_cas = 5;
446 } else if (current_cas_mask & SPD_CAS_LATENCY_DDR2_4) {
447 highest_supported_cas = 4;
448 } else if (current_cas_mask & SPD_CAS_LATENCY_DDR2_3) {
449 highest_supported_cas = 3;
450 }
451 if (current_cas_mask & SPD_CAS_LATENCY_DDR2_3) {
452 current_cas = 3;
453 } else if (current_cas_mask & SPD_CAS_LATENCY_DDR2_4) {
454 current_cas = 4;
455 } else if (current_cas_mask & SPD_CAS_LATENCY_DDR2_5) {
456 current_cas = 5;
457 }
458
459 idx = highest_supported_cas - current_cas;
460 PRINTK_DEBUG("idx=%d, ", idx);
461 PRINTK_DEBUG("tCLK=%x, ", spd_read_byte(DIMM_SPD_BASE + i, spd_lookup_table[2*idx]));
462 PRINTK_DEBUG("tAC=%x", spd_read_byte(DIMM_SPD_BASE + i, spd_lookup_table[(2*idx)+1]));
463
464 if (spd_read_byte(DIMM_SPD_BASE + i, spd_lookup_table[2*idx]) <= ddr2_speeds_table[2*j] &&
465 spd_read_byte(DIMM_SPD_BASE + i, spd_lookup_table[(2*idx)+1]) <= ddr2_speeds_table[(2*j)+1]) {
466 PRINTK_DEBUG(": OK\n");
467 break;
468 }
469
470 PRINTK_DEBUG(": Not fast enough!\n");
471
472 current_cas_mask &= ~(1 << (current_cas));
473 }
474
475 freq_cas_mask &= current_cas_mask;
476 if (!current_cas_mask) {
477 PRINTK_DEBUG(" No valid CAS for this speed on DIMM %d\n", i);
478 break;
479 }
480 }
481 PRINTK_DEBUG(" freq_cas_mask for speed %d: %04x\n", j, freq_cas_mask);
482 if (freq_cas_mask) {
483 switch (j) {
484 case 0: sysinfo->memory_frequency = 400; break;
485 case 1: sysinfo->memory_frequency = 533; break;
486 case 2: sysinfo->memory_frequency = 667; break;
487 }
488 if (freq_cas_mask & SPD_CAS_LATENCY_DDR2_3) {
489 sysinfo->cas = 3;
490 } else if (freq_cas_mask & SPD_CAS_LATENCY_DDR2_4) {
491 sysinfo->cas = 4;
492 } else if (freq_cas_mask & SPD_CAS_LATENCY_DDR2_5) {
493 sysinfo->cas = 5;
494 }
495 break;
496 }
497 }
498
499 if (sysinfo->memory_frequency && sysinfo->cas) {
Stefan Reinauer977ed2d2009-01-20 22:46:52 +0000500 printk_debug("Memory will be driven at %dMHz with CAS=%d clocks\n",
Stefan Reinauer278534d2008-10-29 04:51:07 +0000501 sysinfo->memory_frequency, sysinfo->cas);
502 } else {
503 die("Could not find common memory frequency and CAS\n");
504 }
505}
506
507static void sdram_detect_smallest_tRAS(struct sys_info * sysinfo)
508{
509 int i;
510 int tRAS_time;
511 int tRAS_cycles;
512 int freq_multiplier = 0;
513
514 switch (sysinfo->memory_frequency) {
515 case 400: freq_multiplier = 0x14; break; /* 5ns */
516 case 533: freq_multiplier = 0x0f; break; /* 3.75ns */
517 case 667: freq_multiplier = 0x0c; break; /* 3ns */
518 }
519
520 tRAS_cycles = 4; /* 4 clocks minimum */
521 tRAS_time = tRAS_cycles * freq_multiplier;
522
523 for (i=0; i<2*DIMM_SOCKETS; i++) {
524 u8 reg8;
525
526 if (sysinfo->dimm[i] == SYSINFO_DIMM_NOT_POPULATED)
527 continue;
528
529 reg8 = spd_read_byte(DIMM_SPD_BASE + i, SPD_MIN_ACTIVE_TO_PRECHARGE_DELAY);
530 if (!reg8) {
531 die("Invalid tRAS value.\n");
532 }
533
534 while ((tRAS_time >> 2) < reg8) {
535 tRAS_time += freq_multiplier;
536 tRAS_cycles++;
537 }
538 }
539 if(tRAS_cycles > 0x18) {
540 die("DDR-II Module does not support this frequency (tRAS error)\n");
541 }
542
543 printk_debug("tRAS = %d cycles\n", tRAS_cycles);
544 sysinfo->tras = tRAS_cycles;
545}
546
547static void sdram_detect_smallest_tRP(struct sys_info * sysinfo)
548{
549 int i;
550 int tRP_time;
551 int tRP_cycles;
552 int freq_multiplier = 0;
553
554 switch (sysinfo->memory_frequency) {
555 case 400: freq_multiplier = 0x14; break; /* 5ns */
556 case 533: freq_multiplier = 0x0f; break; /* 3.75ns */
557 case 667: freq_multiplier = 0x0c; break; /* 3ns */
558 }
559
560 tRP_cycles = 2; /* 2 clocks minimum */
561 tRP_time = tRP_cycles * freq_multiplier;
562
563 for (i=0; i<2*DIMM_SOCKETS; i++) {
564 u8 reg8;
565
566 if (sysinfo->dimm[i] == SYSINFO_DIMM_NOT_POPULATED)
567 continue;
568
569 reg8 = spd_read_byte(DIMM_SPD_BASE + i, SPD_MIN_ROW_PRECHARGE_TIME);
570 if (!reg8) {
571 die("Invalid tRP value.\n");
572 }
573
574 while (tRP_time < reg8) {
575 tRP_time += freq_multiplier;
576 tRP_cycles++;
577 }
578 }
579
580 if(tRP_cycles > 6) {
581 die("DDR-II Module does not support this frequency (tRP error)\n");
582 }
583
584 printk_debug("tRP = %d cycles\n", tRP_cycles);
585 sysinfo->trp = tRP_cycles;
586}
587
588static void sdram_detect_smallest_tRCD(struct sys_info * sysinfo)
589{
590 int i;
591 int tRCD_time;
592 int tRCD_cycles;
593 int freq_multiplier = 0;
594
595 switch (sysinfo->memory_frequency) {
596 case 400: freq_multiplier = 0x14; break; /* 5ns */
597 case 533: freq_multiplier = 0x0f; break; /* 3.75ns */
598 case 667: freq_multiplier = 0x0c; break; /* 3ns */
599 }
600
601 tRCD_cycles = 2;
602 tRCD_time = tRCD_cycles * freq_multiplier;
603
604 for (i=0; i<2*DIMM_SOCKETS; i++) {
605 u8 reg8;
606
607 if (sysinfo->dimm[i] == SYSINFO_DIMM_NOT_POPULATED)
608 continue;
609
610 reg8 = spd_read_byte(DIMM_SPD_BASE + i, SPD_MIN_RAS_TO_CAS_DELAY);
611 if (!reg8) {
612 die("Invalid tRCD value.\n");
613 }
614
615 while (tRCD_time < reg8) {
616 tRCD_time += freq_multiplier;
617 tRCD_cycles++;
618 }
619 }
620 if(tRCD_cycles > 6) {
621 die("DDR-II Module does not support this frequency (tRCD error)\n");
622 }
623
624 printk_debug("tRCD = %d cycles\n", tRCD_cycles);
625 sysinfo->trcd = tRCD_cycles;
626}
627
628static void sdram_detect_smallest_tWR(struct sys_info * sysinfo)
629{
630 int i;
631 int tWR_time;
632 int tWR_cycles;
633 int freq_multiplier = 0;
634
635 switch (sysinfo->memory_frequency) {
636 case 400: freq_multiplier = 0x14; break; /* 5ns */
637 case 533: freq_multiplier = 0x0f; break; /* 3.75ns */
638 case 667: freq_multiplier = 0x0c; break; /* 3ns */
639 }
640
641 tWR_cycles = 2; /* 2 clocks minimum */
642 tWR_time = tWR_cycles * freq_multiplier;
643
644 for (i=0; i<2*DIMM_SOCKETS; i++) {
645 u8 reg8;
646
647 if (sysinfo->dimm[i] == SYSINFO_DIMM_NOT_POPULATED)
648 continue;
649
650 reg8 = spd_read_byte(DIMM_SPD_BASE + i, SPD_WRITE_RECOVERY_TIME);
651 if (!reg8) {
652 die("Invalid tWR value.\n");
653 }
654
655 while (tWR_time < reg8) {
656 tWR_time += freq_multiplier;
657 tWR_cycles++;
658 }
659 }
660 if(tWR_cycles > 5) {
661 die("DDR-II Module does not support this frequency (tWR error)\n");
662 }
663
664 printk_debug("tWR = %d cycles\n", tWR_cycles);
665 sysinfo->twr = tWR_cycles;
666}
667
668static void sdram_detect_smallest_tRFC(struct sys_info * sysinfo)
669{
670 int i, index = 0;
671
672 const u8 tRFC_cycles[] = {
673 /* 75 105 127.5 */
674 15, 21, 26, /* DDR2-400 */
675 20, 28, 34, /* DDR2-533 */
676 25, 35, 43 /* DDR2-667 */
677 };
678
679 for (i=0; i<2*DIMM_SOCKETS; i++) {
680 u8 reg8;
681
682 if (sysinfo->dimm[i] == SYSINFO_DIMM_NOT_POPULATED)
683 continue;
684
685 reg8 = sysinfo->banksize[i*2];
686 switch (reg8) {
687 case 0x04: reg8 = 0; break;
688 case 0x08: reg8 = 1; break;
689 case 0x10: reg8 = 2; break;
690 case 0x20: reg8 = 3; break;
691 }
692
693 if (sysinfo->dimm[i] == SYSINFO_DIMM_X16DS || sysinfo->dimm[i] == SYSINFO_DIMM_X16SS)
694 reg8++;
695
696 if (reg8 > 3) {
697 /* Can this happen? Go back to 127.5ns just to be sure
698 * we don't run out of the array. This may be wrong
699 */
700 printk_debug("DIMM %d is 1Gb x16.. Please report.\n", i);
701 reg8 = 3;
702 }
703
704 if (reg8 > index)
705 index = reg8;
706
707 }
708 index--;
709 switch (sysinfo->memory_frequency) {
710 case 667: index += 3;
711 case 533: index += 3;
712 case 400: break;
713 }
714
715 sysinfo->trfc = tRFC_cycles[index];
716 printk_debug("tRFC = %d cycles\n", tRFC_cycles[index]);
717}
718
719
720static void sdram_detect_smallest_refresh(struct sys_info * sysinfo)
721{
722 int i;
723
724 sysinfo->refresh = 0;
725
726 for (i=0; i<2*DIMM_SOCKETS; i++) {
727 int refresh;
728
729 if (sysinfo->dimm[i] == SYSINFO_DIMM_NOT_POPULATED)
730 continue;
731
732 refresh = spd_read_byte(DIMM_SPD_BASE + i, SPD_REFRESH) & ~(1 << 7);
733
734 /* 15.6us */
735 if (!refresh)
736 continue;
737
738 /* Refresh is slower than 15.6us, use 15.6us */
739 if (refresh > 2)
740 continue;
741
742 if (refresh == 2) {
743 sysinfo->refresh = 1;
744 break;
745 }
746
747 die("DDR-II module has unsupported refresh value\n");
748 }
749 printk_debug("Refresh: %s\n", sysinfo->refresh?"7.8us":"15.6us");
750}
751
752static void sdram_verify_burst_length(struct sys_info * sysinfo)
753{
754 int i;
755
756 for (i=0; i<2*DIMM_SOCKETS; i++) {
757 if (sysinfo->dimm[i] == SYSINFO_DIMM_NOT_POPULATED)
758 continue;
759
760 if (!(spd_read_byte(DIMM_SPD_BASE + i, SPD_SUPPORTED_BURST_LENGTHS) & SPD_BURST_LENGTH_8))
761 die("Only DDR-II RAM with burst length 8 is supported by this chipset.\n");
762 }
763}
764
765static void sdram_program_dram_width(struct sys_info * sysinfo)
766{
767 u16 c0dramw=0, c1dramw=0;
768 int idx;
769
770 if (sysinfo->dual_channel)
771 idx = 2;
772 else
773 idx = 1;
774
775 switch (sysinfo->dimm[0]) {
776 case 0: c0dramw = 0x0000; break; /* x16DS */
777 case 1: c0dramw = 0x0001; break; /* x8DS */
778 case 2: c0dramw = 0x0000; break; /* x16SS */
779 case 3: c0dramw = 0x0005; break; /* x8DDS */
780 case 4: c0dramw = 0x0000; break; /* NC */
781 }
782
783 switch (sysinfo->dimm[idx]) {
784 case 0: c1dramw = 0x0000; break; /* x16DS */
785 case 1: c1dramw = 0x0010; break; /* x8DS */
786 case 2: c1dramw = 0x0000; break; /* x16SS */
787 case 3: c1dramw = 0x0050; break; /* x8DDS */
788 case 4: c1dramw = 0x0000; break; /* NC */
789 }
790
791 if ( !sdram_capabilities_dual_channel() ) {
792 /* Single Channel */
793 c0dramw |= c1dramw;
794 c1dramw = 0;
795 }
796
797 MCHBAR16(C0DRAMW) = c0dramw;
798 MCHBAR16(C1DRAMW) = c1dramw;
799}
800
801static void sdram_write_slew_rates(u32 offset, const u32 *slew_rate_table)
802{
803 int i;
804
805 for (i=0; i<16; i++)
806 MCHBAR32(offset+(i*4)) = slew_rate_table[i];
807}
808
809static void sdram_rcomp_buffer_strength_and_slew(struct sys_info *sysinfo)
810{
811 static const u32 dq2030[] = {
812 0x08070706, 0x0a090908, 0x0d0c0b0a, 0x12100f0e,
813 0x1a181614, 0x22201e1c, 0x2a282624, 0x3934302d,
814 0x0a090908, 0x0c0b0b0a, 0x0e0d0d0c, 0x1211100f,
815 0x19171513, 0x211f1d1b, 0x2d292623, 0x3f393531
816 };
817
818 static const u32 dq2330[] = {
819 0x08070706, 0x0a090908, 0x0d0c0b0a, 0x12100f0e,
820 0x1a181614, 0x22201e1c, 0x2a282624, 0x3934302d,
821 0x0a090908, 0x0c0b0b0a, 0x0e0d0d0c, 0x1211100f,
822 0x19171513, 0x211f1d1b, 0x2d292623, 0x3f393531
823 };
824
825 static const u32 cmd2710[] = {
826 0x07060605, 0x0f0d0b09, 0x19171411, 0x1f1f1d1b,
827 0x1f1f1f1f, 0x1f1f1f1f, 0x1f1f1f1f, 0x1f1f1f1f,
828
829 0x1110100f, 0x0f0d0b09, 0x19171411, 0x1f1f1d1b,
830 0x1f1f1f1f, 0x1f1f1f1f, 0x1f1f1f1f, 0x1f1f1f1f
831 };
832
833 static const u32 cmd3210[] = {
834 0x0f0d0b0a, 0x17151311, 0x1f1d1b19, 0x1f1f1f1f,
835 0x1f1f1f1f, 0x1f1f1f1f, 0x1f1f1f1f, 0x1f1f1f1f,
836 0x18171615, 0x1f1f1c1a, 0x1f1f1f1f, 0x1f1f1f1f,
837 0x1f1f1f1f, 0x1f1f1f1f, 0x1f1f1f1f, 0x1f1f1f1f
838 };
839
840 static const u32 clk2030[] = {
841 0x0e0d0d0c, 0x100f0f0e, 0x100f0e0d, 0x15131211,
842 0x1d1b1917, 0x2523211f, 0x2a282927, 0x32302e2c,
843 0x17161514, 0x1b1a1918, 0x1f1e1d1c, 0x23222120,
844 0x27262524, 0x2d2b2928, 0x3533312f, 0x3d3b3937
845 };
846
847 static const u32 ctl3215[] = {
848 0x01010000, 0x03020101, 0x07060504, 0x0b0a0908,
849 0x100f0e0d, 0x14131211, 0x18171615, 0x1c1b1a19,
850 0x05040403, 0x07060605, 0x0a090807, 0x0f0d0c0b,
851 0x14131211, 0x18171615, 0x1c1b1a19, 0x201f1e1d
852 };
853
854 static const u32 ctl3220[] = {
855 0x05040403, 0x07060505, 0x0e0c0a08, 0x1a171411,
856 0x2825221f, 0x35322f2b, 0x3e3e3b38, 0x3e3e3e3e,
857 0x09080807, 0x0b0a0a09, 0x0f0d0c0b, 0x1b171311,
858 0x2825221f, 0x35322f2b, 0x3e3e3b38, 0x3e3e3e3e
859 };
860
861 static const u32 nc[] = {
862 0x00000000, 0x00000000, 0x00000000, 0x00000000,
863 0x00000000, 0x00000000, 0x00000000, 0x00000000,
864 0x00000000, 0x00000000, 0x00000000, 0x00000000,
865 0x00000000, 0x00000000, 0x00000000, 0x00000000
866 };
867
868 static const u32 const * const dual_channel_slew_group_lookup[] = {
869 dq2030, cmd3210, ctl3215, ctl3215, clk2030, clk2030, dq2030, cmd3210,
870 dq2030, cmd3210, ctl3215, ctl3215, clk2030, clk2030, dq2030, cmd3210,
871 dq2030, cmd3210, nc, ctl3215, nc, clk2030, dq2030, cmd3210,
872 dq2030, cmd3210, ctl3215, ctl3215, clk2030, clk2030, dq2030, cmd2710,
873 dq2030, cmd3210, nc, ctl3215, nc, clk2030, nc, nc,
874
875 dq2030, cmd3210, ctl3215, ctl3215, clk2030, clk2030, dq2030, cmd3210,
876 dq2030, cmd3210, ctl3215, nc, clk2030, nc, dq2030, cmd3210,
877 dq2030, cmd3210, ctl3215, ctl3215, clk2030, clk2030, dq2030, cmd3210,
878 dq2030, cmd3210, ctl3215, nc, clk2030, nc, dq2030, cmd2710,
879 dq2030, cmd3210, ctl3215, nc, clk2030, nc, nc, nc,
880
881 dq2030, cmd3210, nc, ctl3215, nc, clk2030, dq2030, cmd3210,
882 dq2030, cmd3210, ctl3215, ctl3215, clk2030, clk2030, dq2030, cmd3210,
883 dq2030, cmd3210, nc, ctl3215, nc, clk2030, dq2030, cmd3210,
884 dq2030, cmd3210, ctl3215, ctl3215, clk2030, clk2030, dq2030, cmd2710,
885 dq2030, cmd3210, nc, ctl3215, nc, clk2030, nc, nc,
886
887 dq2030, cmd2710, ctl3215, ctl3215, clk2030, clk2030, dq2030, cmd3210,
888 dq2030, cmd2710, ctl3215, nc, clk2030, nc, dq2030, cmd3210,
889 dq2030, cmd2710, ctl3215, ctl3215, clk2030, clk2030, dq2030, cmd3210,
890 dq2030, cmd2710, ctl3215, nc, clk2030, nc, dq2030, cmd2710,
891 dq2030, cmd2710, ctl3215, nc, clk2030, nc, nc, nc,
892
893 nc, nc, nc, ctl3215, nc, clk2030, dq2030, cmd3210,
894 nc, nc, ctl3215, nc, clk2030, nc, dq2030, cmd3210,
895 nc, nc, nc, ctl3215, nc, clk2030, dq2030, cmd3210,
896 nc, nc, ctl3215, nc, clk2030, clk2030, dq2030, cmd2710
897 };
898
899 static const u32 const * const single_channel_slew_group_lookup[] = {
900 dq2330, cmd3210, ctl3215, ctl3215, clk2030, clk2030, dq2330, cmd3210,
901 dq2330, cmd3210, ctl3215, ctl3215, clk2030, clk2030, dq2330, cmd3210,
902 dq2330, cmd3210, nc, ctl3215, nc, clk2030, dq2330, cmd3210,
903 dq2330, cmd3210, ctl3215, ctl3215, clk2030, clk2030, dq2330, cmd3210,
904 dq2330, cmd3210, nc, ctl3215, nc, clk2030, nc, nc,
905
906 dq2330, cmd3210, ctl3215, ctl3215, clk2030, clk2030, dq2330, cmd3210,
907 dq2330, cmd3210, ctl3215, nc, clk2030, nc, dq2330, cmd3210,
908 dq2330, cmd3210, ctl3215, ctl3215, clk2030, clk2030, dq2330, cmd3210,
909 dq2330, cmd3210, ctl3215, nc, clk2030, nc, dq2330, cmd3210,
910 dq2330, cmd3210, ctl3215, nc, clk2030, nc, nc, nc,
911
912 dq2330, cmd3210, nc, ctl3215, nc, clk2030, dq2330, cmd3210,
913 dq2330, cmd3210, ctl3215, ctl3215, clk2030, clk2030, dq2330, cmd3210,
914 dq2330, cmd3210, nc, ctl3215, nc, clk2030, dq2330, cmd3210,
915 dq2330, cmd3210, ctl3215, ctl3215, clk2030, clk2030, dq2330, cmd3210,
916 dq2330, cmd3210, nc, ctl3215, nc, clk2030, nc, nc,
917
918 dq2330, cmd3210, ctl3215, ctl3215, clk2030, clk2030, dq2330, cmd3210,
919 dq2330, cmd3210, ctl3215, nc, clk2030, nc, dq2330, cmd3210,
920 dq2330, cmd3210, ctl3215, ctl3215, clk2030, clk2030, dq2330, cmd3210,
921 dq2330, cmd3210, ctl3215, nc, clk2030, nc, dq2330, cmd3210,
922 dq2330, cmd3210, ctl3215, nc, clk2030, nc, nc, nc,
923
924 dq2330, nc, nc, ctl3215, nc, clk2030, dq2030, cmd3210,
925 dq2330, nc, ctl3215, nc, clk2030, nc, dq2030, cmd3210,
926 dq2330, nc, nc, ctl3215, nc, clk2030, dq2030, cmd3210,
927 dq2330, nc, ctl3215, nc, clk2030, clk2030, dq2030, cmd3210
928 };
929
930
931 /* Strength multiplier tables */
932 static const u8 dual_channel_strength_multiplier[] = {
933 0x44, 0x11, 0x11, 0x11, 0x44, 0x44, 0x44, 0x11,
934 0x44, 0x11, 0x11, 0x11, 0x44, 0x44, 0x44, 0x11,
935 0x44, 0x11, 0x00, 0x11, 0x00, 0x44, 0x44, 0x11,
936 0x44, 0x11, 0x11, 0x11, 0x44, 0x44, 0x44, 0x22,
937 0x44, 0x11, 0x00, 0x11, 0x00, 0x44, 0x00, 0x00,
938 0x44, 0x11, 0x11, 0x11, 0x44, 0x44, 0x44, 0x11,
939 0x44, 0x11, 0x11, 0x00, 0x44, 0x00, 0x44, 0x11,
940 0x44, 0x11, 0x11, 0x11, 0x44, 0x44, 0x44, 0x11,
941 0x44, 0x11, 0x11, 0x00, 0x44, 0x00, 0x44, 0x22,
942 0x44, 0x11, 0x11, 0x00, 0x44, 0x00, 0x00, 0x00,
943 0x44, 0x11, 0x00, 0x11, 0x00, 0x44, 0x44, 0x11,
944 0x44, 0x11, 0x11, 0x11, 0x44, 0x44, 0x44, 0x11,
945 0x44, 0x11, 0x00, 0x11, 0x00, 0x44, 0x44, 0x11,
946 0x44, 0x11, 0x11, 0x11, 0x44, 0x44, 0x44, 0x22,
947 0x44, 0x11, 0x00, 0x11, 0x00, 0x44, 0x00, 0x00,
948 0x44, 0x22, 0x11, 0x11, 0x44, 0x44, 0x44, 0x11,
949 0x44, 0x22, 0x11, 0x00, 0x44, 0x00, 0x44, 0x11,
950 0x44, 0x22, 0x11, 0x11, 0x44, 0x44, 0x44, 0x11,
951 0x44, 0x22, 0x11, 0x00, 0x44, 0x00, 0x44, 0x22,
952 0x44, 0x22, 0x11, 0x00, 0x44, 0x00, 0x00, 0x00,
953 0x00, 0x00, 0x00, 0x11, 0x00, 0x44, 0x44, 0x11,
954 0x00, 0x00, 0x11, 0x00, 0x44, 0x00, 0x44, 0x11,
955 0x00, 0x00, 0x00, 0x11, 0x00, 0x44, 0x44, 0x11,
956 0x00, 0x00, 0x11, 0x00, 0x44, 0x44, 0x44, 0x22
957 };
958
959 static const u8 single_channel_strength_multiplier[] = {
960 0x33, 0x11, 0x11, 0x11, 0x44, 0x44, 0x33, 0x11,
961 0x33, 0x11, 0x11, 0x11, 0x44, 0x44, 0x33, 0x11,
962 0x33, 0x11, 0x00, 0x11, 0x00, 0x44, 0x33, 0x11,
963 0x33, 0x11, 0x11, 0x11, 0x44, 0x44, 0x33, 0x11,
964 0x33, 0x11, 0x00, 0x11, 0x00, 0x44, 0x00, 0x00,
965 0x33, 0x11, 0x11, 0x11, 0x44, 0x44, 0x33, 0x11,
966 0x33, 0x11, 0x11, 0x00, 0x44, 0x00, 0x33, 0x11,
967 0x33, 0x11, 0x11, 0x11, 0x44, 0x44, 0x33, 0x11,
968 0x33, 0x11, 0x11, 0x00, 0x44, 0x00, 0x33, 0x11,
969 0x33, 0x11, 0x11, 0x00, 0x44, 0x00, 0x00, 0x00,
970 0x33, 0x11, 0x00, 0x11, 0x00, 0x44, 0x33, 0x11,
971 0x33, 0x11, 0x11, 0x11, 0x44, 0x44, 0x33, 0x11,
972 0x33, 0x11, 0x00, 0x11, 0x00, 0x44, 0x33, 0x11,
973 0x33, 0x11, 0x11, 0x11, 0x44, 0x44, 0x33, 0x11,
974 0x33, 0x11, 0x00, 0x11, 0x00, 0x44, 0x00, 0x00,
975 0x33, 0x11, 0x11, 0x11, 0x44, 0x44, 0x33, 0x11,
976 0x33, 0x11, 0x11, 0x00, 0x44, 0x00, 0x33, 0x11,
977 0x33, 0x11, 0x11, 0x11, 0x44, 0x44, 0x33, 0x11,
978 0x33, 0x11, 0x11, 0x00, 0x44, 0x00, 0x33, 0x11,
979 0x33, 0x11, 0x11, 0x00, 0x44, 0x00, 0x00, 0x00,
980 0x33, 0x00, 0x00, 0x11, 0x00, 0x44, 0x33, 0x11,
981 0x33, 0x00, 0x11, 0x00, 0x44, 0x00, 0x33, 0x11,
982 0x33, 0x00, 0x00, 0x11, 0x00, 0x44, 0x33, 0x11,
983 0x33, 0x00, 0x11, 0x00, 0x44, 0x44, 0x33, 0x11
984 };
985
986 const u8 * strength_multiplier;
987 const u32* const * slew_group_lookup;
988 int idx;
989
990 /* Set Strength Multipliers */
991
992 /* Dual Channel needs different tables. */
993 if (sdram_capabilities_dual_channel()) {
Stefan Reinauer779b3e32008-11-10 15:43:37 +0000994 printk_debug("Programming Dual Channel RCOMP\n");
Stefan Reinauer278534d2008-10-29 04:51:07 +0000995 strength_multiplier = dual_channel_strength_multiplier;
996 slew_group_lookup = dual_channel_slew_group_lookup;
997 idx = 5 * sysinfo->dimm[0] + sysinfo->dimm[2];
998 } else {
Stefan Reinauer779b3e32008-11-10 15:43:37 +0000999 printk_debug("Programming Single Channel RCOMP\n");
Stefan Reinauer278534d2008-10-29 04:51:07 +00001000 strength_multiplier = single_channel_strength_multiplier;
1001 slew_group_lookup = single_channel_slew_group_lookup;
1002 idx = 5 * sysinfo->dimm[0] + sysinfo->dimm[1];
1003 }
1004
Stefan Reinauer779b3e32008-11-10 15:43:37 +00001005 printk_debug("Table Index: %d\n", idx);
Stefan Reinauer278534d2008-10-29 04:51:07 +00001006
1007 MCHBAR8(G1SC) = strength_multiplier[idx * 8 + 0];
1008 MCHBAR8(G2SC) = strength_multiplier[idx * 8 + 1];
1009 MCHBAR8(G3SC) = strength_multiplier[idx * 8 + 2];
1010 MCHBAR8(G4SC) = strength_multiplier[idx * 8 + 3];
1011 MCHBAR8(G5SC) = strength_multiplier[idx * 8 + 4];
1012 MCHBAR8(G6SC) = strength_multiplier[idx * 8 + 5];
1013 MCHBAR8(G7SC) = strength_multiplier[idx * 8 + 6];
1014 MCHBAR8(G8SC) = strength_multiplier[idx * 8 + 7];
1015
1016 /* Channel 0 */
1017 sdram_write_slew_rates(G1SRPUT, slew_group_lookup[idx * 8 + 0]);
1018 sdram_write_slew_rates(G2SRPUT, slew_group_lookup[idx * 8 + 1]);
1019 if ((slew_group_lookup[idx * 8 + 2] != nc) && (sysinfo->package == SYSINFO_PACKAGE_STACKED)) {
1020
1021
1022 sdram_write_slew_rates(G3SRPUT, ctl3220);
1023 } else {
1024 sdram_write_slew_rates(G3SRPUT, slew_group_lookup[idx * 8 + 2]);
1025 }
1026 sdram_write_slew_rates(G4SRPUT, slew_group_lookup[idx * 8 + 3]);
1027 sdram_write_slew_rates(G5SRPUT, slew_group_lookup[idx * 8 + 4]);
1028 sdram_write_slew_rates(G6SRPUT, slew_group_lookup[idx * 8 + 5]);
1029
1030 /* Channel 1 */
1031 if (sysinfo->dual_channel) {
1032 sdram_write_slew_rates(G7SRPUT, slew_group_lookup[idx * 8 + 6]);
1033 sdram_write_slew_rates(G8SRPUT, slew_group_lookup[idx * 8 + 7]);
1034 } else {
1035 sdram_write_slew_rates(G7SRPUT, nc);
1036 sdram_write_slew_rates(G8SRPUT, nc);
1037 }
1038}
1039
1040static void sdram_enable_rcomp(void)
1041{
1042 u32 reg32;
1043
1044 udelay(300);
1045 reg32 = MCHBAR32(GBRCOMPCTL);
1046 reg32 &= ~(1 << 23);
1047 MCHBAR32(GBRCOMPCTL) = reg32;
1048}
1049
1050static void sdram_program_dll_timings(struct sys_info *sysinfo)
1051{
1052 u32 chan0dll = 0, chan1dll = 0;
1053 int i;
1054
Stefan Reinauer779b3e32008-11-10 15:43:37 +00001055 printk_debug ("Programming DLL Timings... \n");
Stefan Reinauer278534d2008-10-29 04:51:07 +00001056
1057 MCHBAR16(DQSMT) &= ~( (3 << 12) | (1 << 10) | ( 0xf << 0) );
1058 MCHBAR16(DQSMT) |= (1 << 13) | (0xc << 0);
1059
1060 /* We drive both channels with the same speed */
1061 switch (sysinfo->memory_frequency) {
1062 case 400: chan0dll = 0x26262626; chan1dll=0x26262626; break; /* 400MHz */
1063 case 533: chan0dll = 0x22222222; chan1dll=0x22222222; break; /* 533MHz */
1064 case 667: chan0dll = 0x11111111; chan1dll=0x11111111; break; /* 667MHz */
1065 }
1066
1067 for (i=0; i < 4; i++) {
1068 MCHBAR32(C0R0B00DQST + (i * 0x10) + 0) = chan0dll;
1069 MCHBAR32(C0R0B00DQST + (i * 0x10) + 4) = chan0dll;
1070 MCHBAR32(C1R0B00DQST + (i * 0x10) + 0) = chan1dll;
1071 MCHBAR32(C1R0B00DQST + (i * 0x10) + 4) = chan1dll;
1072 }
1073}
1074
1075static void sdram_force_rcomp(void)
1076{
1077 u32 reg32;
1078 u8 reg8;
1079
1080 reg32 = MCHBAR32(ODTC);
1081 reg32 |= (1 << 28);
1082 MCHBAR32(ODTC) = reg32;
1083
1084 reg32 = MCHBAR32(SMSRCTL);
1085 reg32 |= (1 << 0);
1086 MCHBAR32(SMSRCTL) = reg32;
1087
1088 reg32 = MCHBAR32(GBRCOMPCTL);
1089 reg32 |= (1 << 8);
1090 MCHBAR32(GBRCOMPCTL) = reg32;
1091
1092 reg8 = i945_silicon_revision();
1093 if ((reg8 == 0 && (MCHBAR32(DCC) & (3 << 0)) == 0) || (reg8 == 1)) {
1094 reg32 = MCHBAR32(GBRCOMPCTL);
1095 reg32 |= (3 << 5);
1096 MCHBAR32(GBRCOMPCTL) = reg32;
1097 }
1098}
1099
1100static void sdram_initialize_system_memory_io(struct sys_info *sysinfo)
1101{
1102 u8 reg8;
1103 u32 reg32;
1104
Stefan Reinauer779b3e32008-11-10 15:43:37 +00001105 printk_debug ("Initializing System Memory IO... \n");
Stefan Reinauer278534d2008-10-29 04:51:07 +00001106
1107 reg8 = MCHBAR8(C0HCTC);
1108 reg8 &= ~0x1f;
1109 reg8 |= ( 1 << 0);
1110 MCHBAR8(C0HCTC) = reg8;
1111
1112 reg8 = MCHBAR8(C1HCTC);
1113 reg8 &= ~0x1f;
1114 reg8 |= ( 1 << 0);
1115 MCHBAR8(C1HCTC) = reg8;
1116
1117
1118 MCHBAR16(WDLLBYPMODE) &= ~( (1 << 9) | (1 << 6) | (1 << 4) | (1 << 3) | (1 << 1) );
1119 MCHBAR16(WDLLBYPMODE) |= (1 << 8) | (1 << 7) | (1 << 5) | (1 << 2) | (1 << 0);
1120
1121 MCHBAR8(C0WDLLCMC) = 0;
1122 MCHBAR8(C1WDLLCMC) = 0;
1123
1124 sdram_program_dram_width(sysinfo);
1125
1126 sdram_rcomp_buffer_strength_and_slew(sysinfo);
1127
1128 reg32 = MCHBAR32(GBRCOMPCTL);
1129 reg32 &= ~( (1 << 29) | (1 << 26) | (3 << 21) | (3 << 2) );
1130 reg32 |= (3 << 27) | (3 << 0);
1131 MCHBAR32(GBRCOMPCTL) = reg32;
1132
1133 MCHBAR32(GBRCOMPCTL) |= (1 << 10);
1134
1135 sdram_program_dll_timings(sysinfo);
1136
1137 sdram_force_rcomp();
1138}
1139
1140static void sdram_enable_system_memory_io(struct sys_info *sysinfo)
1141{
1142 u32 reg32;
1143
Stefan Reinauer779b3e32008-11-10 15:43:37 +00001144 printk_debug ("Enabling System Memory IO... \n");
Stefan Reinauer278534d2008-10-29 04:51:07 +00001145
1146 reg32 = MCHBAR32(RCVENMT);
1147 reg32 &= ~(0x3f << 6);
1148 MCHBAR32(RCVENMT) = reg32;
1149
1150 reg32 |= (1 << 11) | (1 << 9);
1151 MCHBAR32(RCVENMT) = reg32;
1152
1153 reg32 = MCHBAR32(DRTST);
1154 reg32 |= (1 << 3) | (1 << 2);
1155 MCHBAR32(DRTST) = reg32;
1156
1157 reg32 = MCHBAR32(DRTST);
1158 reg32 |= (1 << 6) | (1 << 4);
1159 MCHBAR32(DRTST) = reg32;
1160
1161 asm volatile ("nop; nop;");
1162
1163 reg32 = MCHBAR32(DRTST);
1164
1165 /* Is channel 0 populated? */
1166 if (sysinfo->dimm[0] != SYSINFO_DIMM_NOT_POPULATED ||
1167 sysinfo->dimm[1] != SYSINFO_DIMM_NOT_POPULATED)
1168 reg32 |= (1 << 7) | (1 << 5);
1169 else
1170 reg32 |= (1 << 31);
1171
1172 /* Is channel 1 populated? */
1173 if (sysinfo->dimm[2] != SYSINFO_DIMM_NOT_POPULATED ||
1174 sysinfo->dimm[3] != SYSINFO_DIMM_NOT_POPULATED)
1175 reg32 |= (1 << 9) | (1 << 8);
1176 else
1177 reg32 |= (1 << 30);
1178
1179 MCHBAR32(DRTST) = reg32;
1180
1181 if (sysinfo->dimm[0] != SYSINFO_DIMM_NOT_POPULATED ||
1182 sysinfo->dimm[1] != SYSINFO_DIMM_NOT_POPULATED) {
1183 reg32 = MCHBAR32(C0DRC1);
1184 reg32 |= (1 << 8);
1185 MCHBAR32(C0DRC1) = reg32;
1186 }
1187 if (sysinfo->dimm[2] != SYSINFO_DIMM_NOT_POPULATED ||
1188 sysinfo->dimm[3] != SYSINFO_DIMM_NOT_POPULATED) {
1189 reg32 = MCHBAR32(C1DRC1);
1190 reg32 |= (1 << 8);
1191 MCHBAR32(C1DRC1) = reg32;
1192 }
1193}
1194
1195struct dimm_size {
1196 unsigned long side1;
1197 unsigned long side2;
1198};
1199
1200static struct dimm_size sdram_get_dimm_size(u16 device)
1201{
1202 /* Calculate the log base 2 size of a DIMM in bits */
1203 struct dimm_size sz;
1204 int value, low, rows, columns;
1205
1206 sz.side1 = 0;
1207 sz.side2 = 0;
1208
1209 rows = spd_read_byte(device, SPD_NUM_ROWS); /* rows */
1210 if (rows < 0) goto hw_err;
1211 if ((rows & 0xf) == 0) goto val_err;
1212 sz.side1 += rows & 0xf;
1213
1214 columns = spd_read_byte(device, SPD_NUM_COLUMNS); /* columns */
1215 if (columns < 0) goto hw_err;
1216 if ((columns & 0xf) == 0) goto val_err;
1217 sz.side1 += columns & 0xf;
1218
1219 value = spd_read_byte(device, SPD_NUM_BANKS_PER_SDRAM); /* banks */
1220 if (value < 0) goto hw_err;
1221 if ((value & 0xff) == 0) goto val_err;
1222 sz.side1 += log2(value & 0xff);
1223
1224 /* Get the module data width and convert it to a power of two */
1225 value = spd_read_byte(device, SPD_MODULE_DATA_WIDTH_MSB); /* (high byte) */
1226 if (value < 0) goto hw_err;
1227 value &= 0xff;
1228 value <<= 8;
1229
1230 low = spd_read_byte(device, SPD_MODULE_DATA_WIDTH_LSB); /* (low byte) */
1231 if (low < 0) goto hw_err;
1232 value = value | (low & 0xff);
1233 if ((value != 72) && (value != 64)) goto val_err;
1234 sz.side1 += log2(value);
1235
1236 /* side 2 */
1237 value = spd_read_byte(device, SPD_NUM_DIMM_BANKS); /* number of physical banks */
1238
1239 if (value < 0) goto hw_err;
1240 value &= 7;
1241 value++;
1242 if (value == 1) goto out;
1243 if (value != 2) goto val_err;
1244
1245 /* Start with the symmetrical case */
1246 sz.side2 = sz.side1;
1247
1248 if ((rows & 0xf0) == 0) goto out; /* If symmetrical we are done */
1249
1250 /* Don't die here, I have not come across any of these to test what
1251 * actually happens.
1252 */
1253 printk_err("Assymetric DIMMs are not supported by this chipset\n");
1254
1255 sz.side2 -= (rows & 0x0f); /* Subtract out rows on side 1 */
1256 sz.side2 += ((rows >> 4) & 0x0f); /* Add in rows on side 2 */
1257
1258 sz.side2 -= (columns & 0x0f); /* Subtract out columns on side 1 */
1259 sz.side2 += ((columns >> 4) & 0x0f); /* Add in columns on side 2 */
1260
1261 goto out;
1262
1263 val_err:
Stefan Reinauer779b3e32008-11-10 15:43:37 +00001264 die("Bad SPD value\n");
Stefan Reinauer278534d2008-10-29 04:51:07 +00001265 hw_err:
1266 /* If a hardware error occurs the spd rom probably does not exist.
1267 * In this case report that there is no memory
1268 */
1269 sz.side1 = 0;
1270 sz.side2 = 0;
1271 out:
1272 return sz;
1273}
1274
1275static void sdram_detect_dimm_size(struct sys_info * sysinfo)
1276{
1277 int i;
1278
1279 for(i = 0; i < 2 * DIMM_SOCKETS; i++) {
1280 struct dimm_size sz;
1281
1282 sysinfo->banksize[i * 2] = 0;
1283 sysinfo->banksize[(i * 2) + 1] = 0;
1284
1285 if (sysinfo->dimm[i] == SYSINFO_DIMM_NOT_POPULATED)
1286 continue;
1287
1288 sz = sdram_get_dimm_size(DIMM_SPD_BASE + i);
1289
1290 sysinfo->banks[i] = spd_read_byte(DIMM_SPD_BASE + i, SPD_NUM_BANKS_PER_SDRAM); /* banks */
1291
1292 if (sz.side1 < 30)
1293 die("DDR-II rank size smaller than 128MB is not supported.\n");
1294
1295 sysinfo->banksize[i * 2] = sz.side1 - 30;
1296
1297 printk_debug("DIMM %d side 0 = %d MB\n", i, (1 << sysinfo->banksize[i * 2]) * 128 );
1298
1299 if (!sz.side2)
1300 continue;
1301
1302 /* If there is a second side, it has to have at least 128M, too */
1303 if (sz.side2 < 30)
1304 die("DDR-II rank size smaller than 128MB is not supported.\n");
1305
1306 sysinfo->banksize[(i * 2) + 1] = sz.side2 - 30;
1307
1308 printk_debug("DIMM %d side 1 = %d MB\n", i, (1 << sysinfo->banksize[(i * 2) + 1]) * 128);
1309 }
1310}
1311
1312static int sdram_program_row_boundaries(struct sys_info *sysinfo)
1313{
1314 int i;
1315 int cum0, cum1, tolud;
1316
Stefan Reinauer779b3e32008-11-10 15:43:37 +00001317 printk_debug ("Setting RAM size... \n");
Stefan Reinauer278534d2008-10-29 04:51:07 +00001318
1319 cum0 = 0;
1320 for(i = 0; i < 2 * DIMM_SOCKETS; i++) {
1321 cum0 += (sysinfo->banksize[i] << 3);
1322 MCHBAR8(C0DRB0+i) = cum0;
1323 }
1324
1325 /* Assume we continue in Channel 1 where we stopped in Channel 0 */
1326 cum1 = cum0;
1327
1328 /* Exception: Interleaved starts from the beginning */
1329 if (sysinfo->interleaved)
1330 cum1 = 0;
1331
1332 /* Exception: Channel 1 is not populated. C1DRB stays zero */
1333 if (sysinfo->dimm[2] == SYSINFO_DIMM_NOT_POPULATED &&
1334 sysinfo->dimm[3] == SYSINFO_DIMM_NOT_POPULATED)
1335 cum1 = 0;
1336
1337 for(i = 0; i < 2 * DIMM_SOCKETS; i++) {
1338 cum1 += (sysinfo->banksize[i + 4] << 3);
1339 MCHBAR8(C1DRB0+i) = cum1;
1340 }
1341
1342 /* Set TOLUD Top Of Low Usable DRAM */
1343 if (sysinfo->interleaved)
1344 tolud = (cum0 + cum1) << 1;
1345 else
1346 tolud = (cum1 ? cum1 : cum0) << 1;
Stefan Reinauer779b3e32008-11-10 15:43:37 +00001347
1348 /* Some extra checks needed. See 4.1.26 in the
1349 * 82945G MCH datasheet (30750203)
1350 */
Stefan Reinauer977ed2d2009-01-20 22:46:52 +00001351 pci_write_config16(PCI_DEV(0,0,0), TOLUD, tolud);
Stefan Reinauer278534d2008-10-29 04:51:07 +00001352
Stefan Reinauer779b3e32008-11-10 15:43:37 +00001353 printk_debug("C0DRB = 0x%08x\n", MCHBAR32(C0DRB0));
1354 printk_debug("C1DRB = 0x%08x\n", MCHBAR32(C1DRB0));
Stefan Reinauer977ed2d2009-01-20 22:46:52 +00001355 printk_debug("TOLUD = 0x%04x\n", tolud);
Stefan Reinauer278534d2008-10-29 04:51:07 +00001356
1357 pci_write_config16(PCI_DEV(0,0,0), TOM, tolud>>3);
1358
1359 return 0;
1360}
1361
1362
1363static int sdram_set_row_attributes(struct sys_info *sysinfo)
1364{
1365 int i, value;
1366 u16 dra0=0, dra1=0, dra = 0;
1367
Stefan Reinauer779b3e32008-11-10 15:43:37 +00001368 printk_debug ("Setting row attributes... \n");
Stefan Reinauer278534d2008-10-29 04:51:07 +00001369 for(i=0; i < 2 * DIMM_SOCKETS; i++) {
1370 u16 device;
1371 u8 columnsrows;
1372
1373 if (sysinfo->dimm[i] == SYSINFO_DIMM_NOT_POPULATED) {
1374 continue;
1375 }
1376
1377 device = DIMM_SPD_BASE + i;
1378 columnsrows = 0;
1379
1380 value = spd_read_byte(device, SPD_NUM_ROWS); /* rows */
1381 columnsrows = (value & 0x0f);
1382
1383 value = spd_read_byte(device, SPD_NUM_COLUMNS); /* columns */
1384 columnsrows |= (value & 0xf) << 4;
1385
1386 switch (columnsrows) {
1387 case 0x9d: dra = 2; break;
1388 case 0xad: dra = 3; break;
1389 case 0xbd: dra = 4; break;
1390 case 0xae: dra = 3; break;
1391 case 0xbe: dra = 4; break;
1392 default: die("Unsupported Rows/Columns. (DRA)");
1393 }
1394
1395 /* Double Sided DIMMs? */
1396 if (sysinfo->banksize[(2 * i) + 1] != 0) {
1397 dra = (dra << 4) | dra;
1398 }
1399
1400 if (i < DIMM_SOCKETS)
1401 dra0 |= (dra << (i*8));
1402 else
1403 dra1 |= (dra << ((i - DIMM_SOCKETS)*8));
1404 }
1405
1406 MCHBAR16(C0DRA0) = dra0;
1407 MCHBAR16(C1DRA0) = dra1;
1408
Stefan Reinauer779b3e32008-11-10 15:43:37 +00001409 printk_debug("C0DRA = 0x%04x\n", dra0);
1410 printk_debug("C1DRA = 0x%04x\n", dra1);
Stefan Reinauer278534d2008-10-29 04:51:07 +00001411
1412 return 0;
1413}
1414
1415static void sdram_set_bank_architecture(struct sys_info *sysinfo)
1416{
1417 u32 off32;
1418 int i;
1419
1420 MCHBAR16(C1BNKARC) &= 0xff00;
1421 MCHBAR16(C0BNKARC) &= 0xff00;
1422
1423 off32 = C0BNKARC;
1424 for (i=0; i < 2 * DIMM_SOCKETS; i++) {
1425 /* Switch to second channel */
1426 if (i == DIMM_SOCKETS)
1427 off32 = C1BNKARC;
1428
1429 if (sysinfo->dimm[i] == SYSINFO_DIMM_NOT_POPULATED)
1430 continue;
1431
1432 if (sysinfo->banks[i] != 8)
1433 continue;
1434
1435 printk_spew("DIMM%d has 8 banks.\n");
1436
1437 if (i & 1)
1438 MCHBAR16(off32) |= 0x50;
1439 else
1440 MCHBAR16(off32) |= 0x05;
1441 }
1442}
1443
1444#define REFRESH_7_8US 1
1445#define REFRESH_15_6US 0
1446static void sdram_program_refresh_rate(struct sys_info *sysinfo)
1447{
1448 u32 reg32;
1449
1450 if (sysinfo->refresh == REFRESH_7_8US) {
1451 reg32 = (2 << 8); /* Refresh enabled at 7.8us */
1452 } else {
1453 reg32 = (1 << 8); /* Refresh enabled at 15.6us */
1454 }
1455
1456 MCHBAR32(C0DRC0) &= ~(7 << 8);
1457 MCHBAR32(C0DRC0) |= reg32;
1458
1459 MCHBAR32(C1DRC0) &= ~(7 << 8);
1460 MCHBAR32(C1DRC0) |= reg32;
1461}
1462
1463static void sdram_program_cke_tristate(struct sys_info *sysinfo)
1464{
1465 u32 reg32;
1466 int i;
1467
1468 reg32 = MCHBAR32(C0DRC1);
1469
1470 for (i=0; i < 4; i++) {
1471 if (sysinfo->banksize[i] == 0) {
1472 reg32 |= (1 << (16 + i));
1473 }
1474 }
1475
1476 reg32 |= (1 << 12);
1477
1478 reg32 |= (1 << 11);
1479 MCHBAR32(C0DRC1) = reg32;
1480
1481 /* Do we have to do this if we're in Single Channel Mode? */
1482 reg32 = MCHBAR32(C1DRC1);
1483
1484 for (i=4; i < 8; i++) {
1485 if (sysinfo->banksize[i] == 0) {
1486 reg32 |= (1 << (12 + i));
1487 }
1488 }
1489
1490 reg32 |= (1 << 12);
1491
1492 reg32 |= (1 << 11);
1493 MCHBAR32(C1DRC1) = reg32;
1494}
1495
1496static void sdram_program_odt_tristate(struct sys_info *sysinfo)
1497{
1498 u32 reg32;
1499 int i;
1500
1501 reg32 = MCHBAR32(C0DRC2);
1502
1503 for (i=0; i < 4; i++) {
1504 if (sysinfo->banksize[i] == 0) {
1505 reg32 |= (1 << (24 + i));
1506 }
1507 }
1508 MCHBAR32(C0DRC2) = reg32;
1509
1510 reg32 = MCHBAR32(C1DRC2);
1511
1512 for (i=4; i < 8; i++) {
1513 if (sysinfo->banksize[i] == 0) {
1514 reg32 |= (1 << (20 + i));
1515 }
1516 }
1517 MCHBAR32(C1DRC2) = reg32;
1518}
1519
1520static void sdram_set_timing_and_control(struct sys_info *sysinfo)
1521{
1522 u32 reg32, off32;
1523 u32 tWTR;
1524 u32 temp_drt;
1525 int i, page_size;
1526
1527 static const u8 const drt0_table[] = {
1528 /* CL 3, 4, 5 */
1529 3, 4, 5, /* FSB533/400, DDR533/400 */
1530 4, 5, 6, /* FSB667, DDR533/400 */
1531 4, 5, 6, /* FSB667, DDR667 */
1532 };
1533
1534 static const u8 const cas_table[] = {
1535 2, 1, 0, 3
1536 };
1537
1538 reg32 = MCHBAR32(C0DRC0);
1539 reg32 |= (1 << 2); /* Burst Length 8 */
1540 reg32 &= ~( (1 << 13) | (1 << 12) );
1541 MCHBAR32(C0DRC0) = reg32;
1542
1543 reg32 = MCHBAR32(C1DRC0);
1544 reg32 |= (1 << 2); /* Burst Length 8 */
1545 reg32 &= ~( (1 << 13) | (1 << 12) );
1546 MCHBAR32(C1DRC0) = reg32;
1547
1548 if (!sysinfo->dual_channel && sysinfo->dimm[1] !=
1549 SYSINFO_DIMM_NOT_POPULATED) {
1550 reg32 = MCHBAR32(C0DRC0);
1551 reg32 |= (1 << 15);
1552 MCHBAR32(C0DRC0) = reg32;
1553 }
1554
1555 sdram_program_refresh_rate(sysinfo);
1556
1557 sdram_program_cke_tristate(sysinfo);
1558
1559 sdram_program_odt_tristate(sysinfo);
1560
1561 /* Calculate DRT0 */
1562
1563 temp_drt = 0;
1564
1565 /* B2B Write Precharge (same bank) = CL-1 + BL/2 + tWR */
1566 reg32 = (sysinfo->cas - 1) + (BURSTLENGTH / 2) + sysinfo->twr;
1567 temp_drt |= (reg32 << 28);
1568
1569 /* Write Auto Precharge (same bank) = CL-1 + BL/2 + tWR + tRP */
1570 reg32 += sysinfo->trp;
1571 temp_drt |= (reg32 << 4);
1572
1573 if (sysinfo->memory_frequency == 667) {
1574 tWTR = 3; /* 667MHz */
1575 } else {
1576 tWTR = 2; /* 400 and 533 */
1577 }
1578
1579 /* B2B Write to Read Command Spacing */
1580 reg32 = (sysinfo->cas - 1) + (BURSTLENGTH / 2) + tWTR;
1581 temp_drt |= (reg32 << 24);
1582
1583
1584 temp_drt |= ( (1 << 22) | (3 << 20) | (1 << 18) | (0 << 16) );
1585
1586 /* Program Write Auto Precharge to Activate */
1587 off32 = 0;
1588 if (sysinfo->fsb_frequency == 667) { /* 667MHz FSB */
1589 off32 += 3;
1590 }
1591 if (sysinfo->memory_frequency == 667) {
1592 off32 += 3;
1593 }
1594 off32 += sysinfo->cas - 3;
1595 reg32 = drt0_table[off32];
1596 temp_drt |= (reg32 << 11);
1597
1598 /* Read Auto Precharge to Activate */
1599
1600 temp_drt |= (8 << 0);
1601
1602 MCHBAR32(C0DRT0) = temp_drt;
1603 MCHBAR32(C1DRT0) = temp_drt;
1604
1605 /* Calculate DRT1 */
1606
1607 temp_drt = MCHBAR32(C0DRT1) & 0x00020088;
1608
1609 /* DRAM RASB Precharge */
1610 temp_drt |= (sysinfo->trp - 2) << 0;
1611
1612 /* DRAM RASB to CASB Delay */
1613 temp_drt |= (sysinfo->trcd - 2) << 4;
1614
1615 /* CASB Latency */
1616 temp_drt |= (cas_table[sysinfo->cas - 3]) << 8;
1617
1618 /* Refresh Cycle Time */
1619 temp_drt |= (sysinfo->trfc) << 10;
1620
1621 /* Pre-All to Activate Delay */
1622 temp_drt |= (0 << 16);
1623
1624 /* Precharge to Precharge Delay stays at 1 clock */
1625 temp_drt |= (0 << 18);
1626
1627 /* Activate to Precharge Delay */
1628 temp_drt |= (sysinfo->tras << 19);
1629
1630 /* Read to Precharge (tRTP) */
1631 if (sysinfo->memory_frequency == 667) {
1632 temp_drt |= (1 << 28);
1633 } else {
1634 temp_drt |= (0 << 28);
1635 }
1636
1637 /* Determine page size */
1638 reg32 = 0;
1639 page_size = 1; /* Default: 1k pagesize */
1640 for (i=0; i< 2*DIMM_SOCKETS; i++) {
1641 if (sysinfo->dimm[i] == SYSINFO_DIMM_X16DS ||
1642 sysinfo->dimm[i] == SYSINFO_DIMM_X16SS)
1643 page_size = 2; /* 2k pagesize */
1644 }
1645
1646 if (sysinfo->memory_frequency == 533 && page_size == 2) {
1647 reg32 = 1;
1648 }
1649 if (sysinfo->memory_frequency == 667) {
1650 reg32 = page_size;
1651 }
1652
1653 temp_drt |= (reg32 << 30);
1654
1655 MCHBAR32(C0DRT1) = temp_drt;
1656 MCHBAR32(C1DRT1) = temp_drt;
1657
1658 /* Program DRT2 */
1659 reg32 = MCHBAR32(C0DRT2);
1660 reg32 &= ~(1 << 8);
1661 MCHBAR32(C0DRT2) = reg32;
1662
1663 reg32 = MCHBAR32(C1DRT2);
1664 reg32 &= ~(1 << 8);
1665 MCHBAR32(C1DRT2) = reg32;
1666
1667 /* Calculate DRT3 */
1668 temp_drt = MCHBAR32(C0DRT3) & ~0x07ffffff;
1669
1670 /* Get old tRFC value */
1671 reg32 = MCHBAR32(C0DRT1) >> 10;
1672 reg32 &= 0x3f;
1673
1674 /* 788nS - tRFC */
1675 switch (sysinfo->memory_frequency) {
1676 case 400: /* 5nS */
1677 reg32 = ((78800 / 500) - reg32) & 0x1ff;
1678 reg32 |= (0x8c << 16) | (0x0c << 10); /* 1 us */
1679 break;
1680 case 533: /* 3.75nS */
1681 reg32 = ((78800 / 375) - reg32) & 0x1ff;
1682 reg32 |= (0xba << 16) | (0x10 << 10); /* 1 us */
1683 break;
1684 case 667: /* 3nS */
1685 reg32 = ((78800 / 300) - reg32) & 0x1ff;
1686 reg32 |= (0xe9 << 16) | (0x14 << 10); /* 1 us */
1687 break;
1688 }
1689
1690 temp_drt |= reg32;
1691
1692 MCHBAR32(C0DRT3) = temp_drt;
1693 MCHBAR32(C1DRT3) = temp_drt;
1694}
1695
1696static void sdram_set_channel_mode(struct sys_info *sysinfo)
1697{
1698 u32 reg32;
1699
1700 printk_debug("Setting mode of operation for memory channels...");
1701
1702 if (sdram_capabilities_interleave() &&
1703 ( ( sysinfo->banksize[0] + sysinfo->banksize[1] +
1704 sysinfo->banksize[2] + sysinfo->banksize[3] ) ==
1705 ( sysinfo->banksize[4] + sysinfo->banksize[5] +
1706 sysinfo->banksize[6] + sysinfo->banksize[7] ) ) ) {
1707 /* Both channels equipped with DIMMs of the same size */
1708
1709 sysinfo->interleaved = 1;
1710 } else {
1711 sysinfo->interleaved = 0;
1712 }
1713
1714 reg32 = MCHBAR32(DCC);
1715 reg32 &= ~(7 << 0);
1716
1717 if(sysinfo->interleaved) {
1718 /* Dual Channel Interleaved */
1719 printk_debug("Dual Channel Interleaved.\n");
1720 reg32 |= (1 << 1);
1721 } else if (sysinfo->dimm[0] == SYSINFO_DIMM_NOT_POPULATED &&
1722 sysinfo->dimm[1] == SYSINFO_DIMM_NOT_POPULATED) {
1723 /* Channel 1 only */
1724 printk_debug("Single Channel 1 only.\n");
1725 reg32 |= (1 << 2);
1726 } else if (sdram_capabilities_dual_channel() && sysinfo->dimm[2] !=
1727 SYSINFO_DIMM_NOT_POPULATED) {
1728 /* Dual Channel Assymetric */
1729 printk_debug("Dual Channel Assymetric.\n");
1730 reg32 |= (1 << 0);
1731 } else {
1732 /* All bits 0 means Single Channel 0 operation */
1733 printk_debug("Single Channel 0 only.\n");
1734 }
1735
1736 reg32 |= (1 << 10);
1737
1738 MCHBAR32(DCC) = reg32;
1739
Stefan Reinauer779b3e32008-11-10 15:43:37 +00001740 PRINTK_DEBUG("DCC=0x%08x\n", MCHBAR32(DCC));
Stefan Reinauer278534d2008-10-29 04:51:07 +00001741}
1742
1743static void sdram_program_pll_settings(void)
1744{
1745 volatile u16 reg16;
1746 volatile u32 reg32;
1747
1748 const u8 HPLLGPLLPowerDown[] = {
1749 0x90, /* 400MHz */
1750 0x95, /* 533MHz */
1751 0x00, /* --- */
1752 0x8d, /* 667MHz */
1753 };
1754
1755 MCHBAR32(PLLMON) = 0x80800000;
1756
1757 reg32 = MCHBAR32(CLKCFG);
1758 reg32 &= (7 << 0);
1759
1760 reg16 = MCHBAR16(CPCTL);
1761 reg16 &= 0xff00;
1762 reg16 |= HPLLGPLLPowerDown[reg32];
1763 MCHBAR16(CPCTL) = reg16;
1764
1765 reg16 &= ~(1 << 11);
1766 MCHBAR16(CPCTL) = reg16;
1767
1768 reg16 = MCHBAR16(CPCTL);
1769}
1770
1771static void sdram_program_graphics_frequency(struct sys_info *sysinfo)
1772{
1773 u8 reg8;
1774 u16 reg16;
1775 u8 freq, second_vco;
1776
1777#define CRCLK_166MHz 0x00
1778#define CRCLK_200MHz 0x01
1779#define CRCLK_250MHz 0x03
1780#define CRCLK_400MHz 0x05
1781
1782#define CDCLK_200MHz 0x00
1783#define CDCLK_320MHz 0x40
1784
Stefan Reinauer779b3e32008-11-10 15:43:37 +00001785 printk_debug ("Setting Graphics Frequency... \n");
Stefan Reinauer278534d2008-10-29 04:51:07 +00001786
1787 reg16 = pci_read_config16(PCI_DEV(0,2,0), GCFC);
1788 reg16 |= (1<<11) | (1<<9);
1789 pci_write_config16(PCI_DEV(0,2,0), GCFC, reg16);
1790
1791 /* Program CPCTL according to FSB speed */
1792 reg16 = MCHBAR16(CPCTL);
1793 reg16 &= 0xff00;
1794
1795 switch (MCHBAR32(CLKCFG) & 0x7) {
1796 case 0: sysinfo->fsb_frequency = 400; break; /* FSB400 */
1797 case 1: sysinfo->fsb_frequency = 533; break; /* FSB533 */
1798 case 3: sysinfo->fsb_frequency = 667; break; /* FSB667 */
1799 default: die("Unsupported FSB speed");
1800 }
1801
1802 switch (sysinfo->fsb_frequency) {
1803 case 533: reg16 |= 0x95; break; /* FSB533 */
1804 case 667: reg16 |= 0x8d; break; /* FSB667 */
1805 }
1806 MCHBAR16(CPCTL) = reg16;
1807
1808 /* Get graphics frequency capabilities */
1809 reg8 = (pci_read_config8(PCI_DEV(0, 0x00,0), 0xe5) & 0x0e) >> 1;
1810
1811 freq = CRCLK_250MHz;
1812 switch (reg8) {
1813 case 0:
1814 if (MCHBAR32(DFT_STRAP1) & (1 << 20))
1815 freq = CRCLK_250MHz;
1816 else
1817 freq = CRCLK_400MHz;
1818 break;
1819 case 2: freq = CRCLK_250MHz; break;
1820 case 3: freq = CRCLK_200MHz; break;
1821 case 4: freq = CRCLK_166MHz; break;
1822 }
1823
1824 if (freq != CRCLK_400MHz) {
1825
1826 reg8 = (pci_read_config8(PCI_DEV(0, 0x00,0), 0xe7) & 0x70) >> 4;
1827 if (reg8==2)
1828 freq = CRCLK_166MHz;
1829 }
1830
1831 if (i945_silicon_revision() == 0) {
1832 sysinfo->mvco4x = 1;
1833 } else {
1834 sysinfo->mvco4x = 0;
1835 }
1836
1837
1838 second_vco = 0;
1839
1840 if (MCHBAR32(DFT_STRAP1) & (1 << 20)) {
1841 second_vco = 1;
1842 } else if ((i945_silicon_revision() > 0) && (freq == CRCLK_250MHz)) {
1843 u16 mem = sysinfo->memory_frequency;
1844 u16 fsb = sysinfo->fsb_frequency;
1845
1846 if ( (fsb == 667 && mem == 533) ||
1847 (fsb == 533 && mem == 533) ||
1848 (fsb == 533 && mem == 400)) {
1849 second_vco = 1;
1850 }
1851
1852 if (fsb == 667 && mem == 533)
1853 sysinfo->mvco4x = 1;
1854 }
1855
1856 if (second_vco) {
Stefan Reinauer779b3e32008-11-10 15:43:37 +00001857 printk_debug("Programming second TCO\n");
Stefan Reinauer278534d2008-10-29 04:51:07 +00001858 sysinfo->clkcfg_bit7=1;
1859 } else {
1860 sysinfo->clkcfg_bit7=0;
1861 }
1862
1863 reg16 = pci_read_config16(PCI_DEV(0,2,0), GCFC);
1864 reg16 &= ~( (7 << 0) | (1 << 13) );
1865 reg16 |= freq;
1866 pci_write_config16(PCI_DEV(0,2,0), GCFC, reg16);
1867
1868 reg16 = pci_read_config16(PCI_DEV(0,2,0), GCFC);
1869 reg16 &= ~( (1<<7) | (7<<4) );
1870 if (MCHBAR32(DFT_STRAP1) & (1 << 20)) {
1871 reg16 |= CDCLK_200MHz;
1872 } else {
1873 reg16 |= CDCLK_320MHz;
1874 }
1875 pci_write_config16(PCI_DEV(0,2,0), GCFC, reg16);
1876
1877 reg16 = pci_read_config16(PCI_DEV(0,2,0), GCFC);
1878 reg16 &= ~( (1<<10) | (1<<8) );
1879 pci_write_config16(PCI_DEV(0,2,0), GCFC, reg16);
1880 reg16 |= (1<<10) | (1<<8);
1881 pci_write_config16(PCI_DEV(0,2,0), GCFC, reg16);
1882
1883 reg16 &= 0xf0ff;
1884 pci_write_config16(PCI_DEV(0,2,0), GCFC, reg16);
1885}
1886
1887static void sdram_program_memory_frequency(struct sys_info *sysinfo)
1888{
1889 u32 clkcfg;
1890 u8 reg8;
1891
1892 printk_debug ("Setting Memory Frequency... ");
1893
1894 clkcfg = MCHBAR32(CLKCFG);
1895
1896 printk_debug("CLKCFG=0x%08x, ", clkcfg);
1897
1898 clkcfg &= ~( (1 << 12) | (1 << 7) | ( 7 << 4) );
1899
1900 if (sysinfo->mvco4x) {
1901 printk_debug("MVCO 4x, ");
1902 clkcfg &= ~(1 << 12);
1903 }
1904
1905 if (sysinfo->clkcfg_bit7) {
1906 printk_debug("second VCO, ");
1907
1908 clkcfg |= (1 << 7);
1909 }
1910
1911 switch (sysinfo->memory_frequency) {
1912 case 400: clkcfg |= (2 << 4); break;
1913 case 533: clkcfg |= (3 << 4); break;
1914 case 667: clkcfg |= (4 << 4); break;
1915 default: die("Target Memory Frequency Error");
1916 }
1917
1918 if (MCHBAR32(CLKCFG) == clkcfg) {
Stefan Reinauer779b3e32008-11-10 15:43:37 +00001919 printk_debug ("ok (unchanged)\n");
Stefan Reinauer278534d2008-10-29 04:51:07 +00001920 return;
1921 }
1922
1923 MCHBAR32(CLKCFG) = clkcfg;
1924
1925 /* Make sure the following code is in the
1926 * cache before we execute it.
1927 */
1928 goto cache_code;
1929vco_update:
1930 reg8 = pci_read_config8(PCI_DEV(0,0x1f,0), 0xa2);
1931 reg8 &= ~(1 << 7);
1932 pci_write_config8(PCI_DEV(0, 0x1f, 0), 0xa2, reg8);
1933
1934
1935 clkcfg &= ~(1 << 10);
1936 MCHBAR32(CLKCFG) = clkcfg;
1937 clkcfg |= (1 << 10);
1938 MCHBAR32(CLKCFG) = clkcfg;
1939
1940
1941 __asm__ __volatile__ (
1942 " movl $0x100, %%ecx\n"
1943 "delay_update:\n"
1944 " nop\n"
1945 " nop\n"
1946 " nop\n"
1947 " nop\n"
1948 " loop delay_update\n"
1949 : /* No outputs */
1950 : /* No inputs */
1951 : "%ecx"
1952 );
1953
1954
1955 clkcfg &= ~(1 << 10);
1956 MCHBAR32(CLKCFG) = clkcfg;
1957
1958 goto out;
1959cache_code:
1960 goto vco_update;
1961out:
1962
1963 printk_debug("CLKCFG=0x%08x, ", MCHBAR32(CLKCFG));
Stefan Reinauer779b3e32008-11-10 15:43:37 +00001964 printk_debug ("ok\n");
Stefan Reinauer278534d2008-10-29 04:51:07 +00001965}
1966
1967static void sdram_program_clock_crossing(void)
1968{
1969 u32 reg32;
1970 int idx = 0;
1971
1972 /**
1973 * The first two lines of each of these tables are for FSB533,
1974 * the following three lines are for FSB667. We ignore FSB400.
1975 * Thus we add the indices according to our clocks from CLKCFG.
1976 */
1977
1978 static const u32 data_clock_crossing[] = {
1979 0x08040120, 0x00000000, /* DDR400 FSB533 */
1980 0x00100401, 0x00000000, /* DDR533 FSB533 */
1981
1982 0x04020120, 0x00000010, /* DDR400 FSB667 */
1983 0x10040280, 0x00000040, /* DDR533 FSB667 */
1984 0x00100401, 0x00000000 /* DDR667 FSB667 */
1985 };
1986
1987 static const u32 command_clock_crossing[] = {
1988 0x00060108, 0x00000000, /* DDR400 FSB533 */
1989 0x04020108, 0x00000000, /* DDR533 FSB533 */
1990
1991 0x00040318, 0x00000000, /* DDR400 FSB667 */
1992 0x04020118, 0x00000000, /* DDR533 FSB667 */
1993 0x02010804, 0x00000000 /* DDR667 FSB667 */
1994 };
1995
1996 printk_debug("Programming Clock Crossing...");
1997 reg32 = MCHBAR32(CLKCFG);
1998
1999 printk_debug("MEM=");
2000 switch ((reg32 >> 4) & 7) {
2001 case 2: printk_debug("400"); idx += 0; break;
2002 case 3: printk_debug("533"); idx += 2; break;
2003 case 4: printk_debug("667"); idx += 4; break;
Stefan Reinauer779b3e32008-11-10 15:43:37 +00002004 default: printk_debug("RSVD\n"); return;
Stefan Reinauer278534d2008-10-29 04:51:07 +00002005 }
2006
2007 printk_debug(" FSB=");
2008 switch (reg32 & 7) {
Stefan Reinauer779b3e32008-11-10 15:43:37 +00002009 case 0: printk_debug("400\n"); return;
Stefan Reinauer278534d2008-10-29 04:51:07 +00002010 case 1: printk_debug("533"); idx += 0; break;
2011 case 3: printk_debug("667"); idx += 4; break;
Stefan Reinauer779b3e32008-11-10 15:43:37 +00002012 default: printk_debug("RSVD\n"); return;
Stefan Reinauer278534d2008-10-29 04:51:07 +00002013 }
2014
2015 MCHBAR32(C0DCCFT + 0) = data_clock_crossing[idx];
2016 MCHBAR32(C0DCCFT + 4) = data_clock_crossing[idx + 1];
2017 MCHBAR32(C1DCCFT + 0) = data_clock_crossing[idx];
2018 MCHBAR32(C1DCCFT + 4) = data_clock_crossing[idx + 1];
2019
2020 MCHBAR32(CCCFT + 0) = command_clock_crossing[idx];
2021 MCHBAR32(CCCFT + 4) = command_clock_crossing[idx + 1];
2022
Stefan Reinauer779b3e32008-11-10 15:43:37 +00002023 printk_debug("... ok\n");
Stefan Reinauer278534d2008-10-29 04:51:07 +00002024}
2025
2026static void sdram_disable_fast_dispatch(void)
2027{
2028 u32 reg32;
2029
2030 reg32 = MCHBAR32(FSBPMC3);
2031 reg32 |= (1 << 1);
2032 MCHBAR32(FSBPMC3) = reg32;
2033
2034 reg32 = MCHBAR32(SBTEST);
2035 reg32 |= (3 << 1);
2036 MCHBAR32(SBTEST) = reg32;
2037}
2038
2039static void sdram_pre_jedec_initialization(void)
2040{
2041 u32 reg32;
2042
2043 reg32 = MCHBAR32(WCC);
2044 reg32 &= 0x113ff3ff;
2045 reg32 |= (4 << 29) | (3 << 25) | (1 << 10);
2046 MCHBAR32(WCC) = reg32;
2047
2048 MCHBAR32(SMVREFC) |= (1 << 6);
2049
2050 MCHBAR32(MMARB0) &= ~(3 << 17);
2051 MCHBAR32(MMARB0) |= (1 << 21) | (1 << 16);
2052
2053 MCHBAR32(MMARB1) &= ~(7 << 8);
2054 MCHBAR32(MMARB1) |= (3 << 8);
2055
2056 MCHBAR32(C0AIT) = 0x000006c4;
2057 MCHBAR32(C0AIT+4) = 0x871a066d;
2058
2059 MCHBAR32(C1AIT) = 0x000006c4;
2060 MCHBAR32(C1AIT+4) = 0x871a066d;
2061}
2062
2063#define EA_DUALCHANNEL_XOR_BANK_RANK_MODE (0xd4 << 24)
2064#define EA_DUALCHANNEL_XOR_BANK_MODE (0xf4 << 24)
2065#define EA_DUALCHANNEL_BANK_RANK_MODE (0xc2 << 24)
2066#define EA_DUALCHANNEL_BANK_MODE (0xe2 << 24)
2067#define EA_SINGLECHANNEL_XOR_BANK_RANK_MODE (0x91 << 24)
2068#define EA_SINGLECHANNEL_XOR_BANK_MODE (0xb1 << 24)
2069#define EA_SINGLECHANNEL_BANK_RANK_MODE (0x80 << 24)
2070#define EA_SINGLECHANNEL_BANK_MODE (0xa0 << 24)
2071
2072static void sdram_enhanced_addressing_mode(struct sys_info *sysinfo)
2073{
2074 u32 chan0 = 0, chan1 = 0;
2075 int chan0_dualsided, chan1_dualsided, chan0_populated, chan1_populated;
2076
2077 chan0_populated = (sysinfo->dimm[0] != SYSINFO_DIMM_NOT_POPULATED ||
2078 sysinfo->dimm[1] != SYSINFO_DIMM_NOT_POPULATED);
2079 chan1_populated = (sysinfo->dimm[0] != SYSINFO_DIMM_NOT_POPULATED ||
2080 sysinfo->dimm[1] != SYSINFO_DIMM_NOT_POPULATED);
2081 chan0_dualsided = (sysinfo->banksize[1] || sysinfo->banksize[3]);
2082 chan1_dualsided = (sysinfo->banksize[5] || sysinfo->banksize[7]);
2083
2084 if (sdram_capabilities_enhanced_addressing_xor()) {
2085 if (!sysinfo->interleaved) {
2086 /* Single Channel & Dual Channel Assymetric */
2087 if (chan0_populated) {
2088 if (chan0_dualsided) {
2089 chan0 = EA_SINGLECHANNEL_XOR_BANK_RANK_MODE;
2090 } else {
2091 chan0 = EA_SINGLECHANNEL_XOR_BANK_MODE;
2092 }
2093 }
2094 if (chan1_populated) {
2095 if (chan1_dualsided) {
2096 chan1 = EA_SINGLECHANNEL_XOR_BANK_RANK_MODE;
2097 } else {
2098 chan1 = EA_SINGLECHANNEL_XOR_BANK_MODE;
2099 }
2100 }
2101 } else {
2102 /* Interleaved has always both channels populated */
2103 if (chan0_dualsided) {
2104 chan0 = EA_DUALCHANNEL_XOR_BANK_RANK_MODE;
2105 } else {
2106 chan0 = EA_DUALCHANNEL_XOR_BANK_MODE;
2107 }
2108
2109 if (chan1_dualsided) {
2110 chan1 = EA_DUALCHANNEL_XOR_BANK_RANK_MODE;
2111 } else {
2112 chan1 = EA_DUALCHANNEL_XOR_BANK_MODE;
2113 }
2114 }
2115 } else {
2116 if (!sysinfo->interleaved) {
2117 /* Single Channel & Dual Channel Assymetric */
2118 if (chan0_populated) {
2119 if (chan0_dualsided) {
2120 chan0 = EA_SINGLECHANNEL_BANK_RANK_MODE;
2121 } else {
2122 chan0 = EA_SINGLECHANNEL_BANK_MODE;
2123 }
2124 }
2125 if (chan1_populated) {
2126 if (chan1_dualsided) {
2127 chan1 = EA_SINGLECHANNEL_BANK_RANK_MODE;
2128 } else {
2129 chan1 = EA_SINGLECHANNEL_BANK_MODE;
2130 }
2131 }
2132 } else {
2133 /* Interleaved has always both channels populated */
2134 if (chan0_dualsided) {
2135 chan0 = EA_DUALCHANNEL_BANK_RANK_MODE;
2136 } else {
2137 chan0 = EA_DUALCHANNEL_BANK_MODE;
2138 }
2139
2140 if (chan1_dualsided) {
2141 chan1 = EA_DUALCHANNEL_BANK_RANK_MODE;
2142 } else {
2143 chan1 = EA_DUALCHANNEL_BANK_MODE;
2144 }
2145 }
2146 }
2147
2148 MCHBAR32(C0DRC1) &= 0x00ffffff;
2149 MCHBAR32(C0DRC1) |= chan0;
2150 MCHBAR32(C1DRC1) &= 0x00ffffff;
2151 MCHBAR32(C1DRC1) |= chan1;
2152}
2153
2154static void sdram_post_jedec_initialization(struct sys_info *sysinfo)
2155{
2156 u32 reg32;
2157
2158 /* Enable Channel XORing for Dual Channel Interleave */
2159 if (sysinfo->interleaved) {
2160 reg32 = MCHBAR32(DCC);
2161#if CHANNEL_XOR_RANDOMIZATION
2162 reg32 &= ~(1 << 10);
Stefan Reinauer30140a52009-03-11 16:20:39 +00002163 reg32 |= (1 << 9);
2164#else
Stefan Reinauer278534d2008-10-29 04:51:07 +00002165 reg32 &= ~(1 << 9);
Stefan Reinauer30140a52009-03-11 16:20:39 +00002166#endif
Stefan Reinauer278534d2008-10-29 04:51:07 +00002167 MCHBAR32(DCC) = reg32;
2168 }
2169
2170 /* DRAM mode optimizations */
2171 sdram_enhanced_addressing_mode(sysinfo);
2172
2173 reg32 = MCHBAR32(FSBPMC3);
2174 reg32 &= ~(1 << 1);
2175 MCHBAR32(FSBPMC3) = reg32;
2176
2177 reg32 = MCHBAR32(SBTEST);
2178 reg32 &= ~(1 << 2);
2179 MCHBAR32(SBTEST) = reg32;
2180
2181 reg32 = MCHBAR32(SBOCC);
2182 reg32 &= 0xffbdb6ff;
2183 reg32 |= (0xbdb6 << 8) | (1 << 0);
2184 MCHBAR32(SBOCC) = reg32;
2185}
2186
2187static void sdram_power_management(struct sys_info *sysinfo)
2188{
2189 u8 reg8;
2190 u16 reg16;
2191 u32 reg32;
2192 int integrated_graphics = 1;
2193 int i;
2194
2195 reg32 = MCHBAR32(C0DRT2);
2196 reg32 &= 0xffffff00;
2197 /* Idle timer = 8 clocks, CKE idle timer = 16 clocks */
2198 reg32 |= (1 << 5) | (1 << 4);
2199 MCHBAR32(C0DRT2) = reg32;
2200
2201 reg32 = MCHBAR32(C1DRT2);
2202 reg32 &= 0xffffff00;
2203 /* Idle timer = 8 clocks, CKE idle timer = 16 clocks */
2204 reg32 |= (1 << 5) | (1 << 4);
2205 MCHBAR32(C1DRT2) = reg32;
2206
2207 reg32 = MCHBAR32(C0DRC1);
2208
2209 reg32 |= (1 << 12) | (1 << 11);
2210 MCHBAR32(C0DRC1) = reg32;
2211
2212 reg32 = MCHBAR32(C1DRC1);
2213
2214 reg32 |= (1 << 12) | (1 << 11);
2215 MCHBAR32(C1DRC1) = reg32;
2216
2217 if (i945_silicon_revision()>1) {
2218 MCHBAR16(UPMC1) = 0x1010;
2219 } else {
2220 /* Rev 0 and 1 */
2221 MCHBAR16(UPMC1) = 0x0010;
2222 }
2223
2224 reg16 = MCHBAR16(UPMC2);
2225 reg16 &= 0xfc00;
2226 reg16 |= 0x0100;
2227 MCHBAR16(UPMC2) = reg16;
2228
2229 MCHBAR32(UPMC3) = 0x000f06ff;
2230
2231 for (i=0; i<5; i++) {
2232 MCHBAR32(UPMC3) &= ~(1 << 16);
2233 MCHBAR32(UPMC3) |= (1 << 16);
2234 }
2235
2236 MCHBAR32(GIPMC1) = 0x8000000c;
2237
2238 reg16 = MCHBAR16(CPCTL);
2239 reg16 &= ~(7 << 11);
2240 if (i945_silicon_revision()>2) {
2241 reg16 |= (6 << 11);
2242 } else {
2243 reg16 |= (4 << 11);
2244 }
2245 MCHBAR16(CPCTL) = reg16;
2246
Stefan Reinauer30140a52009-03-11 16:20:39 +00002247#if 0
2248 /* This is set later in the game */
Stefan Reinauer278534d2008-10-29 04:51:07 +00002249 if ((MCHBAR32(ECO) & (1 << 16)) != 0) {
Stefan Reinauer30140a52009-03-11 16:20:39 +00002250#else
2251 if (i945_silicon_revision() != 0) {
2252#endif
Stefan Reinauer278534d2008-10-29 04:51:07 +00002253 switch (sysinfo->fsb_frequency) {
2254 case 667: MCHBAR32(HGIPMC2) = 0x0d590d59; break;
2255 case 533: MCHBAR32(HGIPMC2) = 0x155b155b; break;
2256 }
2257 } else {
2258 switch (sysinfo->fsb_frequency) {
2259 case 667: MCHBAR32(HGIPMC2) = 0x09c409c4; break;
2260 case 533: MCHBAR32(HGIPMC2) = 0x0fa00fa0; break;
2261 }
2262 }
2263
2264 MCHBAR32(FSBPMC1) = 0x8000000c;
2265
2266 reg32 = MCHBAR32(C2C3TT);
2267 reg32 &= 0xffff0000;
2268 switch (sysinfo->fsb_frequency) {
2269 case 667: reg32 |= 0x0600; break;
2270 case 533: reg32 |= 0x0480; break;
2271 }
2272 MCHBAR32(C2C3TT) = reg32;
2273
2274 reg32 = MCHBAR32(C3C4TT);
2275 reg32 &= 0xffff0000;
2276 switch (sysinfo->fsb_frequency) {
2277 case 667: reg32 |= 0x0b80; break;
2278 case 533: reg32 |= 0x0980; break;
2279 }
2280 MCHBAR32(C3C4TT) = reg32;
2281
2282 if (i945_silicon_revision() == 0) {
2283 MCHBAR32(ECO) &= ~(1 << 16);
2284 } else {
2285 MCHBAR32(ECO) |= (1 << 16);
2286 }
2287
2288#if 0
2289 if (i945_silicon_revision() == 0) {
2290 MCHBAR32(FSBPMC3) &= ~(1 << 29);
2291 } else {
2292 MCHBAR32(FSBPMC3) |= (1 << 29);
2293 }
2294#endif
2295 MCHBAR32(FSBPMC3) &= ~(1 << 29);
2296
2297 MCHBAR32(FSBPMC3) |= (1 << 21);
2298
2299 MCHBAR32(FSBPMC3) &= ~(1 << 19);
2300
2301 MCHBAR32(FSBPMC3) &= ~(1 << 13);
2302
2303 reg32 = MCHBAR32(FSBPMC4);
2304 reg32 &= ~(3 << 24);
2305 reg32 |= ( 2 << 24);
2306 MCHBAR32(FSBPMC4) = reg32;
2307
2308 MCHBAR32(FSBPMC4) |= (1 << 21);
2309
2310 MCHBAR32(FSBPMC4) |= (1 << 5);
2311
2312 if (i945_silicon_revision() < 2) {
2313 /* stepping 0 and 1 */
2314 MCHBAR32(FSBPMC4) &= ~(1 << 4);
2315 } else {
Stefan Reinauer30140a52009-03-11 16:20:39 +00002316 MCHBAR32(FSBPMC4) |= (1 << 4);
Stefan Reinauer278534d2008-10-29 04:51:07 +00002317 }
2318
2319 reg8 = pci_read_config8(PCI_DEV(0,0x0,0), 0xfc);
2320 reg8 |= (1 << 4);
2321 pci_write_config8(PCI_DEV(0, 0x0, 0), 0xfc, reg8);
2322
2323 reg8 = pci_read_config8(PCI_DEV(0,0x2,0), 0xc1);
2324 reg8 |= (1 << 2);
2325 pci_write_config8(PCI_DEV(0, 0x2, 0), 0xc1, reg8);
2326
2327 if (integrated_graphics) {
2328 MCHBAR16(MIPMC4) = 0x0468;
2329 MCHBAR16(MIPMC5) = 0x046c;
2330 MCHBAR16(MIPMC6) = 0x046c;
2331 } else {
2332 MCHBAR16(MIPMC4) = 0x6468;
2333 MCHBAR16(MIPMC5) = 0x646c;
2334 MCHBAR16(MIPMC6) = 0x646c;
2335 }
2336
2337 reg32 = MCHBAR32(PMCFG);
2338 reg32 &= ~(3 << 17);
2339 reg32 |= (2 << 17);
2340 reg32 |= (1 << 4);
2341 MCHBAR32(PMCFG) = reg32;
2342
2343 reg32 = MCHBAR32(0xc30);
2344 reg32 &= 0xffffff00;
2345 reg32 |= 0x01;
2346 MCHBAR32(0xc30) = reg32;
2347
2348 MCHBAR32(0xb18) &= ~(1 << 21);
2349}
2350
2351static void sdram_thermal_management(void)
2352{
2353 /* The Thermal Sensors for DIMMs at 0x50, 0x52 are at I2C addr
2354 * 0x30/0x32.
2355 */
2356
2357 /* Explicitly set to 0 */
2358 MCHBAR8(TCO1) = 0x00;
2359 MCHBAR8(TCO0) = 0x00;
2360}
2361
2362#include "rcven.c"
2363
2364static void sdram_program_receive_enable(struct sys_info *sysinfo)
2365{
2366 MCHBAR32(REPC) |= (1 << 0);
2367
2368 receive_enable_adjust(sysinfo);
2369
2370 MCHBAR32(C0DRC1) |= (1 << 6);
2371 MCHBAR32(C1DRC1) |= (1 << 6);
2372 MCHBAR32(C0DRC1) &= ~(1 << 6);
2373 MCHBAR32(C1DRC1) &= ~(1 << 6);
2374
2375 MCHBAR32(MIPMC3) |= (0x0f << 0);
2376}
2377
2378/**
2379 * @brief Enable On-Die Termination for DDR2.
2380 *
2381 */
2382
2383static void sdram_on_die_termination(struct sys_info *sysinfo)
2384{
2385 static const u32 odt[] = {
2386 0x00024911, 0xe0010000,
2387 0x00049211, 0xe0020000,
2388 0x0006db11, 0xe0030000,
2389 };
2390
2391 u32 reg32;
2392 int cas;
2393
2394 reg32 = MCHBAR32(ODTC);
2395 reg32 &= ~(3 << 16);
2396 reg32 |= (1 << 14) | (1 << 6) | (2 << 16);
2397 MCHBAR32(ODTC) = reg32;
2398
2399 if ( !(sysinfo->dimm[0] != SYSINFO_DIMM_NOT_POPULATED &&
2400 sysinfo->dimm[1] != SYSINFO_DIMM_NOT_POPULATED) ) {
2401 printk_debug("one dimm per channel config.. \n");
2402
2403 reg32 = MCHBAR32(C0ODT);
2404 reg32 &= ~(7 << 28);
2405 MCHBAR32(C0ODT) = reg32;
2406 reg32 = MCHBAR32(C1ODT);
2407 reg32 &= ~(7 << 28);
2408 MCHBAR32(C1ODT) = reg32;
2409 }
2410
2411 cas = sysinfo->cas;
2412
2413 reg32 = MCHBAR32(C0ODT) & 0xfff00000;
2414 reg32 |= odt[(cas-3) * 2];
2415 MCHBAR32(C0ODT) = reg32;
2416
2417 reg32 = MCHBAR32(C1ODT) & 0xfff00000;
2418 reg32 |= odt[(cas-3) * 2];
2419 MCHBAR32(C1ODT) = reg32;
2420
2421 reg32 = MCHBAR32(C0ODT + 4) & 0x1fc8ffff;
2422 reg32 |= odt[((cas-3) * 2) + 1];
2423 MCHBAR32(C0ODT + 4) = reg32;
2424
2425 reg32 = MCHBAR32(C1ODT + 4) & 0x1fc8ffff;
2426 reg32 |= odt[((cas-3) * 2) + 1];
2427 MCHBAR32(C1ODT + 4) = reg32;
2428}
2429
2430/**
2431 * @brief Enable clocks to populated sockets
2432 */
2433
2434static void sdram_enable_memory_clocks(struct sys_info *sysinfo)
2435{
2436 u8 clocks[2] = { 0, 0 };
2437
2438 if (sysinfo->dimm[0] != SYSINFO_DIMM_NOT_POPULATED)
2439 clocks[0] |= (1 << 0) | (1 << 1);
2440
2441 if (sysinfo->dimm[1] != SYSINFO_DIMM_NOT_POPULATED)
2442 clocks[0] |= (1 << 2) | (1 << 3);
2443
2444 if (sysinfo->dimm[2] != SYSINFO_DIMM_NOT_POPULATED)
2445 clocks[1] |= (1 << 0) | (1 << 1);
2446
2447 if (sysinfo->dimm[3] != SYSINFO_DIMM_NOT_POPULATED)
2448 clocks[1] |= (1 << 2) | (1 << 3);
2449
2450#ifdef OVERRIDE_CLOCK_DISABLE
2451 clocks[0] = 0xf;
2452 clocks[1] = 0xf;
2453#endif
2454
2455 MCHBAR8(C0DCLKDIS) = clocks[0];
2456 MCHBAR8(C1DCLKDIS) = clocks[1];
2457}
2458
2459#define RTT_ODT_75_OHM (1 << 5)
2460#define RTT_ODT_150_OHM (1 << 9)
2461
2462#define EMRS_OCD_DEFAULT ( (1 << 12) | (1 << 11) | (1 << 10) )
2463
2464#define MRS_CAS_3 (3 << 7)
2465#define MRS_CAS_4 (4 << 7)
2466#define MRS_CAS_5 (5 << 7)
2467
2468#define MRS_TWR_3 (2 << 12)
2469#define MRS_TWR_4 (3 << 12)
2470#define MRS_TWR_5 (4 << 12)
2471
2472#define MRS_BT (1 << 6)
2473
2474#define MRS_BL4 (2 << 3)
2475#define MRS_BL8 (3 << 3)
2476
2477static void sdram_jedec_enable(struct sys_info *sysinfo)
2478{
2479 int i, nonzero;
2480 u32 bankaddr = 0, tmpaddr, mrsaddr = 0;
2481
2482 for (i = 0, nonzero = -1; i < 8; i++) {
2483 if (sysinfo->banksize[i] == 0) {
2484 continue;
2485 }
2486
2487 printk_debug("jedec enable sequence: bank %d\n", i);
2488 switch (i) {
2489 case 0:
2490 /* Start at address 0 */
2491 bankaddr = 0;
2492 break;
2493 case 4:
2494 if (sysinfo->interleaved) {
2495 bankaddr = 0x40;
2496 break;
2497 }
2498 default:
2499 if (nonzero != -1) {
2500 printk_debug("bankaddr from bank size of rank %d\n", nonzero);
2501 bankaddr += (1 << sysinfo->banksize[nonzero]) << (sysinfo->interleaved?28:27);
2502 break;
2503 }
2504 /* No populated bank hit before. Start at address 0 */
2505 bankaddr = 0;
2506 }
2507
2508 /* We have a bank with a non-zero size.. Remember it
2509 * for the next offset we have to calculate
2510 */
2511 nonzero = i;
2512
2513 /* Get CAS latency set up */
2514 switch (sysinfo->cas) {
2515 case 5: mrsaddr = MRS_CAS_5; break;
2516 case 4: mrsaddr = MRS_CAS_4; break;
2517 case 3: mrsaddr = MRS_CAS_3; break;
2518 default: die("Jedec Error (CAS).\n");
2519 }
2520
2521 /* Get tWR set */
2522 switch (sysinfo->twr) {
2523 case 5: mrsaddr |= MRS_TWR_5; break;
2524 case 4: mrsaddr |= MRS_TWR_4; break;
2525 case 3: mrsaddr |= MRS_TWR_3; break;
2526 default: die("Jedec Error (tWR).\n");
2527 }
2528
2529 /* Interleaved */
2530 if (sysinfo->interleaved) {
2531 mrsaddr |= MRS_BT;
2532 mrsaddr = mrsaddr << 1;
2533 }
2534
2535 /* Only burst length 8 supported */
2536 mrsaddr |= MRS_BL8;
2537
2538 /* Apply NOP */
Stefan Reinauer779b3e32008-11-10 15:43:37 +00002539 PRINTK_DEBUG("Apply NOP\n");
Stefan Reinauer278534d2008-10-29 04:51:07 +00002540 do_ram_command(RAM_COMMAND_NOP);
2541 ram_read32(bankaddr);
2542
2543 /* Precharge all banks */
Stefan Reinauer779b3e32008-11-10 15:43:37 +00002544 PRINTK_DEBUG("All Banks Precharge\n");
Stefan Reinauer278534d2008-10-29 04:51:07 +00002545 do_ram_command(RAM_COMMAND_PRECHARGE);
2546 ram_read32(bankaddr);
2547
2548 /* Extended Mode Register Set (2) */
Stefan Reinauer779b3e32008-11-10 15:43:37 +00002549 PRINTK_DEBUG("Extended Mode Register Set(2)\n");
Stefan Reinauer278534d2008-10-29 04:51:07 +00002550 do_ram_command(RAM_COMMAND_EMRS | RAM_EMRS_2);
2551 ram_read32(bankaddr);
2552
2553 /* Extended Mode Register Set (3) */
Stefan Reinauer779b3e32008-11-10 15:43:37 +00002554 PRINTK_DEBUG("Extended Mode Register Set(3)\n");
Stefan Reinauer278534d2008-10-29 04:51:07 +00002555 do_ram_command(RAM_COMMAND_EMRS | RAM_EMRS_3);
2556 ram_read32(bankaddr);
2557
2558 /* Extended Mode Register Set */
Stefan Reinauer779b3e32008-11-10 15:43:37 +00002559 PRINTK_DEBUG("Extended Mode Register Set\n");
Stefan Reinauer278534d2008-10-29 04:51:07 +00002560 do_ram_command(RAM_COMMAND_EMRS | RAM_EMRS_1);
2561 tmpaddr = bankaddr;
2562 if (!sdram_capabilities_dual_channel()) {
2563 tmpaddr |= RTT_ODT_75_OHM;
2564 } else if (sysinfo->interleaved) {
2565 tmpaddr |= (RTT_ODT_150_OHM << 1);
2566 } else {
2567 tmpaddr |= RTT_ODT_150_OHM;
2568 }
2569 ram_read32(tmpaddr);
2570
2571 /* Mode Register Set: Reset DLLs */
Stefan Reinauer779b3e32008-11-10 15:43:37 +00002572 PRINTK_DEBUG("MRS: Reset DLLs\n");
Stefan Reinauer278534d2008-10-29 04:51:07 +00002573 do_ram_command(RAM_COMMAND_MRS);
2574 tmpaddr = bankaddr;
2575 tmpaddr |= mrsaddr;
2576 /* Set DLL reset bit */
2577 if (sysinfo->interleaved)
2578 tmpaddr |= (1 << 12);
2579 else
2580 tmpaddr |= (1 << 11);
2581 ram_read32(tmpaddr);
2582
2583 /* Precharge all banks */
Stefan Reinauer779b3e32008-11-10 15:43:37 +00002584 PRINTK_DEBUG("All Banks Precharge\n");
Stefan Reinauer278534d2008-10-29 04:51:07 +00002585 do_ram_command(RAM_COMMAND_PRECHARGE);
2586 ram_read32(bankaddr);
2587
2588 /* CAS before RAS Refresh */
Stefan Reinauer779b3e32008-11-10 15:43:37 +00002589 PRINTK_DEBUG("CAS before RAS\n");
Stefan Reinauer278534d2008-10-29 04:51:07 +00002590 do_ram_command(RAM_COMMAND_CBR);
2591
2592 /* CBR wants two READs */
2593 ram_read32(bankaddr);
2594 ram_read32(bankaddr);
2595
2596 /* Mode Register Set: Enable DLLs */
Stefan Reinauer779b3e32008-11-10 15:43:37 +00002597 PRINTK_DEBUG("MRS: Enable DLLs\n");
Stefan Reinauer278534d2008-10-29 04:51:07 +00002598 do_ram_command(RAM_COMMAND_MRS);
2599
2600 tmpaddr = bankaddr;
2601 tmpaddr |= mrsaddr;
2602 ram_read32(tmpaddr);
2603
2604 /* Extended Mode Register Set */
Stefan Reinauer779b3e32008-11-10 15:43:37 +00002605 PRINTK_DEBUG("Extended Mode Register Set: ODT/OCD\n");
Stefan Reinauer278534d2008-10-29 04:51:07 +00002606 do_ram_command(RAM_COMMAND_EMRS | RAM_EMRS_1);
2607
2608 tmpaddr = bankaddr;
2609 if (!sdram_capabilities_dual_channel()) {
2610
2611 tmpaddr |= RTT_ODT_75_OHM | EMRS_OCD_DEFAULT;
2612 } else if (sysinfo->interleaved) {
2613 tmpaddr |= ((RTT_ODT_150_OHM | EMRS_OCD_DEFAULT) << 1);
2614 } else {
2615 tmpaddr |= RTT_ODT_150_OHM | EMRS_OCD_DEFAULT;
2616 }
2617 ram_read32(tmpaddr);
2618
2619 /* Extended Mode Register Set */
Stefan Reinauer779b3e32008-11-10 15:43:37 +00002620 PRINTK_DEBUG("Extended Mode Register Set: OCD Exit\n");
Stefan Reinauer278534d2008-10-29 04:51:07 +00002621 do_ram_command(RAM_COMMAND_EMRS | RAM_EMRS_1);
2622
2623 tmpaddr = bankaddr;
2624 if (!sdram_capabilities_dual_channel()) {
2625 tmpaddr |= RTT_ODT_75_OHM;
2626 } else if (sysinfo->interleaved) {
2627 tmpaddr |= (RTT_ODT_150_OHM << 1);
2628 } else {
2629 tmpaddr |= RTT_ODT_150_OHM;
2630 }
2631 ram_read32(tmpaddr);
2632 }
2633}
2634
2635static void sdram_init_complete(void)
2636{
Stefan Reinauer779b3e32008-11-10 15:43:37 +00002637 PRINTK_DEBUG("Normal Operation\n");
Stefan Reinauer278534d2008-10-29 04:51:07 +00002638 do_ram_command(RAM_COMMAND_NORMAL);
2639}
2640
2641static void sdram_setup_processor_side(void)
2642{
2643 if (i945_silicon_revision() == 0)
2644 MCHBAR32(FSBPMC3) |= (1 << 2);
2645
2646 MCHBAR8(0xb00) |= 1;
2647
2648 if (i945_silicon_revision() == 0)
2649 MCHBAR32(SLPCTL) |= (1 << 8);
2650}
2651
2652#define BOOT_MODE_RESUME 1
2653#define BOOT_MODE_NORMAL 0
2654
2655/**
2656 * @param boot_mode: 0 = normal, 1 = resume
2657 */
2658void sdram_initialize(int boot_mode)
2659{
2660 struct sys_info sysinfo;
2661 u8 reg8, cas_mask;
2662
2663 sdram_detect_errors();
2664
Stefan Reinauer779b3e32008-11-10 15:43:37 +00002665 printk_debug ("Setting up RAM controller.\n");
Stefan Reinauer278534d2008-10-29 04:51:07 +00002666
2667 memset(&sysinfo, 0, sizeof(sysinfo));
2668
2669 /* Look at the type of DIMMs and verify all DIMMs are x8 or x16 width */
2670 sdram_get_dram_configuration(&sysinfo);
2671
2672 /* Check whether we have stacked DIMMs */
2673 sdram_verify_package_type(&sysinfo);
2674
2675 /* Determine common CAS */
2676 cas_mask = sdram_possible_cas_latencies(&sysinfo);
2677
2678 /* Choose Common Frequency */
2679 sdram_detect_cas_latency_and_ram_speed(&sysinfo, cas_mask);
2680
2681 /* Determine smallest common tRAS */
2682 sdram_detect_smallest_tRAS(&sysinfo);
2683
2684 /* Determine tRP */
2685 sdram_detect_smallest_tRP(&sysinfo);
2686
2687 /* Determine tRCD */
2688 sdram_detect_smallest_tRCD(&sysinfo);
2689
2690 /* Determine smallest refresh period */
2691 sdram_detect_smallest_refresh(&sysinfo);
2692
2693 /* Verify all DIMMs support burst length 8 */
2694 sdram_verify_burst_length(&sysinfo);
2695
2696 /* determine tWR */
2697 sdram_detect_smallest_tWR(&sysinfo);
2698
2699 /* Determine DIMM size parameters (rows, columns banks) */
2700 sdram_detect_dimm_size(&sysinfo);
2701
2702 /* determine tRFC */
2703 sdram_detect_smallest_tRFC(&sysinfo);
2704
2705 /* Program PLL settings */
2706 sdram_program_pll_settings();
2707
2708 /* Program Graphics Frequency */
2709 sdram_program_graphics_frequency(&sysinfo);
2710
2711 /* Program System Memory Frequency */
2712 sdram_program_memory_frequency(&sysinfo);
2713
2714 /* Determine Mode of Operation (Interleaved etc) */
2715 sdram_set_channel_mode(&sysinfo);
2716
2717 /* Program Clock Crossing values */
2718 sdram_program_clock_crossing();
2719
2720 /* Disable fast dispatch */
2721 sdram_disable_fast_dispatch();
2722
2723 /* Enable WIODLL Power Down in ACPI states */
2724 MCHBAR32(C0DMC) |= (1 << 24);
2725 MCHBAR32(C1DMC) |= (1 << 24);
2726
2727 /* Program DRAM Row Boundary/Attribute Registers */
2728
2729 if (boot_mode != BOOT_MODE_RESUME) {
2730 /* program row size DRB and set TOLUD */
2731 sdram_program_row_boundaries(&sysinfo);
2732
2733 /* program page size DRA */
2734 sdram_set_row_attributes(&sysinfo);
2735 }
2736
2737 /* Program CxBNKARC */
2738 sdram_set_bank_architecture(&sysinfo);
2739
2740 /* Program DRAM Timing and Control registers based on SPD */
2741 sdram_set_timing_and_control(&sysinfo);
2742
2743 /* On-Die Termination Adjustment */
2744 sdram_on_die_termination(&sysinfo);
2745
2746 /* Pre Jedec Initialization */
2747 sdram_pre_jedec_initialization();
2748
2749 /* Perform System Memory IO Initialization */
2750 sdram_initialize_system_memory_io(&sysinfo);
2751
2752 /* Perform System Memory IO Buffer Enable */
2753 sdram_enable_system_memory_io(&sysinfo);
2754
2755 /* Enable System Memory Clocks */
2756 sdram_enable_memory_clocks(&sysinfo);
2757
2758 if (boot_mode != BOOT_MODE_RESUME) {
2759 /* Jedec Initialization sequence */
2760 sdram_jedec_enable(&sysinfo);
2761 }
2762
2763 /* Program Power Management Registers */
2764 sdram_power_management(&sysinfo);
2765
2766 /* Post Jedec Init */
2767 sdram_post_jedec_initialization(&sysinfo);
2768
2769 /* Program DRAM Throttling */
2770 sdram_thermal_management();
2771
2772 /* Normal Operations */
2773 sdram_init_complete();
2774
2775 /* Program Receive Enable Timings */
2776 sdram_program_receive_enable(&sysinfo);
2777
2778 /* Enable Periodic RCOMP */
2779 sdram_enable_rcomp();
2780
2781 /* Tell ICH7 that we're done */
2782 reg8 = pci_read_config8(PCI_DEV(0,0x1f,0), 0xa2);
2783 reg8 &= ~(1 << 7);
2784 pci_write_config8(PCI_DEV(0, 0x1f, 0), 0xa2, reg8);
2785
Stefan Reinauer779b3e32008-11-10 15:43:37 +00002786 printk_debug("RAM initialization finished.\n");
Stefan Reinauer278534d2008-10-29 04:51:07 +00002787
2788 sdram_setup_processor_side();
2789}
2790