Root/
Source at commit 214 created 13 years 5 months ago. By ifabio, update to chameleon trunk 630, and now the pakage folder is the same as blackosx branch, also add Icon "building" into buildpkg script, and add mint theme info into the English localizable.strings. | |
---|---|
1 | /*␊ |
2 | * dram controller access and scan from the pci host controller␊ |
3 | * Integrated and adapted for chameleon 2.0 RC5 by Rekursor from bs0d work␊ |
4 | * original source comes from:␊ |
5 | *␊ |
6 | * memtest86␊ |
7 | *␊ |
8 | * Released under version 2 of the Gnu Public License.␊ |
9 | * By Chris Brady, cbrady@sgi.com␊ |
10 | * ----------------------------------------------------␊ |
11 | * MemTest86+ V4.00 Specific code (GPL V2.0)␊ |
12 | * By Samuel DEMEULEMEESTER, sdemeule@memtest.org␊ |
13 | * http://www.canardpc.com - http://www.memtest.org␊ |
14 | */␊ |
15 | ␊ |
16 | #include "libsaio.h"␊ |
17 | #include "bootstruct.h"␊ |
18 | #include "pci.h"␊ |
19 | #include "platform.h"␊ |
20 | #include "dram_controllers.h"␊ |
21 | ␊ |
22 | #ifndef DEBUG_DRAM␊ |
23 | #define DEBUG_DRAM 0␊ |
24 | #endif␊ |
25 | ␊ |
26 | #if DEBUG_DRAM␊ |
27 | #define DBG(x...) printf(x)␊ |
28 | #else␊ |
29 | #define DBG(x...)␊ |
30 | #endif␊ |
31 | ␊ |
32 | /*␊ |
33 | * Initialise memory controller functions␊ |
34 | */␊ |
35 | ␊ |
36 | // Setup P35 Memory Controller␊ |
37 | static void setup_p35(pci_dt_t *dram_dev)␊ |
38 | {␊ |
39 | ␉uint32_t dev0;␊ |
40 | ␉␊ |
41 | ␉// Activate MMR I/O␊ |
42 | ␉dev0 = pci_config_read32(dram_dev->dev.addr, 0x48);␊ |
43 | ␉if (!(dev0 & 0x1))␊ |
44 | ␉␉pci_config_write8(dram_dev->dev.addr, 0x48, (dev0 | 1));␊ |
45 | }␊ |
46 | ␊ |
47 | int nhm_bus = 0x3F;␊ |
48 | ␊ |
49 | // Setup Nehalem Integrated Memory Controller␊ |
50 | static void setup_nhm(pci_dt_t *dram_dev)␊ |
51 | {␊ |
52 | ␉static long possible_nhm_bus[] = {0xFF, 0x7F, 0x3F};␊ |
53 | ␉unsigned long did, vid;␊ |
54 | ␉int i;␊ |
55 | ␉␊ |
56 | ␉// Nehalem supports Scrubbing␊ |
57 | ␉// First, locate the PCI bus where the MCH is located␊ |
58 | ␉for(i = 0; i < sizeof(possible_nhm_bus); i++)␊ |
59 | ␉{␊ |
60 | ␉␉vid = pci_config_read16(PCIADDR(possible_nhm_bus[i], 3, 4), 0x00);␊ |
61 | ␉␉did = pci_config_read16(PCIADDR(possible_nhm_bus[i], 3, 4), 0x02);␊ |
62 | ␉␉vid &= 0xFFFF;␊ |
63 | ␉␉did &= 0xFF00;␊ |
64 | ␉␉␊ |
65 | ␉␉if(vid == 0x8086 && did >= 0x2C00)␊ |
66 | ␉␉␉nhm_bus = possible_nhm_bus[i]; ␊ |
67 | ␉}␊ |
68 | }␊ |
69 | ␊ |
70 | /*␊ |
71 | * Retrieve memory controller fsb functions␊ |
72 | */␊ |
73 | ␊ |
74 | ␊ |
75 | // Get i965 Memory Speed␊ |
76 | static void get_fsb_i965(pci_dt_t *dram_dev)␊ |
77 | {␊ |
78 | ␉uint32_t dev0, mch_ratio, mch_cfg, mch_fsb;␊ |
79 | ␊ |
80 | ␉long *ptr;␊ |
81 | ␉␊ |
82 | ␉// Find Ratio␊ |
83 | ␉dev0 = pci_config_read32(dram_dev->dev.addr, 0x48);␊ |
84 | ␉dev0 &= 0xFFFFC000;␊ |
85 | ␉ptr = (long*)(dev0 + 0xC00);␊ |
86 | ␉mch_cfg = *ptr & 0xFFFF;␊ |
87 | ␉␊ |
88 | ␉mch_ratio = 100000;␊ |
89 | ␉␊ |
90 | ␉switch (mch_cfg & 7)␊ |
91 | ␉{␊ |
92 | ␉␉case 0: mch_fsb = 1066; break;␊ |
93 | ␉␉case 1: mch_fsb = 533; break;␊ |
94 | ␉ default: ␊ |
95 | ␉␉case 2: mch_fsb = 800; break;␊ |
96 | ␉␉case 3: mch_fsb = 667; break;␉␉␊ |
97 | ␉␉case 4: mch_fsb = 1333; break;␊ |
98 | ␉␉case 6: mch_fsb = 1600; break;␉␉␉␉␉␊ |
99 | ␉}␊ |
100 | ␉␊ |
101 | ␉DBG("mch_fsb %d\n", mch_fsb);␊ |
102 | ␉␊ |
103 | ␉switch (mch_fsb)␊ |
104 | ␉{␊ |
105 | ␉␉case 533:␊ |
106 | ␉␉␉switch ((mch_cfg >> 4) & 7)␊ |
107 | ␉␉{␊ |
108 | ␉␉␉case 1:␉mch_ratio = 200000; break;␊ |
109 | ␉␉␉case 2:␉mch_ratio = 250000; break;␊ |
110 | ␉␉␉case 3:␉mch_ratio = 300000; break;␊ |
111 | ␉␉}␊ |
112 | ␉␉␉break;␊ |
113 | ␉␉␉␊ |
114 | ␉␉default:␊ |
115 | ␉␉case 800:␊ |
116 | ␉␉␉switch ((mch_cfg >> 4) & 7)␊ |
117 | ␉␉{␊ |
118 | ␉␉␉case 0:␉mch_ratio = 100000; break;␊ |
119 | ␉␉␉case 1:␉mch_ratio = 125000; break;␊ |
120 | ␉␉␉case 2:␉mch_ratio = 166667; break; // 1.666666667␊ |
121 | ␉␉␉case 3:␉mch_ratio = 200000; break;␊ |
122 | ␉␉␉case 4:␉mch_ratio = 266667; break; // 2.666666667␊ |
123 | ␉␉␉case 5:␉mch_ratio = 333333; break; // 3.333333333␊ |
124 | ␉␉}␊ |
125 | ␉␉␉break;␊ |
126 | ␉␉␉␊ |
127 | ␉␉case 1066:␊ |
128 | ␉␉␉switch ((mch_cfg >> 4) & 7)␊ |
129 | ␉␉{␊ |
130 | ␉␉␉case 1:␉mch_ratio = 100000; break;␊ |
131 | ␉␉␉case 2:␉mch_ratio = 125000; break;␊ |
132 | ␉␉␉case 3:␉mch_ratio = 150000; break;␊ |
133 | ␉␉␉case 4:␉mch_ratio = 200000; break;␊ |
134 | ␉␉␉case 5:␉mch_ratio = 250000; break;␊ |
135 | ␉␉}␊ |
136 | ␉␉␉break;␊ |
137 | ␉␉␉␊ |
138 | ␉␉case 1333:␊ |
139 | ␉␉␉switch ((mch_cfg >> 4) & 7)␊ |
140 | ␉␉{␊ |
141 | ␉␉␉case 2:␉mch_ratio = 100000; break;␊ |
142 | ␉␉␉case 3:␉mch_ratio = 120000; break;␊ |
143 | ␉␉␉case 4:␉mch_ratio = 160000; break;␊ |
144 | ␉␉␉case 5:␉mch_ratio = 200000; break;␊ |
145 | ␉␉}␊ |
146 | ␉␉␉break;␊ |
147 | ␉␉␉␊ |
148 | ␉␉case 1600:␊ |
149 | ␉␉␉switch ((mch_cfg >> 4) & 7)␊ |
150 | ␉␉{␊ |
151 | ␉␉␉case 3:␉mch_ratio = 100000; break;␊ |
152 | ␉␉␉case 4:␉mch_ratio = 133333; break; // 1.333333333␊ |
153 | ␉␉␉case 5:␉mch_ratio = 150000; break;␊ |
154 | ␉␉␉case 6:␉mch_ratio = 200000; break;␊ |
155 | ␉␉}␊ |
156 | ␉␉␉break;␊ |
157 | ␉}␊ |
158 | ␉␊ |
159 | ␉DBG("mch_ratio %d\n", mch_ratio);␊ |
160 | ␊ |
161 | ␉// Compute RAM Frequency␊ |
162 | ␉Platform.RAM.Frequency = (Platform.CPU.FSBFrequency * mch_ratio) / 100000;␊ |
163 | ␉␊ |
164 | ␉DBG("ram_fsb %d\n", Platform.RAM.Frequency);␊ |
165 | ␊ |
166 | }␊ |
167 | ␊ |
168 | // Get i965m Memory Speed␊ |
169 | static void get_fsb_im965(pci_dt_t *dram_dev)␊ |
170 | {␊ |
171 | ␉uint32_t dev0, mch_ratio, mch_cfg, mch_fsb;␊ |
172 | ␊ |
173 | ␉long *ptr;␊ |
174 | ␉␊ |
175 | ␉// Find Ratio␊ |
176 | ␉dev0 = pci_config_read32(dram_dev->dev.addr, 0x48);␊ |
177 | ␉dev0 &= 0xFFFFC000;␊ |
178 | ␉ptr = (long*)(dev0 + 0xC00);␊ |
179 | ␉mch_cfg = *ptr & 0xFFFF;␊ |
180 | ␉␊ |
181 | ␉mch_ratio = 100000;␊ |
182 | ␉␊ |
183 | ␉switch (mch_cfg & 7)␊ |
184 | ␉{␊ |
185 | ␉␉case 1: mch_fsb = 533; break;␊ |
186 | ␉␉default: ␊ |
187 | ␉␉case 2:␉mch_fsb = 800; break;␊ |
188 | ␉␉case 3:␉mch_fsb = 667; break;␉␉␉␉␊ |
189 | ␉␉case 6:␉mch_fsb = 1066; break;␉␉␉␊ |
190 | ␉}␊ |
191 | ␉␊ |
192 | ␉switch (mch_fsb)␊ |
193 | ␉{␊ |
194 | ␉␉case 533:␊ |
195 | ␉␉␉switch ((mch_cfg >> 4) & 7)␊ |
196 | ␉␉␉{␊ |
197 | ␉␉␉␉case 1:␉mch_ratio = 125000; break;␊ |
198 | ␉␉␉␉case 2:␉mch_ratio = 150000; break;␊ |
199 | ␉␉␉␉case 3:␉mch_ratio = 200000; break;␊ |
200 | ␉␉␉}␊ |
201 | ␉␉␉break;␊ |
202 | ␉␉␉␊ |
203 | ␉␉case 667:␊ |
204 | ␉␉␉switch ((mch_cfg >> 4)& 7)␊ |
205 | ␉␉␉{␊ |
206 | ␉␉␉␉case 1:␉mch_ratio = 100000; break;␊ |
207 | ␉␉␉␉case 2:␉mch_ratio = 120000; break;␊ |
208 | ␉␉␉␉case 3:␉mch_ratio = 160000; break;␊ |
209 | ␉␉␉␉case 4:␉mch_ratio = 200000; break;␊ |
210 | ␉␉␉␉case 5:␉mch_ratio = 240000; break;␊ |
211 | ␉␉␉}␊ |
212 | ␉␉␉break;␊ |
213 | ␉␉␉␊ |
214 | ␉␉default:␊ |
215 | ␉␉case 800:␊ |
216 | ␉␉␉switch ((mch_cfg >> 4) & 7)␊ |
217 | ␉␉␉{␊ |
218 | ␉␉␉␉case 1:␉mch_ratio = 83333; break; // 0.833333333␊ |
219 | ␉␉␉␉case 2:␉mch_ratio = 100000; break;␊ |
220 | ␉␉␉␉case 3:␉mch_ratio = 133333; break; // 1.333333333␊ |
221 | ␉␉␉␉case 4:␉mch_ratio = 166667; break; // 1.666666667␊ |
222 | ␉␉␉␉case 5:␉mch_ratio = 200000; break;␊ |
223 | ␉␉␉}␊ |
224 | ␉␉␉break;␊ |
225 | ␉␉case 1066:␊ |
226 | ␉␉␉switch ((mch_cfg >> 4)&7) {␊ |
227 | ␉␉␉␉case 5:␉mch_ratio = 150000; break;␊ |
228 | ␉␉␉␉case 6:␉mch_ratio = 200000; break;␊ |
229 | ␉␉␉}␊ |
230 | ␉␉␉␊ |
231 | ␉}␊ |
232 | ␉␊ |
233 | ␉// Compute RAM Frequency␊ |
234 | ␉Platform.RAM.Frequency = (Platform.CPU.FSBFrequency * mch_ratio) / 100000;␊ |
235 | }␊ |
236 | ␊ |
237 | ␊ |
238 | // Get iCore7 Memory Speed␊ |
239 | static void get_fsb_nhm(pci_dt_t *dram_dev)␊ |
240 | {␊ |
241 | ␉uint32_t mch_ratio, mc_dimm_clk_ratio;␊ |
242 | ␉␊ |
243 | ␉// Get the clock ratio␊ |
244 | ␉mc_dimm_clk_ratio = pci_config_read16(PCIADDR(nhm_bus, 3, 4), 0x54 );␊ |
245 | ␉mch_ratio = (mc_dimm_clk_ratio & 0x1F);␊ |
246 | ␉␊ |
247 | ␉// Compute RAM Frequency␊ |
248 | ␉Platform.RAM.Frequency = Platform.CPU.FSBFrequency * mch_ratio / 2;␊ |
249 | }␊ |
250 | ␊ |
251 | /*␊ |
252 | * Retrieve memory controller info functions␊ |
253 | */␊ |
254 | ␊ |
255 | // Get i965 Memory Timings␊ |
256 | static void get_timings_i965(pci_dt_t *dram_dev)␊ |
257 | { ␊ |
258 | ␉// Thanks for CDH optis␊ |
259 | ␉uint32_t dev0, c0ckectrl, c1ckectrl, offset;␊ |
260 | ␉uint32_t ODT_Control_Register, Precharge_Register, ACT_Register, Read_Register, Misc_Register;␊ |
261 | ␊ |
262 | ␉long *ptr;␊ |
263 | ␉␊ |
264 | ␉// Read MMR Base Address␊ |
265 | ␉dev0 = pci_config_read32(dram_dev->dev.addr, 0x48);␊ |
266 | ␉dev0 &= 0xFFFFC000;␊ |
267 | ␉␊ |
268 | ␉ptr = (long*)(dev0 + 0x260);␊ |
269 | ␉c0ckectrl = *ptr & 0xFFFFFFFF;␉␊ |
270 | ␉␊ |
271 | ␉ptr = (long*)(dev0 + 0x660);␊ |
272 | ␉c1ckectrl = *ptr & 0xFFFFFFFF;␊ |
273 | ␉␊ |
274 | ␉// If DIMM 0 not populated, check DIMM 1␊ |
275 | ␉((c0ckectrl) >> 20 & 0xF) ? (offset = 0) : (offset = 0x400);␊ |
276 | ␉␊ |
277 | ␉ptr = (long*)(dev0 + offset + 0x29C);␊ |
278 | ␉ODT_Control_Register = *ptr & 0xFFFFFFFF;␊ |
279 | ␉␊ |
280 | ␉ptr = (long*)(dev0 + offset + 0x250);␉␊ |
281 | ␉Precharge_Register = *ptr & 0xFFFFFFFF;␊ |
282 | ␉␊ |
283 | ␉ptr = (long*)(dev0 + offset + 0x252);␊ |
284 | ␉ACT_Register = *ptr & 0xFFFFFFFF;␊ |
285 | ␉␊ |
286 | ␉ptr = (long*)(dev0 + offset + 0x258);␊ |
287 | ␉Read_Register = *ptr & 0xFFFFFFFF;␊ |
288 | ␉␊ |
289 | ␉ptr = (long*)(dev0 + offset + 0x244);␊ |
290 | ␉Misc_Register = *ptr & 0xFFFFFFFF;␊ |
291 | ␉␊ |
292 | ␉// 965 Series only support DDR2␊ |
293 | ␉Platform.RAM.Type = SMB_MEM_TYPE_DDR2;␊ |
294 | ␉␊ |
295 | ␉// CAS Latency (tCAS)␊ |
296 | ␉Platform.RAM.CAS = ((ODT_Control_Register >> 17) & 7) + 3;␊ |
297 | ␉␊ |
298 | ␉// RAS-To-CAS (tRCD)␊ |
299 | ␉Platform.RAM.TRC = (Read_Register >> 16) & 0xF;␊ |
300 | ␉␊ |
301 | ␉// RAS Precharge (tRP)␊ |
302 | ␉Platform.RAM.TRP = (ACT_Register >> 13) & 0xF;␊ |
303 | ␉␊ |
304 | ␉// RAS Active to precharge (tRAS)␊ |
305 | ␉Platform.RAM.RAS = (Precharge_Register >> 11) & 0x1F;␊ |
306 | ␉␊ |
307 | ␉if ((c0ckectrl >> 20 & 0xF) && (c1ckectrl >> 20 & 0xF))␊ |
308 | ␉␉Platform.RAM.Channels = SMB_MEM_CHANNEL_DUAL;␊ |
309 | ␉else␊ |
310 | ␉␉Platform.RAM.Channels = SMB_MEM_CHANNEL_SINGLE;␊ |
311 | }␊ |
312 | ␊ |
313 | // Get im965 Memory Timings␊ |
314 | static void get_timings_im965(pci_dt_t *dram_dev)␊ |
315 | {␊ |
316 | ␉// Thanks for CDH optis␊ |
317 | ␉uint32_t dev0, c0ckectrl, c1ckectrl, offset, ODT_Control_Register, Precharge_Register;␊ |
318 | ␉long *ptr;␊ |
319 | ␉␊ |
320 | ␉// Read MMR Base Address␊ |
321 | ␉dev0 = pci_config_read32(dram_dev->dev.addr, 0x48);␊ |
322 | ␉dev0 &= 0xFFFFC000;␊ |
323 | ␉␊ |
324 | ␉ptr = (long*)(dev0 + 0x1200);␊ |
325 | ␉c0ckectrl = *ptr & 0xFFFFFFFF;␉␊ |
326 | ␉␊ |
327 | ␉ptr = (long*)(dev0 + 0x1300);␊ |
328 | ␉c1ckectrl = *ptr & 0xFFFFFFFF;␊ |
329 | ␉␊ |
330 | ␉// If DIMM 0 not populated, check DIMM 1␊ |
331 | ␉((c0ckectrl) >> 20 & 0xF) ? (offset = 0) : (offset = 0x100);␊ |
332 | ␉␊ |
333 | ␉ptr = (long*)(dev0 + offset + 0x121C);␊ |
334 | ␉ODT_Control_Register = *ptr & 0xFFFFFFFF;␊ |
335 | ␉␊ |
336 | ␉ptr = (long*)(dev0 + offset + 0x1214);␉␊ |
337 | ␉Precharge_Register = *ptr & 0xFFFFFFFF;␊ |
338 | ␉␊ |
339 | ␉// Series only support DDR2␊ |
340 | ␉Platform.RAM.Type = SMB_MEM_TYPE_DDR2;␊ |
341 | ␉␊ |
342 | ␉// CAS Latency (tCAS)␊ |
343 | ␉Platform.RAM.CAS = ((ODT_Control_Register >> 23) & 7) + 3;␊ |
344 | ␉␊ |
345 | ␉// RAS-To-CAS (tRCD)␊ |
346 | ␉Platform.RAM.TRC = ((Precharge_Register >> 5) & 7) + 2;␊ |
347 | ␉␊ |
348 | ␉// RAS Precharge (tRP)␊ |
349 | ␉Platform.RAM.TRP= (Precharge_Register & 7) + 2;␊ |
350 | ␉␊ |
351 | ␉// RAS Active to precharge (tRAS)␊ |
352 | ␉Platform.RAM.RAS = (Precharge_Register >> 21) & 0x1F;␊ |
353 | ␉␊ |
354 | ␉if ((c0ckectrl >> 20 & 0xF) && (c1ckectrl >> 20 & 0xF)) ␊ |
355 | ␉␉Platform.RAM.Channels = SMB_MEM_CHANNEL_DUAL;␊ |
356 | ␉else␊ |
357 | ␉␉Platform.RAM.Channels = SMB_MEM_CHANNEL_SINGLE;␊ |
358 | }␊ |
359 | ␊ |
360 | // Get P35 Memory Timings␊ |
361 | static void get_timings_p35(pci_dt_t *dram_dev)␊ |
362 | { ␊ |
363 | ␉// Thanks for CDH optis␊ |
364 | ␉unsigned long dev0, Memory_Check, c0ckectrl, c1ckectrl, offset;␊ |
365 | ␉unsigned long ODT_Control_Register, Precharge_Register, ACT_Register, Read_Register, Misc_Register;␊ |
366 | ␉long *ptr;␊ |
367 | ␉␊ |
368 | ␉//Device_ID = pci_config_read16(dram_dev->dev.addr, 0x02);␊ |
369 | ␉//Device_ID &= 0xFFFF;␊ |
370 | ␉␊ |
371 | ␉// Now, read MMR Base Address␊ |
372 | ␉dev0 = pci_config_read32(dram_dev->dev.addr, 0x48);␊ |
373 | ␉dev0 &= 0xFFFFC000;␊ |
374 | ␉␊ |
375 | ␉ptr = (long*)(dev0 + 0x260);␊ |
376 | ␉c0ckectrl = *ptr & 0xFFFFFFFF;␉␊ |
377 | ␉␊ |
378 | ␉ptr = (long*)(dev0 + 0x660);␊ |
379 | ␉c1ckectrl = *ptr & 0xFFFFFFFF;␊ |
380 | ␉␊ |
381 | ␉// If DIMM 0 not populated, check DIMM 1␊ |
382 | ␉((c0ckectrl) >> 20 & 0xF) ? (offset = 0) : (offset = 0x400);␊ |
383 | ␉␊ |
384 | ␉ptr = (long*)(dev0 + offset + 0x265);␊ |
385 | ␉ODT_Control_Register = *ptr & 0xFFFFFFFF;␊ |
386 | ␉␊ |
387 | ␉ptr = (long*)(dev0 + offset + 0x25D);␉␊ |
388 | ␉Precharge_Register = *ptr & 0xFFFFFFFF;␊ |
389 | ␉␊ |
390 | ␉ptr = (long*)(dev0 + offset + 0x252);␊ |
391 | ␉ACT_Register = *ptr & 0xFFFFFFFF;␊ |
392 | ␉␊ |
393 | ␉ptr = (long*)(dev0 + offset + 0x258);␊ |
394 | ␉Read_Register = *ptr & 0xFFFFFFFF;␊ |
395 | ␉␊ |
396 | ␉ptr = (long*)(dev0 + offset + 0x244);␊ |
397 | ␉Misc_Register = *ptr & 0xFFFFFFFF;␊ |
398 | ␉␊ |
399 | ␉ptr = (long*)(dev0 + offset + 0x1E8);␊ |
400 | ␉Memory_Check = *ptr & 0xFFFFFFFF;␉␊ |
401 | ␉␊ |
402 | ␉// On P45, check 1A8␊ |
403 | ␉if(dram_dev->device_id > 0x2E00) {␊ |
404 | ␉␉ptr = (long*)(dev0 + offset + 0x1A8);␊ |
405 | ␉␉Memory_Check = *ptr & 0xFFFFFFFF;␉␊ |
406 | ␉␉Memory_Check >>= 2;␊ |
407 | ␉␉Memory_Check &= 1;␊ |
408 | ␉␉Memory_Check = !Memory_Check;␊ |
409 | ␉} else {␊ |
410 | ␉␉ptr = (long*)(dev0 + offset + 0x1E8);␊ |
411 | ␉␉Memory_Check = *ptr & 0xFFFFFFFF;␉␉␊ |
412 | ␉}␊ |
413 | ␉␊ |
414 | ␉// Determine DDR-II or DDR-III␊ |
415 | ␉if (Memory_Check & 1)␊ |
416 | ␉␉Platform.RAM.Type = SMB_MEM_TYPE_DDR2;␊ |
417 | ␉else␊ |
418 | ␉␉Platform.RAM.Type = SMB_MEM_TYPE_DDR3;␊ |
419 | ␉␊ |
420 | ␉// CAS Latency (tCAS)␊ |
421 | ␉if(dram_dev->device_id > 0x2E00)␊ |
422 | ␉␉Platform.RAM.CAS = ((ODT_Control_Register >> 8) & 0x3F) - 6;␊ |
423 | ␉else␊ |
424 | ␉␉Platform.RAM.CAS = ((ODT_Control_Register >> 8) & 0x3F) - 9;␊ |
425 | ␉␊ |
426 | ␉// RAS-To-CAS (tRCD)␊ |
427 | ␉Platform.RAM.TRC = (Read_Register >> 17) & 0xF;␊ |
428 | ␉␊ |
429 | ␉// RAS Precharge (tRP)␊ |
430 | ␉Platform.RAM.TRP = (ACT_Register >> 13) & 0xF;␊ |
431 | ␉␊ |
432 | ␉// RAS Active to precharge (tRAS)␊ |
433 | ␉Platform.RAM.RAS = Precharge_Register & 0x3F;␊ |
434 | ␉␊ |
435 | ␉// Channel configuration␊ |
436 | ␉if (((c0ckectrl >> 20) & 0xF) && ((c1ckectrl >> 20) & 0xF)) ␊ |
437 | ␉␉Platform.RAM.Channels = SMB_MEM_CHANNEL_DUAL;␊ |
438 | ␉else␊ |
439 | ␉␉Platform.RAM.Channels = SMB_MEM_CHANNEL_SINGLE;␊ |
440 | }␊ |
441 | ␊ |
442 | // Get Nehalem Memory Timings␊ |
443 | static void get_timings_nhm(pci_dt_t *dram_dev)␊ |
444 | {␊ |
445 | ␉unsigned long mc_channel_bank_timing, mc_control, mc_channel_mrs_value;␊ |
446 | ␉int fvc_bn = 4;␊ |
447 | ␉␊ |
448 | ␉// Find which channels are populated␊ |
449 | ␉mc_control = pci_config_read16(PCIADDR(nhm_bus, 3, 0), 0x48);␊ |
450 | ␉mc_control = (mc_control >> 8) & 0x7;␊ |
451 | ␉␊ |
452 | ␉// DDR-III␊ |
453 | ␉Platform.RAM.Type = SMB_MEM_TYPE_DDR3;␊ |
454 | ␉␊ |
455 | ␉// Get the first valid channel␊ |
456 | ␉if(mc_control & 1)␊ |
457 | ␉␉fvc_bn = 4; ␊ |
458 | ␉else if(mc_control & 2)␊ |
459 | ␉␉fvc_bn = 5; ␊ |
460 | ␉else if(mc_control & 7) ␊ |
461 | ␉␉fvc_bn = 6; ␊ |
462 | ␉␊ |
463 | ␉// Now, detect timings␊ |
464 | ␉mc_channel_bank_timing = pci_config_read32(PCIADDR(nhm_bus, fvc_bn, 0), 0x88);␊ |
465 | ␉mc_channel_mrs_value = pci_config_read32(PCIADDR(nhm_bus, fvc_bn, 0), 0x70);␊ |
466 | ␉␊ |
467 | ␉// CAS Latency (tCAS)␊ |
468 | ␉Platform.RAM.CAS = ((mc_channel_mrs_value >> 4) & 0xF ) + 4;␊ |
469 | ␉␊ |
470 | ␉// RAS-To-CAS (tRCD)␊ |
471 | ␉Platform.RAM.TRC = (mc_channel_bank_timing >> 9) & 0xF; ␊ |
472 | ␉␊ |
473 | ␉// RAS Active to precharge (tRAS)␊ |
474 | ␉Platform.RAM.RAS = (mc_channel_bank_timing >> 4) & 0x1F; ␊ |
475 | ␉␊ |
476 | ␉// RAS Precharge (tRP)␊ |
477 | ␉Platform.RAM.TRP = mc_channel_bank_timing & 0xF;␊ |
478 | ␉␊ |
479 | ␉// Single , Dual or Triple Channels␊ |
480 | ␉if (mc_control == 1 || mc_control == 2 || mc_control == 4 )␊ |
481 | ␉␉Platform.RAM.Channels = SMB_MEM_CHANNEL_SINGLE;␊ |
482 | ␉else if (mc_control == 7)␊ |
483 | ␉␉Platform.RAM.Channels = SMB_MEM_CHANNEL_TRIPLE;␊ |
484 | ␉else␊ |
485 | ␉␉Platform.RAM.Channels = SMB_MEM_CHANNEL_DUAL;␊ |
486 | }␊ |
487 | ␊ |
488 | static struct mem_controller_t dram_controllers[] = {␊ |
489 | ␊ |
490 | ␉// Default unknown chipset␊ |
491 | ␉{ 0, 0, "",␉NULL, NULL, NULL },␊ |
492 | ␊ |
493 | ␉// Intel␊ |
494 | ␉{ 0x8086, 0x7190, "VMWare",␉NULL, NULL, NULL },␊ |
495 | ␊ |
496 | ␉{ 0x8086, 0x1A30, "i845",␉NULL, NULL, NULL },␊ |
497 | ␉␊ |
498 | ␉{ 0x8086, 0x2970, "i946PL/GZ",␉␉setup_p35, get_fsb_i965, get_timings_i965 },␊ |
499 | ␉{ 0x8086, 0x2990, "Q963/Q965",␉␉setup_p35, get_fsb_i965, get_timings_i965 },␊ |
500 | ␉{ 0x8086, 0x29A0, "P965/G965",␉␉setup_p35, get_fsb_i965, get_timings_i965 },␊ |
501 | ␊ |
502 | ␉{ 0x8086, 0x2A00, "GM965/GL960",␉setup_p35, get_fsb_im965, get_timings_im965 },␊ |
503 | ␉{ 0x8086, 0x2A10, "GME965/GLE960",␉setup_p35, get_fsb_im965, get_timings_im965 },␊ |
504 | ␉{ 0x8086, 0x2A40, "PM/GM45/47",␉␉setup_p35, get_fsb_im965, get_timings_im965 },␉␊ |
505 | ␊ |
506 | ␉{ 0x8086, 0x29B0, "Q35",␉␉␉setup_p35, get_fsb_i965, get_timings_p35 },␉␊ |
507 | ␉{ 0x8086, 0x29C0, "P35/G33",␉␉setup_p35, get_fsb_i965, get_timings_p35 },␉␊ |
508 | ␉{ 0x8086, 0x29D0, "Q33",␉␉␉setup_p35, get_fsb_i965, get_timings_p35 },␉␊ |
509 | ␉{ 0x8086, 0x29E0, "X38/X48",␉␉setup_p35, get_fsb_i965, get_timings_p35 },␉␉␉␊ |
510 | ␉{ 0x8086, 0x2E00, "Eaglelake",␉␉setup_p35, get_fsb_i965, get_timings_p35 },␊ |
511 | ␉{ 0x8086, 0x2E10, "Q45/Q43",␉␉setup_p35, get_fsb_i965, get_timings_p35 },␉␊ |
512 | ␉{ 0x8086, 0x2E20, "P45/G45",␉␉setup_p35, get_fsb_i965, get_timings_p35 },␉␊ |
513 | ␉{ 0x8086, 0x2E30, "G41",␉␉␉setup_p35, get_fsb_i965, get_timings_p35 },␊ |
514 | ␉␊ |
515 | ␉{ 0x8086, 0xD131, "NHM IMC",␉␉setup_nhm, get_fsb_nhm, get_timings_nhm },␊ |
516 | ␉{ 0x8086, 0xD132, "NHM IMC",␉␉setup_nhm, get_fsb_nhm, get_timings_nhm },␊ |
517 | ␉{ 0x8086, 0x3400, "NHM IMC",␉␉setup_nhm, get_fsb_nhm,␉ get_timings_nhm },␊ |
518 | ␉{ 0x8086, 0x3401, "NHM IMC",␉␉setup_nhm, get_fsb_nhm, get_timings_nhm },␊ |
519 | ␉{ 0x8086, 0x3402, "NHM IMC",␉␉setup_nhm, get_fsb_nhm, get_timings_nhm },␊ |
520 | ␉{ 0x8086, 0x3403, "NHM IMC",␉␉setup_nhm, get_fsb_nhm, get_timings_nhm },␊ |
521 | ␉{ 0x8086, 0x3404, "NHM IMC",␉␉setup_nhm, get_fsb_nhm, get_timings_nhm },␊ |
522 | ␉{ 0x8086, 0x3405, "NHM IMC",␉␉setup_nhm, get_fsb_nhm, get_timings_nhm },␊ |
523 | ␉{ 0x8086, 0x3406, "NHM IMC",␉␉setup_nhm, get_fsb_nhm, get_timings_nhm },␊ |
524 | ␉{ 0x8086, 0x3407, "NHM IMC",␉␉setup_nhm, get_fsb_nhm, get_timings_nhm },␊ |
525 | ␉␊ |
526 | };␊ |
527 | ␊ |
528 | static const char *memory_channel_types[] =␊ |
529 | {␊ |
530 | ␉"Unknown", "Single", "Dual", "Triple"␊ |
531 | };␉␉␉␊ |
532 | ␊ |
533 | void scan_dram_controller(pci_dt_t *dram_dev)␊ |
534 | {␊ |
535 | ␉int i;␊ |
536 | ␉for(i = 1; i < sizeof(dram_controllers) / sizeof(dram_controllers[0]); i++)␊ |
537 | ␉if ((dram_controllers[i].vendor == dram_dev->vendor_id) ␊ |
538 | ␉␉␉␉&& (dram_controllers[i].device == dram_dev->device_id))␊ |
539 | ␉␉{␊ |
540 | ␉␉␉verbose("%s%s DRAM Controller [%4x:%4x] at %02x:%02x.%x\n", ␊ |
541 | ␉␉␉␉␉␉(dram_dev->vendor_id == 0x8086) ? "Intel " : "" ,␊ |
542 | ␉␉␉␉␉␉dram_controllers[i].name, dram_dev->vendor_id, dram_dev->device_id,␊ |
543 | ␉␉␉␉␉␉dram_dev->dev.bits.bus, dram_dev->dev.bits.dev, dram_dev->dev.bits.func);␊ |
544 | ␉␉␉␊ |
545 | ␉␉␉if (dram_controllers[i].initialise != NULL)␊ |
546 | ␉␉␉␉dram_controllers[i].initialise(dram_dev);␊ |
547 | ␉␉␉␉␉␉␉␊ |
548 | ␉␉␉if (dram_controllers[i].poll_timings != NULL)␊ |
549 | ␉␉␉␉dram_controllers[i].poll_timings(dram_dev);␊ |
550 | ␉␉␉␉␉␉␉␉␊ |
551 | ␉␉␉if (dram_controllers[i].poll_speed != NULL)␊ |
552 | ␉␉␉␉dram_controllers[i].poll_speed(dram_dev);␊ |
553 | ␊ |
554 | ␉␉␉verbose("Frequency detected: %d MHz (%d) %s Channel \n\tCAS:%d tRC:%d tRP:%d RAS:%d (%d-%d-%d-%d)\n", ␊ |
555 | ␉␉␉␉␉␉(uint32_t)Platform.RAM.Frequency / 1000000,␊ |
556 | ␉␉␉␉␉␉(uint32_t)Platform.RAM.Frequency / 500000,␊ |
557 | ␉␉␉␉␉␉memory_channel_types[Platform.RAM.Channels]␊ |
558 | ␉␉␉␉␉,Platform.RAM.CAS, Platform.RAM.TRC, Platform.RAM.TRP, Platform.RAM.RAS␊ |
559 | ␉␉␉␉␉,Platform.RAM.CAS, Platform.RAM.TRC, Platform.RAM.TRP, Platform.RAM.RAS␊ |
560 | ␉␉␉␉ );␊ |
561 | ␉␉␉/* getc();␊ |
562 | ␉␉␉ */␉␉␉␊ |
563 | ␉␉}␉␊ |
564 | }␉␊ |
565 |