Add constants for fast path resume copying
[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 hcf(void)
30 {
31         printk(BIOS_EMERG, "DIE\n");
32         /* this guarantees we flush the UART fifos (if any) and also
33          * ensures that things, in general, keep going so no debug output
34          * is lost
35          */
36         while (1)
37                 printk(BIOS_EMERG, (0));
38 }
39
40 static void auto_size_dimm(unsigned int dimm)
41 {
42         uint32_t dimm_setting;
43         uint16_t dimm_size;
44         uint8_t spd_byte;
45         msr_t msr;
46
47         dimm_setting = 0;
48
49         printk(BIOS_DEBUG, "Check present\n");
50         /* Check that we have a dimm */
51         if (spd_read_byte(dimm, SPD_MEMORY_TYPE) == 0xFF) {
52                 return;
53         }
54
55         printk(BIOS_DEBUG, "MODBANKS\n");
56         /* Field: Module Banks per DIMM */
57         /* EEPROM byte usage: (5) Number of DIMM Banks */
58         spd_byte = spd_read_byte(dimm, SPD_NUM_DIMM_BANKS);
59         if ((MIN_MOD_BANKS > spd_byte) || (spd_byte > MAX_MOD_BANKS)) {
60                 printk(BIOS_EMERG, "Number of module banks not compatible\n");
61                 post_code(ERROR_BANK_SET);
62                 hcf();
63         }
64         dimm_setting |= (spd_byte >> 1) << CF07_UPPER_D0_MB_SHIFT;
65
66         printk(BIOS_DEBUG, "FIELDBANKS\n");
67         /* Field: Banks per SDRAM device */
68         /* EEPROM byte usage: (17) Number of Banks on SDRAM Device */
69         spd_byte = spd_read_byte(dimm, SPD_NUM_BANKS_PER_SDRAM);
70         if ((MIN_DEV_BANKS > spd_byte) || (spd_byte > MAX_DEV_BANKS)) {
71                 printk(BIOS_EMERG, "Number of device banks not compatible\n");
72                 post_code(ERROR_BANK_SET);
73                 hcf();
74         }
75         dimm_setting |= (spd_byte >> 2) << CF07_UPPER_D0_CB_SHIFT;
76
77         printk(BIOS_DEBUG, "SPDNUMROWS\n");
78         /* Field: DIMM size
79          * EEPROM byte usage:
80          *   (3)  Number of Row Addresses
81          *   (4)  Number of Column Addresses
82          *   (5)  Number of DIMM Banks
83          *   (31) Module Bank Density
84          * Size = Module Density * Module Banks
85          */
86         if ((spd_read_byte(dimm, SPD_NUM_ROWS) & 0xF0)
87             || (spd_read_byte(dimm, SPD_NUM_COLUMNS) & 0xF0)) {
88                 printk(BIOS_EMERG, "Asymmetric DIMM not compatible\n");
89                 post_code(ERROR_UNSUPPORTED_DIMM);
90                 hcf();
91         }
92
93         printk(BIOS_DEBUG, "SPDBANKDENSITY\n");
94         dimm_size = spd_read_byte(dimm, SPD_BANK_DENSITY);
95         printk(BIOS_DEBUG, "DIMMSIZE\n");
96         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 */
97         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 */
98
99         /* Module Density * Module Banks */
100         dimm_size <<= (dimm_setting >> CF07_UPPER_D0_MB_SHIFT) & 1;     /* shift to multiply by # DIMM banks */
101         printk(BIOS_DEBUG, "BEFORT CTZ\n");
102         dimm_size = __builtin_ctz(dimm_size);
103         printk(BIOS_DEBUG, "TEST DIMM SIZE>7\n");
104         if (dimm_size > 7) {    /* 7 is 512MB only support 512MB per DIMM */
105                 printk(BIOS_EMERG, "Only support up to 512MB per DIMM\n");
106                 post_code(ERROR_DENSITY_DIMM);
107                 hcf();
108         }
109         dimm_setting |= dimm_size << CF07_UPPER_D0_SZ_SHIFT;
110         printk(BIOS_DEBUG, "PAGESIZE\n");
111
112 /*
113  * Field: PAGE size
114  * EEPROM byte usage: (4)  Number of Column Addresses
115  * PageSize = 2^# Column Addresses * Data width in bytes
116  *                                   (should be 8bytes for a normal DIMM)
117  *
118  * But this really works by magic.
119  * If ma[11:0] is the memory address pins, and pa[13:0] is the physical column
120  * address that MC generates, here is how the MC assigns the pa onto the
121  * ma pins:
122  *
123  * ma  11 10 09 08 07 06 05 04 03 02 01 00
124  * ---------------------------------------
125  * pa                 09 08 07 06 05 04 03  (7 col addr bits = 1K page size)
126  * pa              10 09 08 07 06 05 04 03  (8 col addr bits = 2K page size)
127  * pa           11 10 09 08 07 06 05 04 03  (9 col addr bits = 4K page size)
128  * pa        12 11 10 09 08 07 06 05 04 03  (10 col addr bits = 8K page size)
129  * pa  13 AP 12 11 10 09 08 07 06 05 04 03  (11 col addr bits = 16K page size)
130  *
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,
136  * #col_addr_bits=7(06h), it adds 3 to get 10, then does 2^10=1K.
137  */
138
139         spd_byte = NumColAddr[spd_read_byte(dimm, SPD_NUM_COLUMNS) & 0xF];
140         printk(BIOS_DEBUG, "MAXCOLADDR\n");
141         if (spd_byte > MAX_COL_ADDR) {
142                 printk(BIOS_EMERG, "DIMM page size not compatible\n");
143                 post_code(ERROR_SET_PAGE);
144                 hcf();
145         }
146         printk(BIOS_DEBUG, ">11address test\n");
147         spd_byte -= 7;
148         if (spd_byte > 4) {     /* if the value is above 4 it means >11 col address lines */
149                 spd_byte = 7;   /* which means >16k so set to disabled */
150         }
151         dimm_setting |= spd_byte << CF07_UPPER_D0_PSZ_SHIFT;    /* 0=1k,1=2k,2=4k,etc */
152
153         printk(BIOS_DEBUG, "RDMSR CF07\n");
154         msr = rdmsr(MC_CF07_DATA);
155         printk(BIOS_DEBUG, "WRMSR CF07\n");
156         if (dimm == DIMM0) {
157                 msr.hi &= 0xFFFF0000;
158                 msr.hi |= dimm_setting;
159         } else {
160                 msr.hi &= 0x0000FFFF;
161                 msr.hi |= dimm_setting << 16;
162         }
163         wrmsr(MC_CF07_DATA, msr);
164         printk(BIOS_DEBUG, "ALL DONE\n");
165 }
166
167 static void checkDDRMax(void)
168 {
169         uint8_t spd_byte0, spd_byte1;
170         uint16_t speed;
171
172         /* PC133 identifier */
173         spd_byte0 = spd_read_byte(DIMM0, SPD_MIN_CYCLE_TIME_AT_CAS_MAX);
174         if (spd_byte0 == 0xFF) {
175                 spd_byte0 = 0;
176         }
177         spd_byte1 = spd_read_byte(DIMM1, SPD_MIN_CYCLE_TIME_AT_CAS_MAX);
178         if (spd_byte1 == 0xFF) {
179                 spd_byte1 = 0;
180         }
181
182         /* Use the slowest DIMM */
183         if (spd_byte0 < spd_byte1) {
184                 spd_byte0 = spd_byte1;
185         }
186
187         /* Turn SPD ns time into MHZ. Check what the asm does to this math. */
188         speed = 20000 / (((spd_byte0 >> 4) * 10) + (spd_byte0 & 0x0F));
189
190         /* current speed > max speed? */
191         if (GeodeLinkSpeed() > speed) {
192                 printk(BIOS_EMERG, "DIMM overclocked. Check GeodeLink Speed\n");
193                 post_code(POST_PLL_MEM_FAIL);
194                 hcf();
195         }
196 }
197
198 const uint16_t REF_RATE[] = { 15, 3, 7, 31, 62, 125 };  /* ns */
199
200 static void set_refresh_rate(void)
201 {
202         uint8_t spd_byte0, spd_byte1;
203         uint16_t rate0, rate1;
204         msr_t msr;
205
206         spd_byte0 = spd_read_byte(DIMM0, SPD_REFRESH);
207         spd_byte0 &= 0xF;
208         if (spd_byte0 > 5) {
209                 spd_byte0 = 5;
210         }
211         rate0 = REF_RATE[spd_byte0];
212
213         spd_byte1 = spd_read_byte(DIMM1, SPD_REFRESH);
214         spd_byte1 &= 0xF;
215         if (spd_byte1 > 5) {
216                 spd_byte1 = 5;
217         }
218         rate1 = REF_RATE[spd_byte1];
219
220         /* Use the faster rate (lowest number) */
221         if (rate0 > rate1) {
222                 rate0 = rate1;
223         }
224
225         msr = rdmsr(MC_CF07_DATA);
226         msr.lo |= ((rate0 * (GeodeLinkSpeed() / 2)) / 16)
227                         << CF07_LOWER_REF_INT_SHIFT;
228         wrmsr(MC_CF07_DATA, msr);
229 }
230
231 const uint8_t CASDDR[] = { 5, 5, 2, 6, 0 };     /* 1(1.5), 1.5, 2, 2.5, 0 */
232
233 static u8 getcasmap(u32 dimm, u16 glspeed)
234 {
235         u16 dimm_speed;
236         u8 spd_byte, casmap, casmap_shift=0;
237
238         /**************************      DIMM0  **********************************/
239         casmap = spd_read_byte(dimm, SPD_ACCEPTABLE_CAS_LATENCIES);
240         if (casmap != 0xFF) {
241                 /* IF -.5 timing is supported, check -.5 timing > GeodeLink */
242                 spd_byte = spd_read_byte(dimm, SPD_SDRAM_CYCLE_TIME_2ND);
243                 if (spd_byte != 0) {
244                         /* Turn SPD ns time into MHZ. Check what the asm does to this math. */
245                         dimm_speed = 20000 / (((spd_byte >> 4) * 10) + (spd_byte & 0x0F));
246                         if (dimm_speed >= glspeed) {
247                                 casmap_shift = 1; /* -.5 is a shift of 1 */
248                                 /* IF -1 timing is supported, check -1 timing > GeodeLink */
249                                 spd_byte = spd_read_byte(dimm, SPD_SDRAM_CYCLE_TIME_3RD);
250                                 if (spd_byte != 0) {
251                                         /* Turn SPD ns time into MHZ. Check what the asm does to this math. */
252                                         dimm_speed = 20000 / (((spd_byte >> 4) * 10) + (spd_byte & 0x0F));
253                                         if (dimm_speed >= glspeed) {
254                                                 casmap_shift = 2; /* -1 is a shift of 2 */
255                                         }
256                                 }       /* SPD_SDRAM_CYCLE_TIME_3RD (-1) !=0 */
257                         } else {
258                                 casmap_shift = 0;
259                         }
260                 }       /* SPD_SDRAM_CYCLE_TIME_2ND (-.5) !=0 */
261                 /* set the casmap based on the shift to limit possible CAS settings */
262                 spd_byte = 31 - __builtin_clz((uint32_t) casmap);
263                 /* just want bits in the lower byte since we have to cast to a 32 */
264                 casmap &= 0xFF << (spd_byte - casmap_shift);
265         } else {                /* No DIMM */
266                 casmap = 0;
267         }
268         return casmap;
269 }
270
271 static void setCAS(void)
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                 printk(BIOS_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
460 static void sdram_set_spd_registers(const struct mem_controller *ctrl)
461 {
462         uint8_t spd_byte;
463
464         printk(BIOS_DEBUG, "sdram_set_spd_register\n");
465         post_code(POST_MEM_SETUP);      /* post_70h */
466
467         spd_byte = spd_read_byte(DIMM0, SPD_MODULE_ATTRIBUTES);
468         printk(BIOS_DEBUG, "Check DIMM 0\n");
469         /* Check DIMM is not Register and not Buffered DIMMs. */
470         if ((spd_byte != 0xFF) && (spd_byte & 3)) {
471                 printk(BIOS_EMERG, "DIMM0 NOT COMPATIBLE\n");
472                 post_code(ERROR_UNSUPPORTED_DIMM);
473                 hcf();
474         }
475         printk(BIOS_DEBUG, "Check DIMM 1\n");
476         spd_byte = spd_read_byte(DIMM1, SPD_MODULE_ATTRIBUTES);
477         if ((spd_byte != 0xFF) && (spd_byte & 3)) {
478                 printk(BIOS_EMERG, "DIMM1 NOT COMPATIBLE\n");
479                 post_code(ERROR_UNSUPPORTED_DIMM);
480                 hcf();
481         }
482
483         post_code(POST_MEM_SETUP2);     /* post_72h */
484         printk(BIOS_DEBUG, "Check DDR MAX\n");
485
486         /* Check that the memory is not overclocked. */
487         checkDDRMax();
488
489         /* Size the DIMMS */
490         post_code(POST_MEM_SETUP3);     /* post_73h */
491         printk(BIOS_DEBUG, "AUTOSIZE DIMM 0\n");
492         auto_size_dimm(DIMM0);
493         post_code(POST_MEM_SETUP4);     /* post_74h */
494         printk(BIOS_DEBUG, "AUTOSIZE DIMM 1\n");
495         auto_size_dimm(DIMM1);
496
497         /* Set CAS latency */
498         printk(BIOS_DEBUG, "set cas latency\n");
499         post_code(POST_MEM_SETUP5);     /* post_75h */
500         setCAS();
501
502         /* Set all the other latencies here (tRAS, tRP....) */
503         printk(BIOS_DEBUG, "set all latency\n");
504         set_latencies();
505
506         /* Set Extended Mode Registers */
507         printk(BIOS_DEBUG, "set emrs\n");
508         set_extended_mode_registers();
509
510         printk(BIOS_DEBUG, "set ref rate\n");
511         /* Set Memory Refresh Rate */
512         set_refresh_rate();
513 }
514
515 /* Section 6.1.3, LX processor databooks, BIOS Initialization Sequence
516  * Section 4.1.4, GX/CS5535 GeodeROM Porting guide */
517 static void sdram_enable(int controllers, const struct mem_controller *ctrl)
518 {
519         int i;
520         msr_t msr;
521
522         /* 2. clock gating for PMode */
523         msr = rdmsr(MC_GLD_MSR_PM);
524         msr.lo &= ~0x04;
525         msr.lo |=  0x01;
526         wrmsr(MC_GLD_MSR_PM, msr);
527         /* undocmented bits in GX, in LX there are
528          * 8 bits in PM1_UP_DLY */
529         msr = rdmsr(MC_CF1017_DATA);
530         msr.lo = 0x0101;
531         wrmsr(MC_CF1017_DATA, msr);
532         printk(BIOS_DEBUG, "sdram_enable step 2\n");
533
534         /* 3. release CKE mask to enable CKE */
535         msr = rdmsr(MC_CFCLK_DBUG);
536         msr.lo &= ~(0x03 << 8);
537         wrmsr(MC_CFCLK_DBUG, msr);
538         printk(BIOS_DEBUG, "sdram_enable step 3\n");
539
540         /* 4. set and clear REF_TST 16 times, more shouldn't hurt
541          * why this is before EMRS and MRS ? */
542         for (i = 0; i < 19; i++) {
543                 msr = rdmsr(MC_CF07_DATA);
544                 msr.lo |=  (0x01 << 3);
545                 wrmsr(MC_CF07_DATA, msr);
546                 msr.lo &= ~(0x01 << 3);
547                 wrmsr(MC_CF07_DATA, msr);
548         }
549         printk(BIOS_DEBUG, "sdram_enable step 4\n");
550
551         /* 6. enable DLL, load Extended Mode Register by set and clear PROG_DRAM */
552         msr = rdmsr(MC_CF07_DATA);
553         msr.lo |=  ((0x01 << 28) | 0x01);
554         wrmsr(MC_CF07_DATA, msr);
555         msr.lo &= ~((0x01 << 28) | 0x01);
556         wrmsr(MC_CF07_DATA, msr);
557         printk(BIOS_DEBUG, "sdram_enable step 6\n");
558
559         /* 7. Reset DLL, Bit 27 is undocumented in GX datasheet,
560          * it is documented in LX datasheet */
561         /* load Mode Register by set and clear PROG_DRAM */
562         msr = rdmsr(MC_CF07_DATA);
563         msr.lo |=  ((0x01 << 27) | 0x01);
564         wrmsr(MC_CF07_DATA, msr);
565         msr.lo &= ~((0x01 << 27) | 0x01);
566         wrmsr(MC_CF07_DATA, msr);
567         printk(BIOS_DEBUG, "sdram_enable step 7\n");
568
569         /* 8. load Mode Register by set and clear PROG_DRAM */
570         msr = rdmsr(MC_CF07_DATA);
571         msr.lo |=  0x01;
572         wrmsr(MC_CF07_DATA, msr);
573         msr.lo &= ~0x01;
574         wrmsr(MC_CF07_DATA, msr);
575         printk(BIOS_DEBUG, "sdram_enable step 8\n");
576
577         /* wait 200 SDCLKs */
578         for (i = 0; i < 200; i++)
579                 outb(0xaa, 0x80);
580
581         /* load RDSYNC */
582         msr = rdmsr(MC_CF_RDSYNC);
583         msr.hi = 0x000ff310;
584         /* the above setting is supposed to be good for "slow" ram. We have found that for
585          * some dram, at some clock rates, e.g. hynix at 366/244, this will actually
586          * cause errors. The fix is to just set it to 0x310. Tested on 3 boards
587          * with 3 different type of dram -- Hynix, PSC, infineon.
588          * I am leaving this comment here so that at some future time nobody is tempted
589          * to mess with this setting -- RGM, 9/2006
590          */
591         msr.hi = 0x00000310;
592         msr.lo = 0x00000000;
593         wrmsr(MC_CF_RDSYNC, msr);
594
595         /* set delay control */
596         msr = rdmsr(GLCP_DELAY_CONTROLS);
597         msr.hi = 0x830d415a;
598         msr.lo = 0x8ea0ad6a;
599         wrmsr(GLCP_DELAY_CONTROLS, msr);
600
601         /* The RAM dll needs a write to lock on so generate a few dummy writes */
602         /* Note: The descriptor needs to be enabled to point at memory */
603         volatile unsigned long *ptr;
604         for (i = 0; i < 5; i++) {
605                 ptr = (void *)i;
606                 *ptr = (unsigned long)i;
607         }
608
609         print_info("RAM DLL lock\n");
610
611 }