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