tree: drop last paragraph of GPL copyright header
[coreboot.git] / src / northbridge / amd / gx2 / raminit.c
blob46ec6b88307da982d6994daf8f2d79bc86fd0d98
1 /*
2 * This file is part of the coreboot project.
4 * Copyright (C) 2007 Advanced Micro Devices, Inc.
5 * Copyright (C) 2010 Nils Jacobs
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
17 #include <cpu/amd/gx2def.h>
18 #include <spd.h>
20 static const unsigned char NumColAddr[] = {
21 0x00, 0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x07,
22 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
25 static void __attribute__((noreturn)) hcf(void)
27 printk(BIOS_EMERG, "DIE\n");
28 /* this guarantees we flush the UART fifos (if any) and also
29 * ensures that things, in general, keep going so no debug output
30 * is lost
32 while (1)
33 printk(BIOS_EMERG, (0));
36 static void auto_size_dimm(unsigned int dimm)
38 uint32_t dimm_setting;
39 uint16_t dimm_size;
40 uint8_t spd_byte;
41 msr_t msr;
43 dimm_setting = 0;
45 printk(BIOS_DEBUG, "Check present\n");
46 /* Check that we have a dimm */
47 if (spd_read_byte(dimm, SPD_MEMORY_TYPE) == 0xFF) {
48 return;
51 printk(BIOS_DEBUG, "MODBANKS\n");
52 /* Field: Module Banks per DIMM */
53 /* EEPROM byte usage: (5) Number of DIMM Banks */
54 spd_byte = spd_read_byte(dimm, SPD_NUM_DIMM_BANKS);
55 if ((MIN_MOD_BANKS > spd_byte) || (spd_byte > MAX_MOD_BANKS)) {
56 printk(BIOS_EMERG, "Number of module banks not compatible\n");
57 post_code(ERROR_BANK_SET);
58 hcf();
60 dimm_setting |= (spd_byte >> 1) << CF07_UPPER_D0_MB_SHIFT;
62 printk(BIOS_DEBUG, "FIELDBANKS\n");
63 /* Field: Banks per SDRAM device */
64 /* EEPROM byte usage: (17) Number of Banks on SDRAM Device */
65 spd_byte = spd_read_byte(dimm, SPD_NUM_BANKS_PER_SDRAM);
66 if ((MIN_DEV_BANKS > spd_byte) || (spd_byte > MAX_DEV_BANKS)) {
67 printk(BIOS_EMERG, "Number of device banks not compatible\n");
68 post_code(ERROR_BANK_SET);
69 hcf();
71 dimm_setting |= (spd_byte >> 2) << CF07_UPPER_D0_CB_SHIFT;
73 printk(BIOS_DEBUG, "SPDNUMROWS\n");
74 /* Field: DIMM size
75 * EEPROM byte usage:
76 * (3) Number of Row Addresses
77 * (4) Number of Column Addresses
78 * (5) Number of DIMM Banks
79 * (31) Module Bank Density
80 * Size = Module Density * Module Banks
82 if ((spd_read_byte(dimm, SPD_NUM_ROWS) & 0xF0)
83 || (spd_read_byte(dimm, SPD_NUM_COLUMNS) & 0xF0)) {
84 printk(BIOS_EMERG, "Asymmetric DIMM not compatible\n");
85 post_code(ERROR_UNSUPPORTED_DIMM);
86 hcf();
89 printk(BIOS_DEBUG, "SPDBANKDENSITY\n");
90 dimm_size = spd_read_byte(dimm, SPD_BANK_DENSITY);
91 printk(BIOS_DEBUG, "DIMMSIZE\n");
92 dimm_size |= (dimm_size << 8); /* align so 1GB(bit0) is bit 8, this is a little weird to get gcc to not optimize this out */
93 dimm_size &= 0x01FC; /* and off 2GB DIMM size : not supported and the 1GB size we just moved up to bit 8 as well as all the extra on top */
95 /* Module Density * Module Banks */
96 dimm_size <<= (dimm_setting >> CF07_UPPER_D0_MB_SHIFT) & 1; /* shift to multiply by # DIMM banks */
97 printk(BIOS_DEBUG, "BEFORT CTZ\n");
98 dimm_size = __builtin_ctz(dimm_size);
99 printk(BIOS_DEBUG, "TEST DIMM SIZE>7\n");
100 if (dimm_size > 7) { /* 7 is 512MB only support 512MB per DIMM */
101 printk(BIOS_EMERG, "Only support up to 512MB per DIMM\n");
102 post_code(ERROR_DENSITY_DIMM);
103 hcf();
105 dimm_setting |= dimm_size << CF07_UPPER_D0_SZ_SHIFT;
106 printk(BIOS_DEBUG, "PAGESIZE\n");
109 * Field: PAGE size
110 * EEPROM byte usage: (4) Number of Column Addresses
111 * PageSize = 2^# Column Addresses * Data width in bytes
112 * (should be 8bytes for a normal DIMM)
114 * But this really works by magic.
115 * If ma[11:0] is the memory address pins, and pa[13:0] is the physical column
116 * address that MC generates, here is how the MC assigns the pa onto the
117 * ma pins:
119 * ma 11 10 09 08 07 06 05 04 03 02 01 00
120 * ---------------------------------------
121 * pa 09 08 07 06 05 04 03 (7 col addr bits = 1K page size)
122 * pa 10 09 08 07 06 05 04 03 (8 col addr bits = 2K page size)
123 * pa 11 10 09 08 07 06 05 04 03 (9 col addr bits = 4K page size)
124 * pa 12 11 10 09 08 07 06 05 04 03 (10 col addr bits = 8K page size)
125 * pa 13 AP 12 11 10 09 08 07 06 05 04 03 (11 col addr bits = 16K page size)
127 * (AP = autoprecharge bit)
129 * Remember that pa[2:0] are zeroed out since it's a 64-bit data bus (8 bytes),
130 * so lower 3 address bits are dont_cares. So from the table above,
131 * it's easier to see what the old code is doing: if for example,
132 * #col_addr_bits=7(06h), it adds 3 to get 10, then does 2^10=1K.
135 spd_byte = NumColAddr[spd_read_byte(dimm, SPD_NUM_COLUMNS) & 0xF];
136 printk(BIOS_DEBUG, "MAXCOLADDR\n");
137 if (spd_byte > MAX_COL_ADDR) {
138 printk(BIOS_EMERG, "DIMM page size not compatible\n");
139 post_code(ERROR_SET_PAGE);
140 hcf();
142 printk(BIOS_DEBUG, ">11address test\n");
143 spd_byte -= 7;
144 if (spd_byte > 4) { /* if the value is above 4 it means >11 col address lines */
145 spd_byte = 7; /* which means >16k so set to disabled */
147 dimm_setting |= spd_byte << CF07_UPPER_D0_PSZ_SHIFT; /* 0=1k,1=2k,2=4k,etc */
149 printk(BIOS_DEBUG, "RDMSR CF07\n");
150 msr = rdmsr(MC_CF07_DATA);
151 printk(BIOS_DEBUG, "WRMSR CF07\n");
152 if (dimm == DIMM0) {
153 msr.hi &= 0xFFFF0000;
154 msr.hi |= dimm_setting;
155 } else {
156 msr.hi &= 0x0000FFFF;
157 msr.hi |= dimm_setting << 16;
159 wrmsr(MC_CF07_DATA, msr);
160 printk(BIOS_DEBUG, "ALL DONE\n");
163 static void checkDDRMax(void)
165 uint8_t spd_byte0, spd_byte1;
166 uint16_t speed;
168 /* PC133 identifier */
169 spd_byte0 = spd_read_byte(DIMM0, SPD_MIN_CYCLE_TIME_AT_CAS_MAX);
170 if (spd_byte0 == 0xFF) {
171 spd_byte0 = 0;
173 spd_byte1 = spd_read_byte(DIMM1, SPD_MIN_CYCLE_TIME_AT_CAS_MAX);
174 if (spd_byte1 == 0xFF) {
175 spd_byte1 = 0;
178 /* Use the slowest DIMM */
179 if (spd_byte0 < spd_byte1) {
180 spd_byte0 = spd_byte1;
183 /* Turn SPD ns time into MHZ. Check what the asm does to this math. */
184 speed = 20000 / (((spd_byte0 >> 4) * 10) + (spd_byte0 & 0x0F));
186 /* current speed > max speed? */
187 if (GeodeLinkSpeed() > speed) {
188 printk(BIOS_EMERG, "DIMM overclocked. Check GeodeLink Speed\n");
189 post_code(POST_PLL_MEM_FAIL);
190 hcf();
194 const uint16_t REF_RATE[] = { 15, 3, 7, 31, 62, 125 }; /* ns */
196 static void set_refresh_rate(void)
198 uint8_t spd_byte0, spd_byte1;
199 uint16_t rate0, rate1;
200 msr_t msr;
202 spd_byte0 = spd_read_byte(DIMM0, SPD_REFRESH);
203 spd_byte0 &= 0xF;
204 if (spd_byte0 > 5) {
205 spd_byte0 = 5;
207 rate0 = REF_RATE[spd_byte0];
209 spd_byte1 = spd_read_byte(DIMM1, SPD_REFRESH);
210 spd_byte1 &= 0xF;
211 if (spd_byte1 > 5) {
212 spd_byte1 = 5;
214 rate1 = REF_RATE[spd_byte1];
216 /* Use the faster rate (lowest number) */
217 if (rate0 > rate1) {
218 rate0 = rate1;
221 msr = rdmsr(MC_CF07_DATA);
222 msr.lo |= ((rate0 * (GeodeLinkSpeed() / 2)) / 16)
223 << CF07_LOWER_REF_INT_SHIFT;
224 wrmsr(MC_CF07_DATA, msr);
227 const uint8_t CASDDR[] = { 5, 5, 2, 6, 0 }; /* 1(1.5), 1.5, 2, 2.5, 0 */
229 static u8 getcasmap(u32 dimm, u16 glspeed)
231 u16 dimm_speed;
232 u8 spd_byte, casmap, casmap_shift=0;
234 /************************** DIMM0 **********************************/
235 casmap = spd_read_byte(dimm, SPD_ACCEPTABLE_CAS_LATENCIES);
236 if (casmap != 0xFF) {
237 /* IF -.5 timing is supported, check -.5 timing > GeodeLink */
238 spd_byte = spd_read_byte(dimm, SPD_SDRAM_CYCLE_TIME_2ND);
239 if (spd_byte != 0) {
240 /* Turn SPD ns time into MHZ. Check what the asm does to this math. */
241 dimm_speed = 20000 / (((spd_byte >> 4) * 10) + (spd_byte & 0x0F));
242 if (dimm_speed >= glspeed) {
243 casmap_shift = 1; /* -.5 is a shift of 1 */
244 /* IF -1 timing is supported, check -1 timing > GeodeLink */
245 spd_byte = spd_read_byte(dimm, SPD_SDRAM_CYCLE_TIME_3RD);
246 if (spd_byte != 0) {
247 /* Turn SPD ns time into MHZ. Check what the asm does to this math. */
248 dimm_speed = 20000 / (((spd_byte >> 4) * 10) + (spd_byte & 0x0F));
249 if (dimm_speed >= glspeed) {
250 casmap_shift = 2; /* -1 is a shift of 2 */
252 } /* SPD_SDRAM_CYCLE_TIME_3RD (-1) !=0 */
253 } else {
254 casmap_shift = 0;
256 } /* SPD_SDRAM_CYCLE_TIME_2ND (-.5) !=0 */
257 /* set the casmap based on the shift to limit possible CAS settings */
258 spd_byte = 31 - __builtin_clz((uint32_t) casmap);
259 /* just want bits in the lower byte since we have to cast to a 32 */
260 casmap &= 0xFF << (spd_byte - casmap_shift);
261 } else { /* No DIMM */
262 casmap = 0;
264 return casmap;
267 static void setCAS(void)
270 * setCAS
271 * EEPROM byte usage: (18) SDRAM device attributes - CAS latency
272 * EEPROM byte usage: (23) SDRAM Minimum Clock Cycle Time @ CLX -.5
273 * EEPROM byte usage: (25) SDRAM Minimum Clock Cycle Time @ CLX -1
275 * The CAS setting is based on the information provided in each DIMMs SPD.
276 * The speed at which a DIMM can run is described relative to the slowest
277 * CAS the DIMM supports. Each speed for the relative CAS settings is
278 * checked that it is within the GeodeLink speed. If it isn't within the GeodeLink
279 * speed, the CAS setting is removed from the list of good settings for
280 * the DIMM. This is done for both DIMMs and the lists are compared to
281 * find the lowest common CAS latency setting. If there are no CAS settings
282 * in common we out a ERROR_DIFF_DIMMS (78h) to port 80h and halt.
284 * Entry:
285 * Exit: Set fastest CAS Latency based on GeodeLink speed and SPD information.
286 * Destroys: We really use everything !
288 uint16_t glspeed;
289 uint8_t spd_byte, casmap0, casmap1;
290 msr_t msr;
292 glspeed = GeodeLinkSpeed();
294 casmap0 = getcasmap(DIMM0, glspeed);
295 casmap1 = getcasmap(DIMM1, glspeed);
297 /* CAS_LAT MAP COMPARE */
298 if (casmap0 == 0) {
299 spd_byte = CASDDR[__builtin_ctz(casmap1)];
300 } else if (casmap1 == 0) {
301 spd_byte = CASDDR[__builtin_ctz(casmap0)];
302 } else if ((casmap0 &= casmap1)) {
303 spd_byte = CASDDR[__builtin_ctz(casmap0)];
304 } else {
305 printk(BIOS_EMERG, "DIMM CAS Latencies not compatible\n");
306 post_code(ERROR_DIFF_DIMMS);
307 hcf();
310 msr = rdmsr(MC_CF8F_DATA);
311 msr.lo &= ~(7 << CF8F_LOWER_CAS_LAT_SHIFT);
312 msr.lo |= spd_byte << CF8F_LOWER_CAS_LAT_SHIFT;
313 wrmsr(MC_CF8F_DATA, msr);
316 static void set_latencies(void)
318 uint32_t memspeed, dimm_setting;
319 uint8_t spd_byte0, spd_byte1;
320 msr_t msr;
322 memspeed = GeodeLinkSpeed() / 2;
323 dimm_setting = 0;
325 /* MC_CF8F setup */
326 /* tRAS */
327 spd_byte0 = spd_read_byte(DIMM0, SPD_tRAS);
328 if (spd_byte0 == 0xFF) {
329 spd_byte0 = 0;
331 spd_byte1 = spd_read_byte(DIMM1, SPD_tRAS);
332 if (spd_byte1 == 0xFF) {
333 spd_byte1 = 0;
335 if (spd_byte0 < spd_byte1) {
336 spd_byte0 = spd_byte1;
338 /* (ns/(1/MHz) = (us*MHZ)/1000 = clocks/1000 = clocks) */
339 spd_byte1 = (spd_byte0 * memspeed) / 1000;
340 if (((spd_byte0 * memspeed) % 1000)) {
341 ++spd_byte1;
343 if (spd_byte1 > 6) {
344 --spd_byte1;
346 dimm_setting |= spd_byte1 << CF8F_LOWER_ACT2PRE_SHIFT;
348 /* tRP */
349 spd_byte0 = spd_read_byte(DIMM0, SPD_tRP);
350 if (spd_byte0 == 0xFF) {
351 spd_byte0 = 0;
353 spd_byte1 = spd_read_byte(DIMM1, SPD_tRP);
354 if (spd_byte1 == 0xFF) {
355 spd_byte1 = 0;
357 if (spd_byte0 < spd_byte1) {
358 spd_byte0 = spd_byte1;
360 /* (ns/(1/MHz) = (us*MHZ)/1000 = clocks/1000 = clocks) */
361 spd_byte1 = ((spd_byte0 >> 2) * memspeed) / 1000;
362 if ((((spd_byte0 >> 2) * memspeed) % 1000)) {
363 ++spd_byte1;
365 dimm_setting |= spd_byte1 << CF8F_LOWER_PRE2ACT_SHIFT;
367 /* tRCD */
368 spd_byte0 = spd_read_byte(DIMM0, SPD_tRCD);
369 if (spd_byte0 == 0xFF) {
370 spd_byte0 = 0;
372 spd_byte1 = spd_read_byte(DIMM1, SPD_tRCD);
373 if (spd_byte1 == 0xFF) {
374 spd_byte1 = 0;
376 if (spd_byte0 < spd_byte1) {
377 spd_byte0 = spd_byte1;
379 /* (ns/(1/MHz) = (us*MHZ)/1000 = clocks/1000 = clocks) */
380 spd_byte1 = ((spd_byte0 >> 2) * memspeed) / 1000;
381 if ((((spd_byte0 >> 2) * memspeed) % 1000)) {
382 ++spd_byte1;
384 dimm_setting |= spd_byte1 << CF8F_LOWER_ACT2CMD_SHIFT;
386 /* tRRD */
387 spd_byte0 = spd_read_byte(DIMM0, SPD_tRRD);
388 if (spd_byte0 == 0xFF) {
389 spd_byte0 = 0;
391 spd_byte1 = spd_read_byte(DIMM1, SPD_tRRD);
392 if (spd_byte1 == 0xFF) {
393 spd_byte1 = 0;
395 if (spd_byte0 < spd_byte1) {
396 spd_byte0 = spd_byte1;
398 /* (ns/(1/MHz) = (us*MHZ)/1000 = clocks/1000 = clocks) */
399 spd_byte1 = ((spd_byte0 >> 2) * memspeed) / 1000;
400 if ((((spd_byte0 >> 2) * memspeed) % 1000)) {
401 ++spd_byte1;
403 dimm_setting |= spd_byte1 << CF8F_LOWER_ACT2ACT_SHIFT;
405 /* tRC = tRP + tRAS */
406 dimm_setting |= (((dimm_setting >> CF8F_LOWER_ACT2PRE_SHIFT) & 0x0F) +
407 ((dimm_setting >> CF8F_LOWER_PRE2ACT_SHIFT) & 0x07))
408 << CF8F_LOWER_REF2ACT_SHIFT;
410 msr = rdmsr(MC_CF8F_DATA);
411 msr.lo &= 0xF00000FF;
412 msr.lo |= dimm_setting;
413 msr.hi |= CF8F_UPPER_REORDER_DIS_SET;
414 wrmsr(MC_CF8F_DATA, msr);
415 printk(BIOS_DEBUG, "MSR MC_CF8F_DATA (%08x) value is %08x:%08x\n",
416 MC_CF8F_DATA, msr.hi, msr.lo);
419 static void set_extended_mode_registers(void)
421 uint8_t spd_byte0, spd_byte1;
422 msr_t msr;
423 spd_byte0 = spd_read_byte(DIMM0, SPD_DEVICE_ATTRIBUTES_GENERAL);
424 if (spd_byte0 == 0xFF) {
425 spd_byte0 = 0;
427 spd_byte1 = spd_read_byte(DIMM1, SPD_DEVICE_ATTRIBUTES_GENERAL);
428 if (spd_byte1 == 0xFF) {
429 spd_byte1 = 0;
431 spd_byte1 &= spd_byte0;
433 msr = rdmsr(MC_CF07_DATA);
434 if (spd_byte1 & 1) { /* Drive Strength Control */
435 msr.lo |= CF07_LOWER_EMR_DRV_SET;
437 if (spd_byte1 & 2) { /* FET Control */
438 msr.lo |= CF07_LOWER_EMR_QFC_SET;
440 wrmsr(MC_CF07_DATA, msr);
443 static void sdram_set_registers(const struct mem_controller *ctrl)
445 msr_t msr;
446 uint32_t msrnum;
448 /* Set Refresh Staggering */
449 msrnum = MC_CF07_DATA;
450 msr = rdmsr(msrnum);
451 msr.lo &= ~0xC0;
452 msr.lo |= 0x0; /* set refresh to 4SDRAM clocks */
453 wrmsr(msrnum, msr);
456 static void sdram_set_spd_registers(const struct mem_controller *ctrl)
458 uint8_t spd_byte;
460 printk(BIOS_DEBUG, "sdram_set_spd_register\n");
461 post_code(POST_MEM_SETUP); /* post_70h */
463 spd_byte = spd_read_byte(DIMM0, SPD_MODULE_ATTRIBUTES);
464 printk(BIOS_DEBUG, "Check DIMM 0\n");
465 /* Check DIMM is not Register and not Buffered DIMMs. */
466 if ((spd_byte != 0xFF) && (spd_byte & 3)) {
467 printk(BIOS_EMERG, "DIMM0 NOT COMPATIBLE\n");
468 post_code(ERROR_UNSUPPORTED_DIMM);
469 hcf();
471 printk(BIOS_DEBUG, "Check DIMM 1\n");
472 spd_byte = spd_read_byte(DIMM1, SPD_MODULE_ATTRIBUTES);
473 if ((spd_byte != 0xFF) && (spd_byte & 3)) {
474 printk(BIOS_EMERG, "DIMM1 NOT COMPATIBLE\n");
475 post_code(ERROR_UNSUPPORTED_DIMM);
476 hcf();
479 post_code(POST_MEM_SETUP2); /* post_72h */
480 printk(BIOS_DEBUG, "Check DDR MAX\n");
482 /* Check that the memory is not overclocked. */
483 checkDDRMax();
485 /* Size the DIMMS */
486 post_code(POST_MEM_SETUP3); /* post_73h */
487 printk(BIOS_DEBUG, "AUTOSIZE DIMM 0\n");
488 auto_size_dimm(DIMM0);
489 post_code(POST_MEM_SETUP4); /* post_74h */
490 printk(BIOS_DEBUG, "AUTOSIZE DIMM 1\n");
491 auto_size_dimm(DIMM1);
493 /* Set CAS latency */
494 printk(BIOS_DEBUG, "set cas latency\n");
495 post_code(POST_MEM_SETUP5); /* post_75h */
496 setCAS();
498 /* Set all the other latencies here (tRAS, tRP....) */
499 printk(BIOS_DEBUG, "set all latency\n");
500 set_latencies();
502 /* Set Extended Mode Registers */
503 printk(BIOS_DEBUG, "set emrs\n");
504 set_extended_mode_registers();
506 printk(BIOS_DEBUG, "set ref rate\n");
507 /* Set Memory Refresh Rate */
508 set_refresh_rate();
511 /* Section 6.1.3, LX processor databooks, BIOS Initialization Sequence
512 * Section 4.1.4, GX/CS5535 GeodeROM Porting guide */
513 static void sdram_enable(int controllers, const struct mem_controller *ctrl)
515 int i;
516 msr_t msr;
518 /* 2. clock gating for PMode */
519 msr = rdmsr(MC_GLD_MSR_PM);
520 msr.lo &= ~0x04;
521 msr.lo |= 0x01;
522 wrmsr(MC_GLD_MSR_PM, msr);
523 /* undocmented bits in GX, in LX there are
524 * 8 bits in PM1_UP_DLY */
525 msr = rdmsr(MC_CF1017_DATA);
526 msr.lo = 0x0101;
527 wrmsr(MC_CF1017_DATA, msr);
528 printk(BIOS_DEBUG, "sdram_enable step 2\n");
530 /* 3. release CKE mask to enable CKE */
531 msr = rdmsr(MC_CFCLK_DBUG);
532 msr.lo &= ~(0x03 << 8);
533 wrmsr(MC_CFCLK_DBUG, msr);
534 printk(BIOS_DEBUG, "sdram_enable step 3\n");
536 /* 4. set and clear REF_TST 16 times, more shouldn't hurt
537 * why this is before EMRS and MRS ? */
538 for (i = 0; i < 19; i++) {
539 msr = rdmsr(MC_CF07_DATA);
540 msr.lo |= (0x01 << 3);
541 wrmsr(MC_CF07_DATA, msr);
542 msr.lo &= ~(0x01 << 3);
543 wrmsr(MC_CF07_DATA, msr);
545 printk(BIOS_DEBUG, "sdram_enable step 4\n");
547 /* 6. enable DLL, load Extended Mode Register by set and clear PROG_DRAM */
548 msr = rdmsr(MC_CF07_DATA);
549 msr.lo |= ((0x01 << 28) | 0x01);
550 wrmsr(MC_CF07_DATA, msr);
551 msr.lo &= ~((0x01 << 28) | 0x01);
552 wrmsr(MC_CF07_DATA, msr);
553 printk(BIOS_DEBUG, "sdram_enable step 6\n");
555 /* 7. Reset DLL, Bit 27 is undocumented in GX datasheet,
556 * it is documented in LX datasheet */
557 /* load Mode Register by set and clear PROG_DRAM */
558 msr = rdmsr(MC_CF07_DATA);
559 msr.lo |= ((0x01 << 27) | 0x01);
560 wrmsr(MC_CF07_DATA, msr);
561 msr.lo &= ~((0x01 << 27) | 0x01);
562 wrmsr(MC_CF07_DATA, msr);
563 printk(BIOS_DEBUG, "sdram_enable step 7\n");
565 /* 8. load Mode Register by set and clear PROG_DRAM */
566 msr = rdmsr(MC_CF07_DATA);
567 msr.lo |= 0x01;
568 wrmsr(MC_CF07_DATA, msr);
569 msr.lo &= ~0x01;
570 wrmsr(MC_CF07_DATA, msr);
571 printk(BIOS_DEBUG, "sdram_enable step 8\n");
573 /* wait 200 SDCLKs */
574 for (i = 0; i < 200; i++)
575 outb(0xaa, 0x80);
577 /* load RDSYNC */
578 msr = rdmsr(MC_CF_RDSYNC);
579 msr.hi = 0x000ff310;
580 /* the above setting is supposed to be good for "slow" ram. We have found that for
581 * some dram, at some clock rates, e.g. hynix at 366/244, this will actually
582 * cause errors. The fix is to just set it to 0x310. Tested on 3 boards
583 * with 3 different type of dram -- Hynix, PSC, infineon.
584 * I am leaving this comment here so that at some future time nobody is tempted
585 * to mess with this setting -- RGM, 9/2006
587 msr.hi = 0x00000310;
588 msr.lo = 0x00000000;
589 wrmsr(MC_CF_RDSYNC, msr);
591 /* set delay control */
592 msr = rdmsr(GLCP_DELAY_CONTROLS);
593 msr.hi = 0x830d415a;
594 msr.lo = 0x8ea0ad6a;
595 wrmsr(GLCP_DELAY_CONTROLS, msr);
597 /* The RAM dll needs a write to lock on so generate a few dummy writes */
598 /* Note: The descriptor needs to be enabled to point at memory */
599 volatile unsigned long *ptr;
600 for (i = 0; i < 5; i++) {
601 ptr = (void *)i;
602 *ptr = (unsigned long)i;
605 printk(BIOS_INFO, "RAM DLL lock\n");