Drop \r\n and \n\r as both print_XXX and printk now do this internally.
[coreboot.git] / src / cpu / amd / model_lx / cpureginit.c
1 /*
2  * This file is part of the coreboot project.
3  *
4  * Copyright (C) 2006 Indrek Kruusa <indrek.kruusa@artecdesign.ee>
5  * Copyright (C) 2006 Ronald G. Minnich <rminnich@gmail.com>
6  * Copyright (C) 2007 Advanced Micro Devices, Inc.
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
21  */
22
23 /**************************************************************************
24 ;*
25 ;*      SetDelayControl
26 ;*
27 ;*************************************************************************/
28 void SetDelayControl(void)
29 {
30         unsigned int msrnum, glspeed;
31         unsigned char spdbyte0, spdbyte1;
32         msr_t msr;
33
34         glspeed = GeodeLinkSpeed();
35
36         /* fix delay controls for DM and IM arrays */
37         msrnum = CPU_BC_MSS_ARRAY_CTL0;
38         msr.hi = 0;
39         msr.lo = 0x2814D352;
40         wrmsr(msrnum, msr);
41
42         msrnum = CPU_BC_MSS_ARRAY_CTL1;
43         msr.hi = 0;
44         msr.lo = 0x1068334D;
45         wrmsr(msrnum, msr);
46
47         msrnum = CPU_BC_MSS_ARRAY_CTL2;
48         msr.hi = 0x00000106;
49         msr.lo = 0x83104104;
50         wrmsr(msrnum, msr);
51
52         msrnum = GLCP_FIFOCTL;
53         msr = rdmsr(msrnum);
54         msr.hi = 0x00000005;
55         wrmsr(msrnum, msr);
56
57         /* Enable setting */
58         msrnum = CPU_BC_MSS_ARRAY_CTL_ENA;
59         msr.hi = 0;
60         msr.lo = 0x00000001;
61         wrmsr(msrnum, msr);
62
63         /* Debug Delay Control Setup Check
64            Leave it alone if it has been setup. FS2 or something is here. */
65         msrnum = GLCP_DELAY_CONTROLS;
66         msr = rdmsr(msrnum);
67         if (msr.lo & ~(0x7C0)) {
68                 return;
69         }
70
71         /*
72          * Delay Controls based on DIMM loading. UGH!
73          * # of Devices = Module Width (SPD6) / Device Width(SPD13) * Physical Banks(SPD5)
74          * Note - We only support module width of 64.
75          */
76         spdbyte0 = spd_read_byte(DIMM0, SPD_PRIMARY_SDRAM_WIDTH);
77         if (spdbyte0 != 0xFF) {
78                 spdbyte0 = (unsigned char)64 / spdbyte0 *
79                     (unsigned char)(spd_read_byte(DIMM0, SPD_NUM_DIMM_BANKS));
80         } else {
81                 spdbyte0 = 0;
82         }
83
84         spdbyte1 = spd_read_byte(DIMM1, SPD_PRIMARY_SDRAM_WIDTH);
85         if (spdbyte1 != 0xFF) {
86                 spdbyte1 = (unsigned char)64 / spdbyte1 *
87                     (unsigned char)(spd_read_byte(DIMM1, SPD_NUM_DIMM_BANKS));
88         } else {
89                 spdbyte1 = 0;
90         }
91
92 /* The current thinking. Subject to change...
93
94 ;                                                                  "FUTURE ROBUSTNESS" PROPOSAL
95 ;                                                                  ----------------------------
96 ;               DIMM     Max MBUS                                          MC 0x2000001A bits 26:24
97 ;DIMMs  devices  Frequency       MCP 0x4C00000F Setting          vvv
98 ;-----  -------  ---------       ----------------------  ----------
99 ;1               4               400MHz          0x82*100FF 0x56960004            4
100 ;1               8               400MHz          0x82*100AA 0x56960004            4
101 ;1               16              400MHz          0x82*10055 0x56960004            4
102 ;
103 ;2               4,4     400MHz          0x82710000 0x56960004            4
104 ;
105 ;1               4               <=333MHz        0x83*100FF 0x56960004            3
106 ;1               8               <=333MHz        0x83*100AA 0x56960004            3
107 ;1               16              <=333MHz        0x83*100AA 0x56960004            3
108 ;
109 ;2               4,4     <=333MHz        0x837100A5 0x56960004            3
110 ;2               8,8     <=333MHz        0x937100A5 0x56960004            3
111 ;
112 ;=========================================================================
113 ;* - Bit 55 (disable SDCLK 1,3,5) should be set if there is a single DIMM in slot 0,
114 ;        but it should be clear for all 2 DIMM settings and if a single DIMM is in slot 1.
115 ;        Bits 54:52 should always be set to '111'.
116
117 ;No VTT termination
118 ;-------------------------------------
119 ;ADDR/CTL have 22 ohm series R
120 ;DQ/DQM/DQS have 33 ohm series R
121 ;
122 ;               DIMM     Max MBUS
123 ;DIMMs  devices  Frequency       MCP 0x4C00000F Setting
124 ;-----  -------  ---------       ----------------------
125 ;1               4               400MHz          0xF2F100FF 0x56960004            4                     The No VTT changes improve timing.
126 ;1               8               400MHz          0xF2F100FF 0x56960004            4
127 ;1               4               <=333MHz        0xF2F100FF 0x56960004            3
128 ;1               8               <=333MHz        0xF2F100FF 0x56960004            3
129 ;1               16              <=333MHz        0xF2F100FF 0x56960004            3
130 */
131         msr.hi = msr.lo = 0;
132
133         if (spdbyte0 == 0 || spdbyte1 == 0) {
134                 /* one dimm solution */
135                 if (spdbyte1 == 0) {
136                         msr.hi |= 0x000800000;
137                 }
138                 spdbyte0 += spdbyte1;
139                 if (spdbyte0 > 8) {
140                         /* large dimm */
141                         if (glspeed < 334) {
142                                 msr.hi |= 0x0837100AA;
143                                 msr.lo |= 0x056960004;
144                         } else {
145                                 msr.hi |= 0x082710055;
146                                 msr.lo |= 0x056960004;
147                         }
148                 } else if (spdbyte0 > 4) {
149                         /* medium dimm */
150                         if (glspeed < 334) {
151                                 msr.hi |= 0x0837100AA;
152                                 msr.lo |= 0x056960004;
153                         } else {
154                                 msr.hi |= 0x0827100AA;
155                                 msr.lo |= 0x056960004;
156                         }
157                 } else {
158                         /* small dimm */
159                         if (glspeed < 334) {
160                                 msr.hi |= 0x0837100FF;
161                                 msr.lo |= 0x056960004;
162                         } else {
163                                 msr.hi |= 0x0827100FF;
164                                 msr.lo |= 0x056960004;
165                         }
166                 }
167         } else {
168                 /* two dimm solution */
169                 spdbyte0 += spdbyte1;
170                 if (spdbyte0 > 24) {
171                         /* huge dimms */
172                         if (glspeed < 334) {
173                                 msr.hi |= 0x0B37100A5;
174                                 msr.lo |= 0x056960004;
175                         } else {
176                                 msr.hi |= 0x0B2710000;
177                                 msr.lo |= 0x056960004;
178                         }
179                 } else if (spdbyte0 > 16) {
180                         /* large dimms */
181                         if (glspeed < 334) {
182                                 msr.hi |= 0x0B37100A5;
183                                 msr.lo |= 0x056960004;
184                         } else {
185                                 msr.hi |= 0x0B27100A5;
186                                 msr.lo |= 0x056960004;
187                         }
188                 } else if (spdbyte0 >= 8) {
189                         /* medium dimms */
190                         if (glspeed < 334) {
191                                 msr.hi |= 0x0937100A5;
192                                 msr.lo |= 0x056960004;
193                         } else {
194                                 msr.hi |= 0x0C27100A5;
195                                 msr.lo |= 0x056960004;
196                         }
197                 } else {
198                         /* small dimms */
199                         if (glspeed < 334) {
200                                 msr.hi |= 0x0837100A5;
201                                 msr.lo |= 0x056960004;
202                         } else {
203                                 msr.hi |= 0x082710000;
204                                 msr.lo |= 0x056960004;
205                         }
206                 }
207         }
208         print_debug("Try to write GLCP_DELAY_CONTROLS: hi ");
209         print_debug_hex32(msr.hi);
210         print_debug(" and lo ");
211         print_debug_hex32(msr.lo);
212         print_debug("\n");
213         wrmsr(GLCP_DELAY_CONTROLS, msr);
214         print_debug("SetDelayControl done\n");
215         return;
216 }
217
218 /* ***************************************************************************/
219 /* *    cpuRegInit*/
220 /* ***************************************************************************/
221 void cpuRegInit(void)
222 {
223         int msrnum;
224         msr_t msr;
225
226         /* Castle 2.0 BTM periodic sync period. */
227         /*      [40:37] 1 sync record per 256 bytes */
228         print_debug("Castle 2.0 BTM periodic sync period.\n");
229         msrnum = CPU_PF_CONF;
230         msr = rdmsr(msrnum);
231         msr.hi |= (0x8 << 5);
232         wrmsr(msrnum, msr);
233
234         /*
235          * LX performance setting.
236          * Enable Quack for fewer re-RAS on the MC
237          */
238         print_debug("Enable Quack for fewer re-RAS on the MC\n");
239         msrnum = GLIU0_ARB;
240         msr = rdmsr(msrnum);
241         msr.hi &= ~ARB_UPPER_DACK_EN_SET;
242         msr.hi |= ARB_UPPER_QUACK_EN_SET;
243         wrmsr(msrnum, msr);
244
245         msrnum = GLIU1_ARB;
246         msr = rdmsr(msrnum);
247         msr.hi &= ~ARB_UPPER_DACK_EN_SET;
248         msr.hi |= ARB_UPPER_QUACK_EN_SET;
249         wrmsr(msrnum, msr);
250
251         /* GLIU port active enable, limit south pole masters 
252          * (AES and PCI) to one outstanding transaction. 
253          */
254         print_debug(" GLIU port active enable\n");
255         msrnum = GLIU1_PORT_ACTIVE;
256         msr = rdmsr(msrnum);
257         msr.lo &= ~0x880;
258         wrmsr(msrnum, msr);
259
260         /* Set the Delay Control in GLCP */
261         print_debug("Set the Delay Control in GLCP\n");
262         SetDelayControl();
263
264         /*  Enable RSDC */
265         print_debug("Enable RSDC\n");
266         msrnum = CPU_AC_SMM_CTL;
267         msr = rdmsr(msrnum);
268         msr.lo |= SMM_INST_EN_SET;
269         wrmsr(msrnum, msr);
270
271         /* FPU imprecise exceptions bit */
272         print_debug("FPU imprecise exceptions bit\n");
273         msrnum = CPU_FPU_MSR_MODE;
274         msr = rdmsr(msrnum);
275         msr.lo |= FPU_IE_SET;
276         wrmsr(msrnum, msr);
277
278         /* Power Savers (Do after BIST) */
279         /* Enable Suspend on HLT & PAUSE instructions */
280         print_debug("Enable Suspend on HLT & PAUSE instructions\n");
281         msrnum = CPU_XC_CONFIG;
282         msr = rdmsr(msrnum);
283         msr.lo |= XC_CONFIG_SUSP_ON_HLT | XC_CONFIG_SUSP_ON_PAUSE;
284         wrmsr(msrnum, msr);
285
286         /* Enable SUSP and allow TSC to run in Suspend (keep speed detection happy) */
287         print_debug("Enable SUSP and allow TSC to run in Suspend\n");
288         msrnum = CPU_BC_CONF_0;
289         msr = rdmsr(msrnum);
290         msr.lo |= TSC_SUSP_SET | SUSP_EN_SET;
291         msr.lo &= 0x0F0FFFFFF;
292         msr.lo |= 0x002000000;  /* PBZ213: Set PAUSEDLY = 2 */
293         wrmsr(msrnum, msr);
294
295         /* Disable the debug clock to save power. */
296         /* NOTE: leave it enabled for fs2 debug */
297 #if 0
298         msrnum = GLCP_DBGCLKCTL;
299         msr.hi = 0;
300         msr.lo = 0;
301         wrmsr(msrnum, msr);
302 #endif
303
304         /* Setup throttling delays to proper mode if it is ever enabled. */
305         print_debug("Setup throttling delays to proper mode\n");
306         msrnum = GLCP_TH_OD;
307         msr.hi = 0;
308         msr.lo = 0x00000603C;
309         wrmsr(msrnum, msr);
310         print_debug("Done cpuRegInit\n");
311 }