3rdparty/fsp: Update submodule to upstream master
[coreboot2.git] / src / northbridge / intel / i945 / raminit.c
blobb664fbee08e764a0f0e896ae22ff7c15c63b115e
1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <cf9_reset.h>
4 #include <console/console.h>
5 #include <delay.h>
6 #include <device/device.h>
7 #include <device/dram/ddr2.h>
8 #include <device/mmio.h>
9 #include <device/pci_ops.h>
10 #include <device/pci_type.h>
11 #include <device/smbus_host.h>
12 #include <inttypes.h>
13 #include <lib.h>
14 #include <pc80/mc146818rtc.h>
15 #include <spd.h>
16 #include <string.h>
17 #include <timestamp.h>
18 #include <types.h>
20 #include "raminit.h"
21 #include "i945.h"
22 #include "chip.h"
24 /* Debugging macros. */
25 #if CONFIG(DEBUG_RAM_SETUP)
26 #define PRINTK_DEBUG(x...) printk(BIOS_DEBUG, x)
27 #else
28 #define PRINTK_DEBUG(x...)
29 #endif
31 #define RAM_INITIALIZATION_COMPLETE (1 << 19)
33 #define RAM_COMMAND_SELF_REFRESH (0x0 << 16)
34 #define RAM_COMMAND_NOP (0x1 << 16)
35 #define RAM_COMMAND_PRECHARGE (0x2 << 16)
36 #define RAM_COMMAND_MRS (0x3 << 16)
37 #define RAM_COMMAND_EMRS (0x4 << 16)
38 #define RAM_COMMAND_CBR (0x6 << 16)
39 #define RAM_COMMAND_NORMAL (0x7 << 16)
41 #define RAM_EMRS_1 (0x0 << 21)
42 #define RAM_EMRS_2 (0x1 << 21)
43 #define RAM_EMRS_3 (0x2 << 21)
45 #define DEFAULT_PCI_MMIO_SIZE 768
46 static int get_dimm_spd_address(struct sys_info *sysinfo, int device)
48 if (sysinfo->spd_addresses)
49 return sysinfo->spd_addresses[device];
50 else
51 return 0x50 + device;
54 static __attribute__((noinline)) void do_ram_command(u32 command)
56 u32 reg32;
58 reg32 = mchbar_read32(DCC);
59 reg32 &= ~((3 << 21) | (1 << 20) | (1 << 19) | (7 << 16));
60 reg32 |= command;
62 /* Also set Init Complete */
63 if (command == RAM_COMMAND_NORMAL)
64 reg32 |= RAM_INITIALIZATION_COMPLETE;
66 PRINTK_DEBUG(" Sending RAM command 0x%08x", reg32);
68 mchbar_write32(DCC, reg32); /* This is the actual magic */
70 PRINTK_DEBUG("...done\n");
72 udelay(1);
75 static void ram_read32(uintptr_t offset)
77 PRINTK_DEBUG(" RAM read: %" PRIxPTR "\n", offset);
79 read32p(offset);
82 void sdram_dump_mchbar_registers(void)
84 int i;
85 printk(BIOS_DEBUG, "Dumping MCHBAR Registers\n");
87 for (i = 0; i < 0xfff; i += 4) {
88 if (mchbar_read32(i) == 0)
89 continue;
90 printk(BIOS_DEBUG, "0x%04x: 0x%08x\n", i, mchbar_read32(i));
94 static int memclk(void)
96 int offset = CONFIG(NORTHBRIDGE_INTEL_SUBTYPE_I945GM) ? 1 : 0;
98 switch (((mchbar_read32(CLKCFG) >> 4) & 7) - offset) {
99 case 1: return 400;
100 case 2: return 533;
101 case 3: return 667;
102 default:
103 printk(BIOS_DEBUG, "%s: unknown register value %x\n", __func__,
104 ((mchbar_read32(CLKCFG) >> 4) & 7) - offset);
106 return -1;
109 static u16 fsbclk(void)
111 if (CONFIG(NORTHBRIDGE_INTEL_SUBTYPE_I945GM)) {
112 switch (mchbar_read32(CLKCFG) & 7) {
113 case 0: return 400;
114 case 1: return 533;
115 case 3: return 667;
116 default:
117 printk(BIOS_DEBUG, "%s: unknown register value %x\n", __func__,
118 mchbar_read32(CLKCFG) & 7);
120 return 0xffff;
121 } else if (CONFIG(NORTHBRIDGE_INTEL_SUBTYPE_I945GC)) {
122 switch (mchbar_read32(CLKCFG) & 7) {
123 case 0: return 1066;
124 case 1: return 533;
125 case 2: return 800;
126 default:
127 printk(BIOS_DEBUG, "%s: unknown register value %x\n", __func__,
128 mchbar_read32(CLKCFG) & 7);
130 return 0xffff;
134 static int sdram_capabilities_max_supported_memory_frequency(void)
136 u32 reg32;
138 #if CONFIG_MAXIMUM_SUPPORTED_FREQUENCY
139 return CONFIG_MAXIMUM_SUPPORTED_FREQUENCY;
140 #endif
142 reg32 = pci_read_config32(HOST_BRIDGE, 0xe4); /* CAPID0 + 4 */
143 reg32 &= (7 << 0);
145 switch (reg32) {
146 case 4: return 400;
147 case 3: return 533;
148 case 2: return 667;
150 /* Newer revisions of this chipset rather support faster memory clocks,
151 * so if it's a reserved value, return the fastest memory clock that we
152 * know of and can handle
154 return 667;
158 * @brief determine whether chipset is capable of dual channel interleaved mode
160 * @return 1 if interleaving is supported, 0 otherwise
162 static int sdram_capabilities_interleave(void)
164 u32 reg32;
166 reg32 = pci_read_config32(HOST_BRIDGE, 0xe4); /* CAPID0 + 4 */
167 reg32 >>= 25;
168 reg32 &= 1;
170 return (!reg32);
174 * @brief determine whether chipset is capable of two memory channels
176 * @return 1 if dual channel operation is supported, 0 otherwise
178 static int sdram_capabilities_dual_channel(void)
180 u32 reg32;
182 reg32 = pci_read_config32(HOST_BRIDGE, 0xe4); /* CAPID0 + 4 */
183 reg32 >>= 24;
184 reg32 &= 1;
186 return (!reg32);
189 static int sdram_capabilities_enhanced_addressing_xor(void)
191 u8 reg8;
193 reg8 = pci_read_config8(HOST_BRIDGE, 0xe5); /* CAPID0 + 5 */
194 reg8 &= (1 << 7);
196 return (!reg8);
199 #define GFX_FREQUENCY_CAP_166MHZ 0x04
200 #define GFX_FREQUENCY_CAP_200MHZ 0x03
201 #define GFX_FREQUENCY_CAP_250MHZ 0x02
202 #define GFX_FREQUENCY_CAP_ALL 0x00
204 static int sdram_capabilities_core_frequencies(void)
206 u8 reg8;
208 reg8 = pci_read_config8(HOST_BRIDGE, 0xe5); /* CAPID0 + 5 */
209 reg8 &= (1 << 3) | (1 << 2) | (1 << 1);
210 reg8 >>= 1;
212 return reg8;
215 static void sdram_detect_errors(struct sys_info *sysinfo)
217 u8 reg8;
218 bool do_reset = false;
220 reg8 = pci_read_config8(PCI_DEV(0, 0x1f, 0), GEN_PMCON_2);
222 if (reg8 & ((1 << 7) | (1 << 2))) {
223 if (reg8 & (1 << 2)) {
224 printk(BIOS_DEBUG, "SLP S4# Assertion Width Violation.\n");
225 /* Write back clears bit 2 */
226 pci_write_config8(PCI_DEV(0, 0x1f, 0), GEN_PMCON_2, reg8);
227 do_reset = true;
230 if (reg8 & (1 << 7)) {
231 printk(BIOS_DEBUG, "DRAM initialization was interrupted.\n");
232 reg8 &= ~(1 << 7);
233 pci_write_config8(PCI_DEV(0, 0x1f, 0), GEN_PMCON_2, reg8);
234 do_reset = true;
237 /* Set SLP_S3# Assertion Stretch Enable */
238 reg8 = pci_read_config8(PCI_DEV(0, 0x1f, 0), GEN_PMCON_3);
239 reg8 |= (1 << 3);
240 pci_write_config8(PCI_DEV(0, 0x1f, 0), GEN_PMCON_3, reg8);
242 if (do_reset) {
243 printk(BIOS_DEBUG, "Reset required.\n");
244 full_reset();
248 /* Set DRAM initialization bit in ICH7 */
249 pci_or_config8(PCI_DEV(0, 0x1f, 0), GEN_PMCON_2, 1 << 7);
251 /* clear self refresh status if check is disabled or not a resume */
252 if (!CONFIG(CHECK_SLFRCS_ON_RESUME) || sysinfo->boot_path != BOOT_PATH_RESUME) {
253 mchbar_setbits8(SLFRCS, 3);
254 } else {
255 /* Validate self refresh config */
256 if (((sysinfo->dimm[0] != SYSINFO_DIMM_NOT_POPULATED) ||
257 (sysinfo->dimm[1] != SYSINFO_DIMM_NOT_POPULATED)) &&
258 !(mchbar_read8(SLFRCS) & (1 << 0))) {
259 do_reset = true;
261 if (((sysinfo->dimm[2] != SYSINFO_DIMM_NOT_POPULATED) ||
262 (sysinfo->dimm[3] != SYSINFO_DIMM_NOT_POPULATED)) &&
263 !(mchbar_read8(SLFRCS) & (1 << 1))) {
264 do_reset = true;
268 if (do_reset) {
269 printk(BIOS_DEBUG, "Reset required.\n");
270 full_reset();
274 struct timings {
275 u32 min_tCLK_cas[8];
276 u32 min_tRAS;
277 u32 min_tRP;
278 u32 min_tRCD;
279 u32 min_tWR;
280 u32 min_tRFC;
281 u32 max_tRR;
282 u8 cas_mask;
286 * @brief loop over dimms and save maximal timings
288 static void gather_common_timing(struct sys_info *sysinfo, struct timings *saved_timings)
290 int i, j;
291 u8 raw_spd[SPD_SIZE_MAX_DDR2];
292 u8 dimm_mask = 0;
294 memset(saved_timings, 0, sizeof(*saved_timings));
295 saved_timings->max_tRR = UINT32_MAX;
296 saved_timings->cas_mask = SPD_CAS_LATENCY_DDR2_3 | SPD_CAS_LATENCY_DDR2_4
297 | SPD_CAS_LATENCY_DDR2_5;
300 * i945 supports two DIMMs, in two configurations:
302 * - single channel with two DIMMs
303 * - dual channel with one DIMM per channel
305 * In practice dual channel mainboards have their SPD at 0x50/0x52
306 * whereas single channel configurations have their SPD at 0x50/0x51.
308 * The capability register knows a lot about the channel configuration
309 * but for now we stick with the information we gather via SPD.
312 printk(BIOS_DEBUG, "This mainboard supports ");
313 if (sdram_capabilities_dual_channel()) {
314 sysinfo->dual_channel = true;
315 printk(BIOS_DEBUG, "Dual Channel Operation.\n");
316 } else {
317 sysinfo->dual_channel = false;
318 printk(BIOS_DEBUG, "only Single Channel Operation.\n");
321 for (i = 0; i < (2 * DIMM_SOCKETS); i++) {
322 int device = get_dimm_spd_address(sysinfo, i), bytes_read;
323 struct dimm_attr_ddr2_st dimm_info;
325 /* Initialize the socket information with a sane value */
326 sysinfo->dimm[i] = SYSINFO_DIMM_NOT_POPULATED;
328 /* Dual Channel not supported, but Channel 1? Bail out */
329 if (!sdram_capabilities_dual_channel() && (i >> 1))
330 continue;
332 if (smbus_read_byte(device, SPD_MEMORY_TYPE) !=
333 SPD_MEMORY_TYPE_SDRAM_DDR2) {
334 printk(BIOS_DEBUG, "DDR II Channel %d Socket %d: N/A\n",
335 (i >> 1), (i & 1));
336 continue;
340 * spd_decode_ddr2() needs a 128-byte sized array but
341 * only the first 64 bytes contain data needed for raminit.
344 bytes_read = i2c_eeprom_read(device, 0, 64, raw_spd);
345 printk(BIOS_DEBUG, "Reading SPD using i2c block operation.\n");
346 if (CONFIG(DEBUG_RAM_SETUP) && bytes_read > 0)
347 hexdump(raw_spd, bytes_read);
348 if (bytes_read != 64) {
349 /* Try again with SMBUS byte read */
350 printk(BIOS_DEBUG, "i2c block operation failed,"
351 " trying smbus byte operation.\n");
352 for (j = 0; j < 64; j++)
353 raw_spd[j] = smbus_read_byte(device, j);
354 if (CONFIG(DEBUG_RAM_SETUP))
355 hexdump(raw_spd, 64);
358 if (spd_decode_ddr2(&dimm_info, raw_spd) != SPD_STATUS_OK) {
359 printk(BIOS_WARNING, "Encountered problems with SPD, "
360 "skipping this DIMM.\n");
361 continue;
364 if (CONFIG(DEBUG_RAM_SETUP))
365 dram_print_spd_ddr2(&dimm_info);
367 if (dimm_info.flags.is_ecc)
368 die("\nError: ECC memory not supported by this chipset\n");
370 if (spd_dimm_is_registered_ddr2(dimm_info.dimm_type))
371 die("\nError: Registered memory not supported by this chipset\n");
373 printk(BIOS_DEBUG, "DDR II Channel %d Socket %d: ", (i >> 1), (i & 1));
375 * There are 5 different possible populations for a DIMM socket:
376 * 0. x16 double ranked (X16DS)
377 * 1. x8 double ranked (X8DS)
378 * 2. x16 single ranked (X16SS)
379 * 3. x8 double stacked (X8DDS)
380 * 4. Unpopulated
382 switch (dimm_info.width) {
383 case 8:
384 switch (dimm_info.ranks) {
385 case 2:
386 printk(BIOS_DEBUG, "x8DDS\n");
387 sysinfo->dimm[i] = SYSINFO_DIMM_X8DDS;
388 break;
389 case 1:
390 printk(BIOS_DEBUG, "x8DS\n");
391 sysinfo->dimm[i] = SYSINFO_DIMM_X8DS;
392 break;
393 default:
394 printk(BIOS_DEBUG, "Unsupported.\n");
396 break;
397 case 16:
398 switch (dimm_info.ranks) {
399 case 2:
400 printk(BIOS_DEBUG, "x16DS\n");
401 sysinfo->dimm[i] = SYSINFO_DIMM_X16DS;
402 break;
403 case 1:
404 printk(BIOS_DEBUG, "x16SS\n");
405 sysinfo->dimm[i] = SYSINFO_DIMM_X16SS;
406 break;
407 default:
408 printk(BIOS_DEBUG, "Unsupported.\n");
410 break;
411 default:
412 die("Unsupported DDR-II memory width.\n");
415 /* Is the current DIMM a stacked DIMM? */
416 if (dimm_info.flags.stacked)
417 sysinfo->package = SYSINFO_PACKAGE_STACKED;
419 if (!dimm_info.flags.bl8)
420 die("Only DDR-II RAM with burst length 8 is supported.\n");
422 if (dimm_info.ranksize_mb < 128)
423 die("DDR-II rank size smaller than 128MB is not supported.\n");
425 sysinfo->banksize[i * 2] = dimm_info.ranksize_mb / 32;
426 printk(BIOS_DEBUG, "DIMM %d side 0 = %zu MB\n", i,
427 sysinfo->banksize[i * 2] * 32);
428 if (dimm_info.ranks == 2) {
429 sysinfo->banksize[(i * 2) + 1] =
430 dimm_info.ranksize_mb / 32;
431 printk(BIOS_DEBUG, "DIMM %d side 1 = %zu MB\n",
432 i, sysinfo->banksize[(i * 2) + 1] * 32);
435 sysinfo->rows[i] = dimm_info.row_bits;
436 sysinfo->cols[i] = dimm_info.col_bits;
437 sysinfo->banks[i] = dimm_info.banks;
439 /* int min_tRAS, min_tRP, min_tRCD, min_tWR, min_tRFC; */
440 saved_timings->min_tRAS = MAX(saved_timings->min_tRAS, dimm_info.tRAS);
441 saved_timings->min_tRP = MAX(saved_timings->min_tRP, dimm_info.tRP);
442 saved_timings->min_tRCD = MAX(saved_timings->min_tRCD, dimm_info.tRCD);
443 saved_timings->min_tWR = MAX(saved_timings->min_tWR, dimm_info.tWR);
444 saved_timings->min_tRFC = MAX(saved_timings->min_tRFC, dimm_info.tRFC);
445 saved_timings->max_tRR = MIN(saved_timings->max_tRR, dimm_info.tRR);
446 saved_timings->cas_mask &= dimm_info.cas_supported;
447 for (j = 0; j < 8; j++) {
448 if (!(saved_timings->cas_mask & (1 << j)))
449 saved_timings->min_tCLK_cas[j] = 0;
450 else
451 saved_timings->min_tCLK_cas[j] = MAX(dimm_info.cycle_time[j],
452 saved_timings->min_tCLK_cas[j]);
454 dimm_mask |= (1 << i);
456 if (!dimm_mask)
457 die("No memory installed.\n");
459 if (!(dimm_mask & ((1 << DIMM_SOCKETS) - 1)))
460 /* FIXME: Possibly does not boot in this case */
461 printk(BIOS_INFO, "Channel 0 has no memory populated.\n");
464 static void choose_tclk(struct sys_info *sysinfo, struct timings *saved_timings)
466 u32 ctrl_min_tclk;
467 int try_cas;
469 ctrl_min_tclk = 2 * 256 * 1000 / sdram_capabilities_max_supported_memory_frequency();
470 normalize_tck(&ctrl_min_tclk);
472 try_cas = spd_get_msbs(saved_timings->cas_mask);
474 while (saved_timings->cas_mask & (1 << try_cas) && try_cas > 0) {
475 sysinfo->cas = try_cas;
476 sysinfo->tclk = saved_timings->min_tCLK_cas[try_cas];
477 if (sysinfo->tclk >= ctrl_min_tclk &&
478 saved_timings->min_tCLK_cas[try_cas] !=
479 saved_timings->min_tCLK_cas[try_cas - 1])
480 break;
481 try_cas--;
484 normalize_tck(&sysinfo->tclk);
486 if ((sysinfo->cas < 3) || (sysinfo->tclk == 0))
487 die("Could not find common memory frequency and CAS\n");
490 * The loop can still results in a timing too fast for the
491 * memory controller.
493 if (sysinfo->tclk < ctrl_min_tclk)
494 sysinfo->tclk = ctrl_min_tclk;
496 switch (sysinfo->tclk) {
497 case TCK_200MHZ:
498 sysinfo->memory_frequency = 400;
499 break;
500 case TCK_266MHZ:
501 sysinfo->memory_frequency = 533;
502 break;
503 case TCK_333MHZ:
504 sysinfo->memory_frequency = 667;
505 break;
508 printk(BIOS_DEBUG,
509 "Memory will be driven at %dMT with CAS=%d clocks\n",
510 sysinfo->memory_frequency, sysinfo->cas);
513 static void derive_timings(struct sys_info *sysinfo, struct timings *saved_timings)
515 sysinfo->tras = DIV_ROUND_UP(saved_timings->min_tRAS, sysinfo->tclk);
516 if (sysinfo->tras > 0x18)
517 die("DDR-II Module does not support this frequency (tRAS error)\n");
519 sysinfo->trp = DIV_ROUND_UP(saved_timings->min_tRP, sysinfo->tclk);
520 if (sysinfo->trp > 6)
521 die("DDR-II Module does not support this frequency (tRP error)\n");
523 sysinfo->trcd = DIV_ROUND_UP(saved_timings->min_tRCD, sysinfo->tclk);
524 if (sysinfo->trcd > 6)
525 die("DDR-II Module does not support this frequency (tRCD error)\n");
527 sysinfo->twr = DIV_ROUND_UP(saved_timings->min_tWR, sysinfo->tclk);
528 if (sysinfo->twr > 5)
529 die("DDR-II Module does not support this frequency (tWR error)\n");
531 sysinfo->trfc = DIV_ROUND_UP(saved_timings->min_tRFC, sysinfo->tclk);
533 printk(BIOS_DEBUG, "tRAS = %d cycles\n", sysinfo->tras);
534 printk(BIOS_DEBUG, "tRP = %d cycles\n", sysinfo->trp);
535 printk(BIOS_DEBUG, "tRCD = %d cycles\n", sysinfo->trcd);
536 printk(BIOS_DEBUG, "tWR = %d cycles\n", sysinfo->twr);
537 printk(BIOS_DEBUG, "tRFC = %d cycles\n", sysinfo->trfc);
539 /* Refresh is slower than 15.6us, use 15.6us */
540 /* tRR is decoded in units of 1/256us */
542 #define T_RR_7_8US 2000000
543 #define T_RR_15_6US 4000000
544 #define REFRESH_7_8US 1
545 #define REFRESH_15_6US 0
547 if (saved_timings->max_tRR < T_RR_7_8US)
548 die("DDR-II module has unsupported refresh value\n");
549 else if (saved_timings->max_tRR < T_RR_15_6US)
550 sysinfo->refresh = REFRESH_7_8US;
551 else
552 sysinfo->refresh = REFRESH_15_6US;
553 printk(BIOS_DEBUG, "Refresh: %s\n", sysinfo->refresh ? "7.8us" : "15.6us");
557 * @brief Get generic DIMM parameters.
558 * @param sysinfo Central memory controller information structure
560 * This function gathers several pieces of information for each system DIMM:
561 * o DIMM width (x8 / x16)
562 * o DIMM rank (single ranked / dual ranked)
564 * Also, some non-supported scenarios are detected.
567 static void sdram_get_dram_configuration(struct sys_info *sysinfo)
569 struct timings saved_timings;
571 gather_common_timing(sysinfo, &saved_timings);
572 choose_tclk(sysinfo, &saved_timings);
573 derive_timings(sysinfo, &saved_timings);
576 static void sdram_program_dram_width(struct sys_info *sysinfo)
578 u16 c0dramw = 0, c1dramw = 0;
579 int i, idx;
581 if (sysinfo->dual_channel)
582 idx = 2;
583 else
584 idx = 1;
586 for (i = 0; i < DIMM_SOCKETS; i++) { /* Channel 0 */
587 switch (sysinfo->dimm[i]) {
588 case SYSINFO_DIMM_X16DS:
589 c0dramw |= (0x0000) << 4 * (i % 2);
590 break;
591 case SYSINFO_DIMM_X8DS:
592 c0dramw |= (0x0001) << 4 * (i % 2);
593 break;
594 case SYSINFO_DIMM_X16SS:
595 c0dramw |= (0x0000) << 4 * (i % 2);
596 break;
597 case SYSINFO_DIMM_X8DDS:
598 c0dramw |= (0x0005) << 4 * (i % 2);
599 break;
600 case SYSINFO_DIMM_NOT_POPULATED:
601 c0dramw |= (0x0000) << 4 * (i % 2);
602 break;
605 for (i = DIMM_SOCKETS; i < idx * DIMM_SOCKETS; i++) { /* Channel 1 */
606 switch (sysinfo->dimm[i]) {
607 case SYSINFO_DIMM_X16DS:
608 c1dramw |= (0x0000) << 4 * (i % 2);
609 break;
610 case SYSINFO_DIMM_X8DS:
611 c1dramw |= (0x0010) << 4 * (i % 2);
612 break;
613 case SYSINFO_DIMM_X16SS:
614 c1dramw |= (0x0000) << 4 * (i % 2);
615 break;
616 case SYSINFO_DIMM_X8DDS:
617 c1dramw |= (0x0050) << 4 * (i % 2);
618 break;
619 case SYSINFO_DIMM_NOT_POPULATED:
620 c1dramw |= (0x0000) << 4 * (i % 2);
621 break;
625 mchbar_write16(C0DRAMW, c0dramw);
626 mchbar_write16(C1DRAMW, c1dramw);
629 static void sdram_write_slew_rates(u32 offset, const u32 *slew_rate_table)
631 int i;
633 for (i = 0; i < 16; i++)
634 mchbar_write32(offset + (i * 4), slew_rate_table[i]);
637 static const u32 dq2030[] = {
638 0x08070706, 0x0a090908, 0x0d0c0b0a, 0x12100f0e,
639 0x1a181614, 0x22201e1c, 0x2a282624, 0x3934302d,
640 0x0a090908, 0x0c0b0b0a, 0x0e0d0d0c, 0x1211100f,
641 0x19171513, 0x211f1d1b, 0x2d292623, 0x3f393531
644 static const u32 dq2330[] = {
645 0x08070706, 0x0a090908, 0x0d0c0b0a, 0x12100f0e,
646 0x1a181614, 0x22201e1c, 0x2a282624, 0x3934302d,
647 0x0a090908, 0x0c0b0b0a, 0x0e0d0d0c, 0x1211100f,
648 0x19171513, 0x211f1d1b, 0x2d292623, 0x3f393531
651 static const u32 cmd2710[] = {
652 0x07060605, 0x0f0d0b09, 0x19171411, 0x1f1f1d1b,
653 0x1f1f1f1f, 0x1f1f1f1f, 0x1f1f1f1f, 0x1f1f1f1f,
654 0x1110100f, 0x0f0d0b09, 0x19171411, 0x1f1f1d1b,
655 0x1f1f1f1f, 0x1f1f1f1f, 0x1f1f1f1f, 0x1f1f1f1f
658 static const u32 cmd3210[] = {
659 0x0f0d0b0a, 0x17151311, 0x1f1d1b19, 0x1f1f1f1f,
660 0x1f1f1f1f, 0x1f1f1f1f, 0x1f1f1f1f, 0x1f1f1f1f,
661 0x18171615, 0x1f1f1c1a, 0x1f1f1f1f, 0x1f1f1f1f,
662 0x1f1f1f1f, 0x1f1f1f1f, 0x1f1f1f1f, 0x1f1f1f1f
665 static const u32 clk2030[] = {
666 0x0e0d0d0c, 0x100f0f0e, 0x100f0e0d, 0x15131211,
667 0x1d1b1917, 0x2523211f, 0x2a282927, 0x32302e2c,
668 0x17161514, 0x1b1a1918, 0x1f1e1d1c, 0x23222120,
669 0x27262524, 0x2d2b2928, 0x3533312f, 0x3d3b3937
672 static const u32 ctl3215[] = {
673 0x01010000, 0x03020101, 0x07060504, 0x0b0a0908,
674 0x100f0e0d, 0x14131211, 0x18171615, 0x1c1b1a19,
675 0x05040403, 0x07060605, 0x0a090807, 0x0f0d0c0b,
676 0x14131211, 0x18171615, 0x1c1b1a19, 0x201f1e1d
679 static const u32 ctl3220[] = {
680 0x05040403, 0x07060505, 0x0e0c0a08, 0x1a171411,
681 0x2825221f, 0x35322f2b, 0x3e3e3b38, 0x3e3e3e3e,
682 0x09080807, 0x0b0a0a09, 0x0f0d0c0b, 0x1b171311,
683 0x2825221f, 0x35322f2b, 0x3e3e3b38, 0x3e3e3e3e
686 static const u32 nc[] = {
687 0x00000000, 0x00000000, 0x00000000, 0x00000000,
688 0x00000000, 0x00000000, 0x00000000, 0x00000000,
689 0x00000000, 0x00000000, 0x00000000, 0x00000000,
690 0x00000000, 0x00000000, 0x00000000, 0x00000000
693 enum {
694 DQ2030,
695 DQ2330,
696 CMD2710,
697 CMD3210,
698 CLK2030,
699 CTL3215,
700 CTL3220,
704 static const u8 dual_channel_slew_group_lookup[] = {
705 DQ2030, CMD3210, CTL3215, CTL3215, CLK2030, CLK2030, DQ2030, CMD3210,
706 DQ2030, CMD3210, CTL3215, CTL3215, CLK2030, CLK2030, DQ2030, CMD3210,
707 DQ2030, CMD3210, NC, CTL3215, NC, CLK2030, DQ2030, CMD3210,
708 DQ2030, CMD3210, CTL3215, CTL3215, CLK2030, CLK2030, DQ2030, CMD2710,
709 DQ2030, CMD3210, NC, CTL3215, NC, CLK2030, NC, NC,
711 DQ2030, CMD3210, CTL3215, CTL3215, CLK2030, CLK2030, DQ2030, CMD3210,
712 DQ2030, CMD3210, CTL3215, NC, CLK2030, NC, DQ2030, CMD3210,
713 DQ2030, CMD3210, CTL3215, CTL3215, CLK2030, CLK2030, DQ2030, CMD3210,
714 DQ2030, CMD3210, CTL3215, NC, CLK2030, NC, DQ2030, CMD2710,
715 DQ2030, CMD3210, CTL3215, NC, CLK2030, NC, NC, NC,
717 DQ2030, CMD3210, NC, CTL3215, NC, CLK2030, DQ2030, CMD3210,
718 DQ2030, CMD3210, CTL3215, CTL3215, CLK2030, CLK2030, DQ2030, CMD3210,
719 DQ2030, CMD3210, NC, CTL3215, NC, CLK2030, DQ2030, CMD3210,
720 DQ2030, CMD3210, CTL3215, CTL3215, CLK2030, CLK2030, DQ2030, CMD2710,
721 DQ2030, CMD3210, NC, CTL3215, NC, CLK2030, NC, NC,
723 DQ2030, CMD2710, CTL3215, CTL3215, CLK2030, CLK2030, DQ2030, CMD3210,
724 DQ2030, CMD2710, CTL3215, NC, CLK2030, NC, DQ2030, CMD3210,
725 DQ2030, CMD2710, CTL3215, CTL3215, CLK2030, CLK2030, DQ2030, CMD3210,
726 DQ2030, CMD2710, CTL3215, NC, CLK2030, NC, DQ2030, CMD2710,
727 DQ2030, CMD2710, CTL3215, NC, CLK2030, NC, NC, NC,
729 NC, NC, NC, CTL3215, NC, CLK2030, DQ2030, CMD3210,
730 NC, NC, CTL3215, NC, CLK2030, NC, DQ2030, CMD3210,
731 NC, NC, NC, CTL3215, NC, CLK2030, DQ2030, CMD3210,
732 NC, NC, CTL3215, NC, CLK2030, CLK2030, DQ2030, CMD2710
735 static const u8 single_channel_slew_group_lookup[] = {
736 DQ2330, CMD3210, CTL3215, CTL3215, CLK2030, CLK2030, DQ2330, CMD3210,
737 DQ2330, CMD3210, CTL3215, CTL3215, CLK2030, CLK2030, DQ2330, CMD3210,
738 DQ2330, CMD3210, NC, CTL3215, NC, CLK2030, DQ2330, CMD3210,
739 DQ2330, CMD3210, CTL3215, CTL3215, CLK2030, CLK2030, DQ2330, CMD3210,
740 DQ2330, CMD3210, NC, CTL3215, NC, CLK2030, NC, NC,
742 DQ2330, CMD3210, CTL3215, CTL3215, CLK2030, CLK2030, DQ2330, CMD3210,
743 DQ2330, CMD3210, CTL3215, NC, CLK2030, NC, DQ2330, CMD3210,
744 DQ2330, CMD3210, CTL3215, CTL3215, CLK2030, CLK2030, DQ2330, CMD3210,
745 DQ2330, CMD3210, CTL3215, NC, CLK2030, NC, DQ2330, CMD3210,
746 DQ2330, CMD3210, CTL3215, NC, CLK2030, NC, NC, NC,
748 DQ2330, CMD3210, NC, CTL3215, NC, CLK2030, DQ2330, CMD3210,
749 DQ2330, CMD3210, CTL3215, CTL3215, CLK2030, CLK2030, DQ2330, CMD3210,
750 DQ2330, CMD3210, NC, CTL3215, NC, CLK2030, DQ2330, CMD3210,
751 DQ2330, CMD3210, CTL3215, CTL3215, CLK2030, CLK2030, DQ2330, CMD3210,
752 DQ2330, CMD3210, NC, CTL3215, NC, CLK2030, NC, NC,
754 DQ2330, CMD3210, CTL3215, CTL3215, CLK2030, CLK2030, DQ2330, CMD3210,
755 DQ2330, CMD3210, CTL3215, NC, CLK2030, NC, DQ2330, CMD3210,
756 DQ2330, CMD3210, CTL3215, CTL3215, CLK2030, CLK2030, DQ2330, CMD3210,
757 DQ2330, CMD3210, CTL3215, NC, CLK2030, NC, DQ2330, CMD3210,
758 DQ2330, CMD3210, CTL3215, NC, CLK2030, NC, NC, NC,
760 DQ2330, NC, NC, CTL3215, NC, CLK2030, DQ2030, CMD3210,
761 DQ2330, NC, CTL3215, NC, CLK2030, NC, DQ2030, CMD3210,
762 DQ2330, NC, NC, CTL3215, NC, CLK2030, DQ2030, CMD3210,
763 DQ2330, NC, CTL3215, NC, CLK2030, CLK2030, DQ2030, CMD3210
766 static const u32 *slew_group_lookup(bool dual_channel, int index)
768 const u8 *slew_group;
769 /* Dual Channel needs different tables. */
770 if (dual_channel)
771 slew_group = dual_channel_slew_group_lookup;
772 else
773 slew_group = single_channel_slew_group_lookup;
775 switch (slew_group[index]) {
776 case DQ2030: return dq2030;
777 case DQ2330: return dq2330;
778 case CMD2710: return cmd2710;
779 case CMD3210: return cmd3210;
780 case CLK2030: return clk2030;
781 case CTL3215: return ctl3215;
782 case CTL3220: return ctl3220;
783 case NC: return nc;
786 return nc;
789 #if CONFIG(NORTHBRIDGE_INTEL_SUBTYPE_I945GM)
790 /* Strength multiplier tables */
791 static const u8 dual_channel_strength_multiplier[] = {
792 0x44, 0x11, 0x11, 0x11, 0x44, 0x44, 0x44, 0x11,
793 0x44, 0x11, 0x11, 0x11, 0x44, 0x44, 0x44, 0x11,
794 0x44, 0x11, 0x00, 0x11, 0x00, 0x44, 0x44, 0x11,
795 0x44, 0x11, 0x11, 0x11, 0x44, 0x44, 0x44, 0x22,
796 0x44, 0x11, 0x00, 0x11, 0x00, 0x44, 0x00, 0x00,
797 0x44, 0x11, 0x11, 0x11, 0x44, 0x44, 0x44, 0x11,
798 0x44, 0x11, 0x11, 0x00, 0x44, 0x00, 0x44, 0x11,
799 0x44, 0x11, 0x11, 0x11, 0x44, 0x44, 0x44, 0x11,
800 0x44, 0x11, 0x11, 0x00, 0x44, 0x00, 0x44, 0x22,
801 0x44, 0x11, 0x11, 0x00, 0x44, 0x00, 0x00, 0x00,
802 0x44, 0x11, 0x00, 0x11, 0x00, 0x44, 0x44, 0x11,
803 0x44, 0x11, 0x11, 0x11, 0x44, 0x44, 0x44, 0x11,
804 0x44, 0x11, 0x00, 0x11, 0x00, 0x44, 0x44, 0x11,
805 0x44, 0x11, 0x11, 0x11, 0x44, 0x44, 0x44, 0x22,
806 0x44, 0x11, 0x00, 0x11, 0x00, 0x44, 0x00, 0x00,
807 0x44, 0x22, 0x11, 0x11, 0x44, 0x44, 0x44, 0x11,
808 0x44, 0x22, 0x11, 0x00, 0x44, 0x00, 0x44, 0x11,
809 0x44, 0x22, 0x11, 0x11, 0x44, 0x44, 0x44, 0x11,
810 0x44, 0x22, 0x11, 0x00, 0x44, 0x00, 0x44, 0x22,
811 0x44, 0x22, 0x11, 0x00, 0x44, 0x00, 0x00, 0x00,
812 0x00, 0x00, 0x00, 0x11, 0x00, 0x44, 0x44, 0x11,
813 0x00, 0x00, 0x11, 0x00, 0x44, 0x00, 0x44, 0x11,
814 0x00, 0x00, 0x00, 0x11, 0x00, 0x44, 0x44, 0x11,
815 0x00, 0x00, 0x11, 0x00, 0x44, 0x44, 0x44, 0x22
818 static const u8 single_channel_strength_multiplier[] = {
819 0x33, 0x11, 0x11, 0x11, 0x44, 0x44, 0x33, 0x11,
820 0x33, 0x11, 0x11, 0x11, 0x44, 0x44, 0x33, 0x11,
821 0x33, 0x11, 0x00, 0x11, 0x00, 0x44, 0x33, 0x11,
822 0x33, 0x11, 0x11, 0x11, 0x44, 0x44, 0x33, 0x11,
823 0x33, 0x11, 0x00, 0x11, 0x00, 0x44, 0x00, 0x00,
824 0x33, 0x11, 0x11, 0x11, 0x44, 0x44, 0x33, 0x11,
825 0x33, 0x11, 0x11, 0x00, 0x44, 0x00, 0x33, 0x11,
826 0x33, 0x11, 0x11, 0x11, 0x44, 0x44, 0x33, 0x11,
827 0x33, 0x11, 0x11, 0x00, 0x44, 0x00, 0x33, 0x11,
828 0x33, 0x11, 0x11, 0x00, 0x44, 0x00, 0x00, 0x00,
829 0x33, 0x11, 0x00, 0x11, 0x00, 0x44, 0x33, 0x11,
830 0x33, 0x11, 0x11, 0x11, 0x44, 0x44, 0x33, 0x11,
831 0x33, 0x11, 0x00, 0x11, 0x00, 0x44, 0x33, 0x11,
832 0x33, 0x11, 0x11, 0x11, 0x44, 0x44, 0x33, 0x11,
833 0x33, 0x11, 0x00, 0x11, 0x00, 0x44, 0x00, 0x00,
834 0x33, 0x11, 0x11, 0x11, 0x44, 0x44, 0x33, 0x11,
835 0x33, 0x11, 0x11, 0x00, 0x44, 0x00, 0x33, 0x11,
836 0x33, 0x11, 0x11, 0x11, 0x44, 0x44, 0x33, 0x11,
837 0x33, 0x11, 0x11, 0x00, 0x44, 0x00, 0x33, 0x11,
838 0x33, 0x11, 0x11, 0x00, 0x44, 0x00, 0x00, 0x00,
839 0x33, 0x00, 0x00, 0x11, 0x00, 0x44, 0x33, 0x11,
840 0x33, 0x00, 0x11, 0x00, 0x44, 0x00, 0x33, 0x11,
841 0x33, 0x00, 0x00, 0x11, 0x00, 0x44, 0x33, 0x11,
842 0x33, 0x00, 0x11, 0x00, 0x44, 0x44, 0x33, 0x11
844 #elif CONFIG(NORTHBRIDGE_INTEL_SUBTYPE_I945GC)
845 static const u8 dual_channel_strength_multiplier[] = {
846 0x44, 0x22, 0x00, 0x00, 0x44, 0x44, 0x44, 0x22,
847 0x44, 0x22, 0x00, 0x00, 0x44, 0x44, 0x44, 0x22,
848 0x44, 0x22, 0x00, 0x00, 0x44, 0x44, 0x44, 0x22,
849 0x44, 0x22, 0x00, 0x00, 0x44, 0x44, 0x44, 0x33,
850 0x44, 0x22, 0x00, 0x00, 0x44, 0x44, 0x44, 0x00,
851 0x44, 0x22, 0x00, 0x00, 0x44, 0x44, 0x44, 0x22,
852 0x44, 0x22, 0x00, 0x00, 0x44, 0x44, 0x44, 0x22,
853 0x44, 0x22, 0x00, 0x00, 0x44, 0x44, 0x44, 0x22,
854 0x44, 0x22, 0x00, 0x00, 0x44, 0x44, 0x44, 0x33,
855 0x44, 0x22, 0x00, 0x00, 0x44, 0x44, 0x44, 0x00,
856 0x44, 0x22, 0x00, 0x00, 0x44, 0x44, 0x44, 0x22,
857 0x44, 0x22, 0x00, 0x00, 0x44, 0x44, 0x44, 0x22,
858 0x44, 0x22, 0x00, 0x00, 0x44, 0x44, 0x44, 0x22,
859 0x44, 0x22, 0x00, 0x00, 0x44, 0x44, 0x44, 0x33,
860 0x44, 0x22, 0x00, 0x00, 0x44, 0x44, 0x44, 0x00,
861 0x44, 0x33, 0x00, 0x00, 0x44, 0x44, 0x44, 0x22,
862 0x44, 0x33, 0x00, 0x00, 0x44, 0x44, 0x44, 0x22,
863 0x44, 0x33, 0x00, 0x00, 0x44, 0x44, 0x44, 0x22,
864 0x44, 0x33, 0x00, 0x00, 0x44, 0x44, 0x44, 0x33,
865 0x44, 0x33, 0x00, 0x00, 0x44, 0x44, 0x44, 0x00,
866 0x44, 0x00, 0x00, 0x00, 0x44, 0x44, 0x44, 0x22,
867 0x44, 0x00, 0x00, 0x00, 0x44, 0x44, 0x44, 0x22,
868 0x44, 0x00, 0x00, 0x00, 0x44, 0x44, 0x44, 0x22,
869 0x44, 0x00, 0x00, 0x00, 0x44, 0x44, 0x44, 0x33
872 static const u8 single_channel_strength_multiplier[] = {
873 0x44, 0x33, 0x00, 0x00, 0x44, 0x44, 0x44, 0x00,
874 0x44, 0x44, 0x00, 0x00, 0x44, 0x44, 0x44, 0x00,
875 0x44, 0x33, 0x00, 0x00, 0x44, 0x44, 0x44, 0x00,
876 0x44, 0x55, 0x00, 0x00, 0x44, 0x44, 0x44, 0x00,
877 0x44, 0x22, 0x00, 0x00, 0x44, 0x44, 0x44, 0x00,
878 0x44, 0x44, 0x00, 0x00, 0x44, 0x44, 0x44, 0x00,
879 0x44, 0x55, 0x00, 0x00, 0x44, 0x44, 0x44, 0x00,
880 0x44, 0x44, 0x00, 0x00, 0x44, 0x44, 0x44, 0x00,
881 0x44, 0x88, 0x00, 0x00, 0x44, 0x44, 0x44, 0x00,
882 0x44, 0x22, 0x00, 0x00, 0x44, 0x44, 0x44, 0x00,
883 0x44, 0x33, 0x00, 0x00, 0x44, 0x44, 0x44, 0x00,
884 0x44, 0x44, 0x00, 0x00, 0x44, 0x44, 0x44, 0x00,
885 0x44, 0x33, 0x00, 0x00, 0x44, 0x44, 0x44, 0x00,
886 0x44, 0x55, 0x00, 0x00, 0x44, 0x44, 0x44, 0x00,
887 0x44, 0x22, 0x00, 0x00, 0x44, 0x44, 0x44, 0x00,
888 0x44, 0x55, 0x00, 0x00, 0x44, 0x44, 0x44, 0x00,
889 0x44, 0x88, 0x00, 0x00, 0x44, 0x44, 0x44, 0x00,
890 0x44, 0x55, 0x00, 0x00, 0x44, 0x44, 0x44, 0x00,
891 0x44, 0x88, 0x00, 0x00, 0x44, 0x44, 0x44, 0x00,
892 0x44, 0x33, 0x00, 0x00, 0x44, 0x44, 0x44, 0x00,
893 0x44, 0x22, 0x00, 0x00, 0x44, 0x44, 0x44, 0x00,
894 0x44, 0x22, 0x00, 0x00, 0x44, 0x44, 0x44, 0x00,
895 0x44, 0x22, 0x00, 0x00, 0x44, 0x44, 0x44, 0x00,
896 0x44, 0x33, 0x00, 0x00, 0x44, 0x44, 0x44, 0x00
898 #endif
900 static void sdram_rcomp_buffer_strength_and_slew(struct sys_info *sysinfo)
902 const u8 *strength_multiplier;
903 int idx;
904 bool dual_channel;
906 /* Set Strength Multipliers */
908 /* Dual Channel needs different tables. */
909 if (sdram_capabilities_dual_channel()) {
910 printk(BIOS_DEBUG, "Programming Dual Channel RCOMP\n");
911 strength_multiplier = dual_channel_strength_multiplier;
912 dual_channel = true;
913 idx = 5 * sysinfo->dimm[0] + sysinfo->dimm[2];
914 } else {
915 printk(BIOS_DEBUG, "Programming Single Channel RCOMP\n");
916 strength_multiplier = single_channel_strength_multiplier;
917 dual_channel = false;
918 idx = 5 * sysinfo->dimm[0] + sysinfo->dimm[1];
921 printk(BIOS_DEBUG, "Table Index: %d\n", idx);
923 mchbar_write8(G1SC, strength_multiplier[idx * 8 + 0]);
924 mchbar_write8(G2SC, strength_multiplier[idx * 8 + 1]);
925 mchbar_write8(G3SC, strength_multiplier[idx * 8 + 2]);
926 mchbar_write8(G4SC, strength_multiplier[idx * 8 + 3]);
927 mchbar_write8(G5SC, strength_multiplier[idx * 8 + 4]);
928 mchbar_write8(G6SC, strength_multiplier[idx * 8 + 5]);
929 mchbar_write8(G7SC, strength_multiplier[idx * 8 + 6]);
930 mchbar_write8(G8SC, strength_multiplier[idx * 8 + 7]);
932 /* Channel 0 */
933 sdram_write_slew_rates(G1SRPUT, slew_group_lookup(dual_channel, idx * 8 + 0));
934 sdram_write_slew_rates(G2SRPUT, slew_group_lookup(dual_channel, idx * 8 + 1));
935 if ((slew_group_lookup(dual_channel, idx * 8 + 2) != nc) &&
936 (sysinfo->package == SYSINFO_PACKAGE_STACKED))
938 sdram_write_slew_rates(G3SRPUT, ctl3220);
939 else
940 sdram_write_slew_rates(G3SRPUT, slew_group_lookup(dual_channel, idx * 8 + 2));
942 sdram_write_slew_rates(G4SRPUT, slew_group_lookup(dual_channel, idx * 8 + 3));
943 sdram_write_slew_rates(G5SRPUT, slew_group_lookup(dual_channel, idx * 8 + 4));
944 sdram_write_slew_rates(G6SRPUT, slew_group_lookup(dual_channel, idx * 8 + 5));
946 /* Channel 1 */
947 if (sysinfo->dual_channel) {
948 sdram_write_slew_rates(G7SRPUT, slew_group_lookup(dual_channel, idx * 8 + 6));
949 sdram_write_slew_rates(G8SRPUT, slew_group_lookup(dual_channel, idx * 8 + 7));
950 } else {
951 sdram_write_slew_rates(G7SRPUT, nc);
952 sdram_write_slew_rates(G8SRPUT, nc);
956 static void sdram_enable_rcomp(void)
958 u32 reg32;
959 /* Enable Global Periodic RCOMP */
960 udelay(300);
961 reg32 = mchbar_read32(GBRCOMPCTL);
962 reg32 &= ~(1 << 23);
963 mchbar_write32(GBRCOMPCTL, reg32);
966 static void sdram_program_dll_timings(struct sys_info *sysinfo)
968 u32 channeldll = 0;
969 int i;
971 printk(BIOS_DEBUG, "Programming DLL Timings...\n");
973 mchbar_clrbits16(DQSMT, 3 << 12 | 1 << 10 | 0xf << 0);
974 mchbar_setbits16(DQSMT, 1 << 13 | 0xc << 0);
976 /* We drive both channels with the same speed */
977 if (CONFIG(NORTHBRIDGE_INTEL_SUBTYPE_I945GM)) {
978 switch (sysinfo->memory_frequency) {
979 case 400:
980 channeldll = 0x26262626;
981 break;
982 case 533:
983 channeldll = 0x22222222;
984 break;
985 case 667:
986 channeldll = 0x11111111;
987 break;
989 } else if (CONFIG(NORTHBRIDGE_INTEL_SUBTYPE_I945GC)) {
990 switch (sysinfo->memory_frequency) {
991 case 400:
992 channeldll = 0x33333333;
993 break;
994 case 533:
995 channeldll = 0x24242424;
996 break;
997 case 667:
998 channeldll = 0x25252525;
999 break;
1003 for (i = 0; i < 4; i++) {
1004 mchbar_write32(C0R0B00DQST + (i * 0x10) + 0, channeldll);
1005 mchbar_write32(C0R0B00DQST + (i * 0x10) + 4, channeldll);
1006 mchbar_write32(C1R0B00DQST + (i * 0x10) + 0, channeldll);
1007 mchbar_write32(C1R0B00DQST + (i * 0x10) + 4, channeldll);
1008 if (CONFIG(NORTHBRIDGE_INTEL_SUBTYPE_I945GC)) {
1009 mchbar_write8(C0R0B00DQST + (i * 0x10) + 8, channeldll & 0xff);
1010 mchbar_write8(C1R0B00DQST + (i * 0x10) + 8, channeldll & 0xff);
1015 static void sdram_force_rcomp(void)
1017 u32 reg32;
1018 u8 reg8;
1020 reg32 = mchbar_read32(ODTC);
1021 reg32 |= (1 << 28);
1022 mchbar_write32(ODTC, reg32);
1024 reg32 = mchbar_read32(SMSRCTL);
1025 reg32 |= (1 << 0);
1026 mchbar_write32(SMSRCTL, reg32);
1028 /* Start initial RCOMP */
1029 reg32 = mchbar_read32(GBRCOMPCTL);
1030 reg32 |= (1 << 8);
1031 mchbar_write32(GBRCOMPCTL, reg32);
1033 reg8 = i945_silicon_revision();
1034 if ((reg8 == 0 && (mchbar_read32(DCC) & (3 << 0)) == 0) || (reg8 == 1)) {
1035 reg32 = mchbar_read32(GBRCOMPCTL);
1036 reg32 |= (3 << 5);
1037 mchbar_write32(GBRCOMPCTL, reg32);
1041 static void sdram_initialize_system_memory_io(struct sys_info *sysinfo)
1043 u8 reg8;
1044 u32 reg32;
1046 printk(BIOS_DEBUG, "Initializing System Memory IO...\n");
1047 /* Enable Data Half Clock Pushout */
1048 reg8 = mchbar_read8(C0HCTC);
1049 reg8 &= ~0x1f;
1050 reg8 |= (1 << 0);
1051 mchbar_write8(C0HCTC, reg8);
1053 reg8 = mchbar_read8(C1HCTC);
1054 reg8 &= ~0x1f;
1055 reg8 |= (1 << 0);
1056 mchbar_write8(C1HCTC, reg8);
1058 mchbar_clrbits16(WDLLBYPMODE, 1 << 9 | 1 << 6 | 1 << 4 | 1 << 3 | 1 << 1);
1059 mchbar_setbits16(WDLLBYPMODE, 1 << 8 | 1 << 7 | 1 << 5 | 1 << 2 | 1 << 0);
1061 mchbar_write8(C0WDLLCMC, 0);
1062 mchbar_write8(C1WDLLCMC, 0);
1064 /* Program RCOMP Settings */
1065 sdram_program_dram_width(sysinfo);
1067 sdram_rcomp_buffer_strength_and_slew(sysinfo);
1069 /* Indicate that RCOMP programming is done */
1070 reg32 = mchbar_read32(GBRCOMPCTL);
1071 reg32 &= ~((1 << 29) | (1 << 26) | (3 << 21) | (3 << 2));
1072 reg32 |= (3 << 27) | (3 << 0);
1073 mchbar_write32(GBRCOMPCTL, reg32);
1075 mchbar_setbits32(GBRCOMPCTL, 1 << 10);
1077 /* Program DLL Timings */
1078 sdram_program_dll_timings(sysinfo);
1080 /* Force RCOMP cycle */
1081 sdram_force_rcomp();
1084 static void sdram_enable_system_memory_io(struct sys_info *sysinfo)
1086 u32 reg32;
1088 printk(BIOS_DEBUG, "Enabling System Memory IO...\n");
1090 reg32 = mchbar_read32(RCVENMT);
1091 reg32 &= ~(0x3f << 6);
1092 mchbar_write32(RCVENMT, reg32); /* [11:6] = 0 */
1094 reg32 |= (1 << 11) | (1 << 9);
1095 mchbar_write32(RCVENMT, reg32);
1097 reg32 = mchbar_read32(DRTST);
1098 reg32 |= (1 << 3) | (1 << 2);
1099 mchbar_write32(DRTST, reg32);
1101 reg32 = mchbar_read32(DRTST);
1102 reg32 |= (1 << 6) | (1 << 4);
1103 mchbar_write32(DRTST, reg32);
1105 asm volatile ("nop; nop;" ::: "memory");
1107 reg32 = mchbar_read32(DRTST);
1109 /* Is channel 0 populated? */
1110 if (sysinfo->dimm[0] != SYSINFO_DIMM_NOT_POPULATED ||
1111 sysinfo->dimm[1] != SYSINFO_DIMM_NOT_POPULATED)
1112 reg32 |= (1 << 7) | (1 << 5);
1113 else
1114 reg32 |= (1 << 31);
1116 /* Is channel 1 populated? */
1117 if (sysinfo->dimm[2] != SYSINFO_DIMM_NOT_POPULATED ||
1118 sysinfo->dimm[3] != SYSINFO_DIMM_NOT_POPULATED)
1119 reg32 |= (1 << 9) | (1 << 8);
1120 else
1121 reg32 |= (1 << 30);
1123 mchbar_write32(DRTST, reg32);
1125 /* Activate DRAM Channel IO Buffers */
1126 if (sysinfo->dimm[0] != SYSINFO_DIMM_NOT_POPULATED ||
1127 sysinfo->dimm[1] != SYSINFO_DIMM_NOT_POPULATED) {
1128 reg32 = mchbar_read32(C0DRC1);
1129 reg32 |= (1 << 8);
1130 mchbar_write32(C0DRC1, reg32);
1132 if (sysinfo->dimm[2] != SYSINFO_DIMM_NOT_POPULATED ||
1133 sysinfo->dimm[3] != SYSINFO_DIMM_NOT_POPULATED) {
1134 reg32 = mchbar_read32(C1DRC1);
1135 reg32 |= (1 << 8);
1136 mchbar_write32(C1DRC1, reg32);
1140 static int sdram_program_row_boundaries(struct sys_info *sysinfo)
1142 int i;
1143 size_t cum0, cum1, tolud, tom, pci_mmio_size;
1144 const struct device *dev;
1145 const struct northbridge_intel_i945_config *cfg = nullptr;
1147 printk(BIOS_DEBUG, "Setting RAM size...\n");
1149 cum0 = 0;
1150 for (i = 0; i < 2 * DIMM_SOCKETS; i++) {
1151 cum0 += sysinfo->banksize[i];
1152 mchbar_write8(C0DRB0 + i, cum0);
1155 /* Assume we continue in Channel 1 where we stopped in Channel 0 */
1156 cum1 = cum0;
1158 /* Exception: Interleaved starts from the beginning */
1159 if (sysinfo->interleaved)
1160 cum1 = 0;
1162 for (i = 0; i < 2 * DIMM_SOCKETS; i++) {
1163 cum1 += sysinfo->banksize[i + 4];
1164 mchbar_write8(C1DRB0 + i, cum1);
1167 /* Set TOLUD Top Of Low Usable DRAM */
1168 if (sysinfo->interleaved)
1169 tolud = (cum0 + cum1) << 1;
1170 else
1171 tolud = (cum1 ? cum1 : cum0) << 1;
1173 /* The TOM register has a different format */
1174 tom = tolud >> 3;
1176 /* Limit the value of TOLUD to leave some space for PCI memory. */
1177 dev = pcidev_on_root(0, 0);
1178 if (dev)
1179 cfg = dev->chip_info;
1181 /* Don't use pci mmio sizes smaller than 768M */
1182 if (!cfg || cfg->pci_mmio_size <= DEFAULT_PCI_MMIO_SIZE)
1183 pci_mmio_size = DEFAULT_PCI_MMIO_SIZE;
1184 else
1185 pci_mmio_size = cfg->pci_mmio_size;
1187 tolud = MIN(((4096 - pci_mmio_size) / 128) << 3, tolud);
1189 pci_write_config8(HOST_BRIDGE, TOLUD, tolud);
1191 printk(BIOS_DEBUG, "C0DRB = 0x%08x\n", mchbar_read32(C0DRB0));
1192 printk(BIOS_DEBUG, "C1DRB = 0x%08x\n", mchbar_read32(C1DRB0));
1193 printk(BIOS_DEBUG, "TOLUD = 0x%04x\n", pci_read_config8(HOST_BRIDGE, TOLUD));
1195 pci_write_config16(HOST_BRIDGE, TOM, tom);
1197 return 0;
1200 static int sdram_set_row_attributes(struct sys_info *sysinfo)
1202 int i;
1203 u16 dra0 = 0, dra1 = 0, dra = 0;
1205 printk(BIOS_DEBUG, "Setting row attributes...\n");
1206 for (i = 0; i < 2 * DIMM_SOCKETS; i++) {
1207 u8 columnsrows;
1209 if (sysinfo->dimm[i] == SYSINFO_DIMM_NOT_POPULATED)
1210 continue;
1212 columnsrows = (sysinfo->rows[i] & 0x0f) | (sysinfo->cols[i] & 0xf) << 4;
1214 switch (columnsrows) {
1215 case 0x9d:
1216 dra = 2;
1217 break;
1218 case 0xad:
1219 dra = 3;
1220 break;
1221 case 0xbd:
1222 dra = 4;
1223 break;
1224 case 0xae:
1225 dra = 3;
1226 break;
1227 case 0xbe:
1228 dra = 4;
1229 break;
1230 default:
1231 die("Unsupported Rows/Columns. (DRA)");
1234 /* Double Sided DIMMs? */
1235 if (sysinfo->banksize[(2 * i) + 1] != 0)
1236 dra = (dra << 4) | dra;
1238 if (i < DIMM_SOCKETS)
1239 dra0 |= (dra << (i * 8));
1240 else
1241 dra1 |= (dra << ((i - DIMM_SOCKETS) * 8));
1244 mchbar_write16(C0DRA0, dra0);
1245 mchbar_write16(C1DRA0, dra1);
1247 printk(BIOS_DEBUG, "C0DRA = 0x%04x\n", dra0);
1248 printk(BIOS_DEBUG, "C1DRA = 0x%04x\n", dra1);
1250 return 0;
1253 static void sdram_set_bank_architecture(struct sys_info *sysinfo)
1255 u32 off32;
1256 int i;
1258 mchbar_clrbits16(C1BNKARC, 0xff);
1259 mchbar_clrbits16(C0BNKARC, 0xff);
1261 off32 = C0BNKARC;
1262 for (i = 0; i < 2 * DIMM_SOCKETS; i++) {
1263 /* Switch to second channel */
1264 if (i == DIMM_SOCKETS)
1265 off32 = C1BNKARC;
1267 if (sysinfo->dimm[i] == SYSINFO_DIMM_NOT_POPULATED)
1268 continue;
1270 if (sysinfo->banks[i] != 8)
1271 continue;
1273 printk(BIOS_SPEW, "DIMM%d has 8 banks.\n", i);
1275 if (i & 1)
1276 mchbar_setbits16(off32, 5 << 4);
1277 else
1278 mchbar_setbits16(off32, 5 << 0);
1282 static void sdram_program_refresh_rate(struct sys_info *sysinfo)
1284 u32 reg32;
1286 if (sysinfo->refresh == REFRESH_7_8US)
1287 reg32 = (2 << 8); /* Refresh enabled at 7.8us */
1288 else
1289 reg32 = (1 << 8); /* Refresh enabled at 15.6us */
1291 mchbar_clrbits32(C0DRC0, 7 << 8);
1292 mchbar_setbits32(C0DRC0, reg32);
1294 mchbar_clrbits32(C1DRC0, 7 << 8);
1295 mchbar_setbits32(C1DRC0, reg32);
1298 static void sdram_program_cke_tristate(struct sys_info *sysinfo)
1300 u32 reg32;
1301 int i;
1303 reg32 = mchbar_read32(C0DRC1);
1305 for (i = 0; i < 4; i++) {
1306 if (sysinfo->banksize[i] == 0)
1307 reg32 |= (1 << (16 + i));
1310 reg32 |= (1 << 12);
1312 reg32 |= (1 << 11);
1313 mchbar_write32(C0DRC1, reg32);
1315 /* Do we have to do this if we're in Single Channel Mode? */
1316 reg32 = mchbar_read32(C1DRC1);
1318 for (i = 4; i < 8; i++) {
1319 if (sysinfo->banksize[i] == 0)
1320 reg32 |= (1 << (12 + i));
1323 reg32 |= (1 << 12);
1325 reg32 |= (1 << 11);
1326 mchbar_write32(C1DRC1, reg32);
1329 static void sdram_program_odt_tristate(struct sys_info *sysinfo)
1331 u32 reg32;
1332 int i;
1334 reg32 = mchbar_read32(C0DRC2);
1336 for (i = 0; i < 4; i++) {
1337 if (sysinfo->banksize[i] == 0)
1338 reg32 |= (1 << (24 + i));
1340 mchbar_write32(C0DRC2, reg32);
1342 reg32 = mchbar_read32(C1DRC2);
1344 for (i = 4; i < 8; i++) {
1345 if (sysinfo->banksize[i] == 0)
1346 reg32 |= (1 << (20 + i));
1348 mchbar_write32(C1DRC2, reg32);
1351 static void sdram_set_timing_and_control(struct sys_info *sysinfo)
1353 u32 reg32, tRD_min;
1354 u32 tWTR;
1355 u32 temp_drt;
1356 int i, page_size;
1358 static const u8 cas_table[] = {
1359 2, 1, 0, 3
1362 reg32 = mchbar_read32(C0DRC0);
1363 reg32 |= (1 << 2); /* Burst Length 8 */
1364 reg32 &= ~((1 << 13) | (1 << 12));
1365 mchbar_write32(C0DRC0, reg32);
1367 reg32 = mchbar_read32(C1DRC0);
1368 reg32 |= (1 << 2); /* Burst Length 8 */
1369 reg32 &= ~((1 << 13) | (1 << 12));
1370 mchbar_write32(C1DRC0, reg32);
1372 if (!sysinfo->dual_channel && sysinfo->dimm[1] != SYSINFO_DIMM_NOT_POPULATED) {
1373 reg32 = mchbar_read32(C0DRC0);
1374 reg32 |= (1 << 15);
1375 mchbar_write32(C0DRC0, reg32);
1378 sdram_program_refresh_rate(sysinfo);
1380 sdram_program_cke_tristate(sysinfo);
1382 sdram_program_odt_tristate(sysinfo);
1384 /* Calculate DRT0 */
1386 temp_drt = 0;
1388 /* B2B Write Precharge (same bank) = CL-1 + BL/2 + tWR */
1389 reg32 = (sysinfo->cas - 1) + (BURSTLENGTH / 2) + sysinfo->twr;
1390 temp_drt |= (reg32 << 28);
1392 /* Write Auto Precharge (same bank) = CL-1 + BL/2 + tWR + tRP */
1393 reg32 += sysinfo->trp;
1394 temp_drt |= (reg32 << 4);
1396 if (sysinfo->memory_frequency == 667)
1397 tWTR = 3; /* 667MHz */
1398 else
1399 tWTR = 2; /* 400 and 533 */
1401 /* B2B Write to Read Command Spacing */
1402 reg32 = (sysinfo->cas - 1) + (BURSTLENGTH / 2) + tWTR;
1403 temp_drt |= (reg32 << 24);
1405 /* CxDRT0 [23:22], [21:20], [19:18] [16] have fixed values */
1406 temp_drt |= ((1 << 22) | (3 << 20) | (1 << 18) | (0 << 16));
1409 * tRD is the delay the memory controller is waiting on the FSB,
1410 * in mclk domain.
1411 * This parameter is important for stability and performance.
1412 * Those values might not be optimal but seem stable.
1414 tRD_min = sysinfo->cas;
1415 switch (sysinfo->fsb_frequency) {
1416 case 533:
1417 break;
1418 case 667:
1419 tRD_min += 1;
1420 break;
1421 case 800:
1422 tRD_min += 2;
1423 break;
1424 case 1066:
1425 tRD_min += 3;
1426 break;
1429 temp_drt |= (tRD_min << 11);
1431 /* Read Auto Precharge to Activate */
1433 temp_drt |= (8 << 0);
1435 mchbar_write32(C0DRT0, temp_drt);
1436 mchbar_write32(C1DRT0, temp_drt);
1438 /* Calculate DRT1 */
1440 temp_drt = mchbar_read32(C0DRT1) & 0x00020088;
1442 /* DRAM RASB Precharge */
1443 temp_drt |= (sysinfo->trp - 2) << 0;
1445 /* DRAM RASB to CASB Delay */
1446 temp_drt |= (sysinfo->trcd - 2) << 4;
1448 /* CASB Latency */
1449 temp_drt |= (cas_table[sysinfo->cas - 3]) << 8;
1451 /* Refresh Cycle Time */
1452 temp_drt |= (sysinfo->trfc) << 10;
1454 /* Pre-All to Activate Delay */
1455 temp_drt |= (0 << 16);
1457 /* Precharge to Precharge Delay stays at 1 clock */
1458 temp_drt |= (0 << 18);
1460 /* Activate to Precharge Delay */
1461 temp_drt |= (sysinfo->tras << 19);
1463 /* Read to Precharge (tRTP) */
1464 if (sysinfo->memory_frequency == 667)
1465 temp_drt |= (1 << 28);
1466 else
1467 temp_drt |= (0 << 28);
1469 /* Determine page size */
1470 reg32 = 0;
1471 page_size = 1; /* Default: 1k pagesize */
1472 for (i = 0; i < 2*DIMM_SOCKETS; i++) {
1473 if (sysinfo->dimm[i] == SYSINFO_DIMM_X16DS ||
1474 sysinfo->dimm[i] == SYSINFO_DIMM_X16SS)
1475 page_size = 2; /* 2k pagesize */
1478 if (sysinfo->memory_frequency == 533 && page_size == 2)
1479 reg32 = 1;
1480 if (sysinfo->memory_frequency == 667)
1481 reg32 = page_size;
1483 temp_drt |= (reg32 << 30);
1485 mchbar_write32(C0DRT1, temp_drt);
1486 mchbar_write32(C1DRT1, temp_drt);
1488 /* Program DRT2 */
1489 reg32 = mchbar_read32(C0DRT2);
1490 reg32 &= ~(1 << 8);
1491 mchbar_write32(C0DRT2, reg32);
1493 reg32 = mchbar_read32(C1DRT2);
1494 reg32 &= ~(1 << 8);
1495 mchbar_write32(C1DRT2, reg32);
1497 /* Calculate DRT3 */
1498 temp_drt = mchbar_read32(C0DRT3) & ~0x07ffffff;
1500 /* Get old tRFC value */
1501 reg32 = mchbar_read32(C0DRT1) >> 10;
1502 reg32 &= 0x3f;
1504 /* 788nS - tRFC */
1505 switch (sysinfo->memory_frequency) {
1506 case 400: /* 5nS */
1507 reg32 = ((78800 / 500) - reg32) & 0x1ff;
1508 reg32 |= (0x8c << 16) | (0x0c << 10); /* 1 us */
1509 break;
1510 case 533: /* 3.75nS */
1511 reg32 = ((78800 / 375) - reg32) & 0x1ff;
1512 reg32 |= (0xba << 16) | (0x10 << 10); /* 1 us */
1513 break;
1514 case 667: /* 3nS */
1515 reg32 = ((78800 / 300) - reg32) & 0x1ff;
1516 reg32 |= (0xe9 << 16) | (0x14 << 10); /* 1 us */
1517 break;
1520 temp_drt |= reg32;
1522 mchbar_write32(C0DRT3, temp_drt);
1523 mchbar_write32(C1DRT3, temp_drt);
1526 static void sdram_set_channel_mode(struct sys_info *sysinfo)
1528 u32 reg32;
1530 printk(BIOS_DEBUG, "Setting mode of operation for memory channels...");
1532 if (sdram_capabilities_interleave() &&
1533 ((sysinfo->banksize[0] + sysinfo->banksize[1] +
1534 sysinfo->banksize[2] + sysinfo->banksize[3]) ==
1535 (sysinfo->banksize[4] + sysinfo->banksize[5] +
1536 sysinfo->banksize[6] + sysinfo->banksize[7]))) {
1537 /* Both channels equipped with DIMMs of the same size */
1538 sysinfo->interleaved = true;
1539 } else {
1540 sysinfo->interleaved = false;
1543 reg32 = mchbar_read32(DCC);
1544 reg32 &= ~(7 << 0);
1546 if (sysinfo->interleaved) {
1547 /* Dual Channel Interleaved */
1548 printk(BIOS_DEBUG, "Dual Channel Interleaved.\n");
1549 reg32 |= (1 << 1);
1550 } else if (sysinfo->dimm[0] == SYSINFO_DIMM_NOT_POPULATED &&
1551 sysinfo->dimm[1] == SYSINFO_DIMM_NOT_POPULATED) {
1552 /* Channel 1 only */
1553 printk(BIOS_DEBUG, "Single Channel 1 only.\n");
1554 reg32 |= (1 << 2);
1555 } else if (sdram_capabilities_dual_channel() &&
1556 (sysinfo->dimm[2] != SYSINFO_DIMM_NOT_POPULATED ||
1557 sysinfo->dimm[3] != SYSINFO_DIMM_NOT_POPULATED)) {
1558 /* Dual Channel Asymmetric */
1559 printk(BIOS_DEBUG, "Dual Channel Asymmetric.\n");
1560 reg32 |= (1 << 0);
1561 } else {
1562 /* All bits 0 means Single Channel 0 operation */
1563 printk(BIOS_DEBUG, "Single Channel 0 only.\n");
1566 /* Now disable channel XORing */
1567 reg32 |= (1 << 10);
1569 mchbar_write32(DCC, reg32);
1571 PRINTK_DEBUG("DCC = 0x%08x\n", mchbar_read32(DCC));
1574 static void sdram_program_pll_settings(struct sys_info *sysinfo)
1576 mchbar_write32(PLLMON, 0x80800000);
1578 sysinfo->fsb_frequency = fsbclk();
1579 if (sysinfo->fsb_frequency == 0xffff)
1580 die("Unsupported FSB speed");
1582 /* Program CPCTL according to FSB speed */
1583 /* Only write the lower byte */
1584 switch (sysinfo->fsb_frequency) {
1585 case 400:
1586 mchbar_write8(CPCTL, 0x90);
1587 break;
1588 case 533:
1589 mchbar_write8(CPCTL, 0x95);
1590 break;
1591 case 667:
1592 mchbar_write8(CPCTL, 0x8d);
1593 break;
1596 mchbar_clrbits16(CPCTL, 1 << 11);
1598 mchbar_read16(CPCTL); /* Read back register to activate settings */
1601 static void sdram_program_graphics_frequency(struct sys_info *sysinfo)
1603 u8 reg8;
1604 u8 freq, voltage;
1605 bool second_vco = false;
1607 #define CRCLK_166MHz 0x00
1608 #define CRCLK_200MHz 0x01
1609 #define CRCLK_250MHz 0x03
1610 #define CRCLK_400MHz 0x05
1612 #define CDCLK_200MHz 0x00
1613 #define CDCLK_320MHz 0x40
1615 #define VOLTAGE_1_05 0x00
1616 #define VOLTAGE_1_50 0x01
1618 printk(BIOS_DEBUG, "Setting Graphics Frequency...\n");
1620 printk(BIOS_DEBUG, "FSB: %d MHz ", sysinfo->fsb_frequency);
1622 voltage = VOLTAGE_1_05;
1623 if (mchbar_read32(DFT_STRAP1) & (1 << 20))
1624 voltage = VOLTAGE_1_50;
1625 printk(BIOS_DEBUG, "Voltage: %s ", (voltage == VOLTAGE_1_05) ? "1.05V" : "1.5V");
1627 /* Gate graphics hardware for frequency change */
1628 reg8 = (1 << 3) | (1 << 1); /* disable crclk, gate cdclk */
1629 pci_write_config8(IGD_DEV, GCFC + 1, reg8);
1631 /* Get graphics frequency capabilities */
1632 reg8 = sdram_capabilities_core_frequencies();
1634 freq = CRCLK_250MHz;
1635 switch (reg8) {
1636 case GFX_FREQUENCY_CAP_ALL:
1637 if (voltage == VOLTAGE_1_05)
1638 freq = CRCLK_250MHz;
1639 else
1640 freq = CRCLK_400MHz; /* 1.5V requires 400MHz */
1641 break;
1642 case GFX_FREQUENCY_CAP_250MHZ:
1643 freq = CRCLK_250MHz;
1644 break;
1645 case GFX_FREQUENCY_CAP_200MHZ:
1646 freq = CRCLK_200MHz;
1647 break;
1648 case GFX_FREQUENCY_CAP_166MHZ:
1649 freq = CRCLK_166MHz;
1650 break;
1653 if (freq != CRCLK_400MHz) {
1654 /* What chipset are we? Force 166MHz for GMS */
1655 reg8 = (pci_read_config8(HOST_BRIDGE, 0xe7) & 0x70) >> 4;
1656 if (reg8 == 2)
1657 freq = CRCLK_166MHz;
1660 printk(BIOS_DEBUG, "Render: ");
1661 switch (freq) {
1662 case CRCLK_166MHz:
1663 printk(BIOS_DEBUG, "166MHz");
1664 break;
1665 case CRCLK_200MHz:
1666 printk(BIOS_DEBUG, "200MHz");
1667 break;
1668 case CRCLK_250MHz:
1669 printk(BIOS_DEBUG, "250MHz");
1670 break;
1671 case CRCLK_400MHz:
1672 printk(BIOS_DEBUG, "400MHz");
1673 break;
1676 if (i945_silicon_revision() == 0)
1677 sysinfo->mvco4x = 1;
1678 else
1679 sysinfo->mvco4x = 0;
1681 if (voltage == VOLTAGE_1_50) {
1682 second_vco = true;
1683 } else if ((i945_silicon_revision() > 0) && (freq == CRCLK_250MHz)) {
1684 u16 mem = sysinfo->memory_frequency;
1685 u16 fsb = sysinfo->fsb_frequency;
1687 if ((fsb == 667 && mem == 533) ||
1688 (fsb == 533 && mem == 533) ||
1689 (fsb == 533 && mem == 400)) {
1690 second_vco = true;
1693 if (fsb == 667 && mem == 533)
1694 sysinfo->mvco4x = 1;
1697 sysinfo->clkcfg_bit7 = second_vco;
1699 /* Graphics Core Render Clock */
1700 pci_update_config16(IGD_DEV, GCFC, ~((7 << 0) | (1 << 13)), freq);
1702 /* Graphics Core Display Clock */
1703 reg8 = pci_read_config8(IGD_DEV, GCFC);
1704 reg8 &= ~((1 << 7) | (7 << 4));
1706 if (voltage == VOLTAGE_1_05) {
1707 reg8 |= CDCLK_200MHz;
1708 printk(BIOS_DEBUG, " Display: 200MHz\n");
1709 } else {
1710 reg8 |= CDCLK_320MHz;
1711 printk(BIOS_DEBUG, " Display: 320MHz\n");
1713 pci_write_config8(IGD_DEV, GCFC, reg8);
1715 reg8 = pci_read_config8(IGD_DEV, GCFC + 1);
1717 reg8 |= (1 << 3) | (1 << 1);
1718 pci_write_config8(IGD_DEV, GCFC + 1, reg8);
1720 reg8 |= 0x0f;
1721 pci_write_config8(IGD_DEV, GCFC + 1, reg8);
1723 /* Ungate core render and display clocks */
1724 reg8 &= 0xf0;
1725 pci_write_config8(IGD_DEV, GCFC + 1, reg8);
1728 static void sdram_program_memory_frequency(struct sys_info *sysinfo)
1730 u32 clkcfg;
1731 u8 offset = CONFIG(NORTHBRIDGE_INTEL_SUBTYPE_I945GM) ? 1 : 0;
1733 printk(BIOS_DEBUG, "Setting Memory Frequency... ");
1735 clkcfg = mchbar_read32(CLKCFG);
1737 printk(BIOS_DEBUG, "CLKCFG = 0x%08x, ", clkcfg);
1739 clkcfg &= ~((1 << 12) | (1 << 7) | (7 << 4));
1741 if (sysinfo->mvco4x) {
1742 printk(BIOS_DEBUG, "MVCO 4x, ");
1743 clkcfg &= ~(1 << 12);
1746 if (sysinfo->clkcfg_bit7) {
1747 printk(BIOS_DEBUG, "second VCO, ");
1748 clkcfg |= (1 << 7);
1751 switch (sysinfo->memory_frequency) {
1752 case 400:
1753 clkcfg |= ((1 + offset) << 4);
1754 break;
1755 case 533:
1756 clkcfg |= ((2 + offset) << 4);
1757 break;
1758 case 667:
1759 clkcfg |= ((3 + offset) << 4);
1760 break;
1761 default:
1762 die("Target Memory Frequency Error");
1765 if (mchbar_read32(CLKCFG) == clkcfg) {
1766 printk(BIOS_DEBUG, "ok (unchanged)\n");
1767 return;
1770 mchbar_write32(CLKCFG, clkcfg);
1773 * Make sure the following code is in the cache before we execute it.
1774 * TODO: Experiments (i945GM) without any cache_code/delay_update
1775 * _seem_ to work even when XIP is disabled. Also on Pentium 4
1776 * the code is not cached at all by default.
1778 asm volatile (
1779 " jmp cache_code\n"
1780 "vco_update:\n"
1781 : /* No outputs */
1782 : /* No inputs */
1783 : "memory"
1786 pci_and_config8(PCI_DEV(0, 0x1f, 0), GEN_PMCON_2, (u8)~(1 << 7));
1788 clkcfg &= ~(1 << 10);
1789 mchbar_write32(CLKCFG, clkcfg);
1790 clkcfg |= (1 << 10);
1791 mchbar_write32(CLKCFG, clkcfg);
1793 asm volatile (
1794 " movl $0x100, %%ecx\n"
1795 "delay_update:\n"
1796 " nop\n"
1797 " nop\n"
1798 " nop\n"
1799 " nop\n"
1800 " loop delay_update\n"
1801 : /* No outputs */
1802 : /* No inputs */
1803 : "%ecx", "memory"
1806 clkcfg &= ~(1 << 10);
1807 mchbar_write32(CLKCFG, clkcfg);
1809 asm volatile (
1810 " jmp out\n"
1811 "cache_code:\n"
1812 " jmp vco_update\n"
1813 "out:\n"
1814 : /* No outputs */
1815 : /* No inputs */
1816 : "memory"
1819 printk(BIOS_DEBUG, "CLKCFG = 0x%08x, ", mchbar_read32(CLKCFG));
1820 printk(BIOS_DEBUG, "ok\n");
1823 static void sdram_program_clock_crossing(void)
1825 int idx = 0;
1828 * We add the indices according to our clocks from CLKCFG.
1830 #if CONFIG(NORTHBRIDGE_INTEL_SUBTYPE_I945GM)
1831 static const u32 data_clock_crossing[] = {
1832 0x00100401, 0x00000000, /* DDR400 FSB400 */
1833 0xffffffff, 0xffffffff, /* nonexistent */
1834 0xffffffff, 0xffffffff, /* nonexistent */
1836 0x08040120, 0x00000000, /* DDR400 FSB533 */
1837 0x00100401, 0x00000000, /* DDR533 FSB533 */
1838 0x00010402, 0x00000000, /* DDR667 FSB533 - fake values */
1840 0x04020120, 0x00000010, /* DDR400 FSB667 */
1841 0x10040280, 0x00000040, /* DDR533 FSB667 */
1842 0x00100401, 0x00000000, /* DDR667 FSB667 */
1844 0xffffffff, 0xffffffff, /* nonexistent */
1845 0xffffffff, 0xffffffff, /* nonexistent */
1846 0xffffffff, 0xffffffff, /* nonexistent */
1848 0xffffffff, 0xffffffff, /* nonexistent */
1849 0xffffffff, 0xffffffff, /* nonexistent */
1850 0xffffffff, 0xffffffff, /* nonexistent */
1853 static const u32 command_clock_crossing[] = {
1854 0x04020208, 0x00000000, /* DDR400 FSB400 */
1855 0xffffffff, 0xffffffff, /* nonexistent */
1856 0xffffffff, 0xffffffff, /* nonexistent */
1858 0x00060108, 0x00000000, /* DDR400 FSB533 */
1859 0x04020108, 0x00000000, /* DDR533 FSB533 */
1860 0xffffffff, 0xffffffff, /* nonexistent */
1862 0x00040318, 0x00000000, /* DDR400 FSB667 */
1863 0x04020118, 0x00000000, /* DDR533 FSB667 */
1864 0x02010804, 0x00000000, /* DDR667 FSB667 */
1866 0xffffffff, 0xffffffff, /* nonexistent */
1867 0xffffffff, 0xffffffff, /* nonexistent */
1868 0xffffffff, 0xffffffff, /* nonexistent */
1870 0xffffffff, 0xffffffff, /* nonexistent */
1871 0xffffffff, 0xffffffff, /* nonexistent */
1872 0xffffffff, 0xffffffff, /* nonexistent */
1875 #elif CONFIG(NORTHBRIDGE_INTEL_SUBTYPE_I945GC)
1876 /* i945 G/P */
1877 static const u32 data_clock_crossing[] = {
1878 0xffffffff, 0xffffffff, /* nonexistent */
1879 0xffffffff, 0xffffffff, /* nonexistent */
1880 0xffffffff, 0xffffffff, /* nonexistent */
1882 0x10080201, 0x00000000, /* DDR400 FSB533 */
1883 0x00100401, 0x00000000, /* DDR533 FSB533 */
1884 0x00010402, 0x00000000, /* DDR667 FSB533 - fake values */
1886 0xffffffff, 0xffffffff, /* nonexistent */
1887 0xffffffff, 0xffffffff, /* nonexistent */
1888 0xffffffff, 0xffffffff, /* nonexistent */
1890 0x04020108, 0x00000000, /* DDR400 FSB800 */
1891 0x00020108, 0x00000000, /* DDR533 FSB800 */
1892 0x00080201, 0x00000000, /* DDR667 FSB800 */
1894 0x00010402, 0x00000000, /* DDR400 FSB1066 */
1895 0x04020108, 0x00000000, /* DDR533 FSB1066 */
1896 0x08040110, 0x00000000, /* DDR667 FSB1066 */
1899 static const u32 command_clock_crossing[] = {
1900 0xffffffff, 0xffffffff, /* nonexistent */
1901 0xffffffff, 0xffffffff, /* nonexistent */
1902 0xffffffff, 0xffffffff, /* nonexistent */
1904 0x00010800, 0x00000402, /* DDR400 FSB533 */
1905 0x01000400, 0x00000200, /* DDR533 FSB533 */
1906 0x00020904, 0x00000000, /* DDR667 FSB533 - fake values */
1908 0xffffffff, 0xffffffff, /* nonexistent */
1909 0xffffffff, 0xffffffff, /* nonexistent */
1910 0xffffffff, 0xffffffff, /* nonexistent */
1912 0x02010804, 0x00000000, /* DDR400 FSB800 */
1913 0x00010402, 0x00000000, /* DDR533 FSB800 */
1914 0x04020130, 0x00000008, /* DDR667 FSB800 */
1916 0x00020904, 0x00000000, /* DDR400 FSB1066 */
1917 0x02010804, 0x00000000, /* DDR533 FSB1066 */
1918 0x180601c0, 0x00000020, /* DDR667 FSB1066 */
1920 #endif
1922 printk(BIOS_DEBUG, "Programming Clock Crossing...");
1924 printk(BIOS_DEBUG, "MEM=");
1925 switch (memclk()) {
1926 case 400:
1927 printk(BIOS_DEBUG, "400");
1928 idx += 0;
1929 break;
1930 case 533:
1931 printk(BIOS_DEBUG, "533");
1932 idx += 2;
1933 break;
1934 case 667:
1935 printk(BIOS_DEBUG, "667");
1936 idx += 4;
1937 break;
1938 default:
1939 printk(BIOS_DEBUG, "RSVD %x", memclk());
1940 return;
1943 printk(BIOS_DEBUG, " FSB=");
1944 switch (fsbclk()) {
1945 case 400:
1946 printk(BIOS_DEBUG, "400");
1947 idx += 0;
1948 break;
1949 case 533:
1950 printk(BIOS_DEBUG, "533");
1951 idx += 6;
1952 break;
1953 case 667:
1954 printk(BIOS_DEBUG, "667");
1955 idx += 12;
1956 break;
1957 case 800:
1958 printk(BIOS_DEBUG, "800");
1959 idx += 18;
1960 break;
1961 case 1066:
1962 printk(BIOS_DEBUG, "1066");
1963 idx += 24;
1964 break;
1965 default:
1966 printk(BIOS_DEBUG, "RSVD %x\n", fsbclk());
1967 return;
1970 if (command_clock_crossing[idx] == 0xffffffff)
1971 printk(BIOS_DEBUG, "Invalid MEM/FSB combination!\n");
1973 mchbar_write32(CCCFT + 0, command_clock_crossing[idx]);
1974 mchbar_write32(CCCFT + 4, command_clock_crossing[idx + 1]);
1976 mchbar_write32(C0DCCFT + 0, data_clock_crossing[idx]);
1977 mchbar_write32(C0DCCFT + 4, data_clock_crossing[idx + 1]);
1978 mchbar_write32(C1DCCFT + 0, data_clock_crossing[idx]);
1979 mchbar_write32(C1DCCFT + 4, data_clock_crossing[idx + 1]);
1981 printk(BIOS_DEBUG, "... ok\n");
1984 static void sdram_disable_fast_dispatch(void)
1986 u32 reg32;
1988 reg32 = mchbar_read32(FSBPMC3);
1989 reg32 |= (1 << 1);
1990 mchbar_write32(FSBPMC3, reg32);
1992 reg32 = mchbar_read32(SBTEST);
1993 reg32 |= (3 << 1);
1994 mchbar_write32(SBTEST, reg32);
1997 static void sdram_pre_jedec_initialization(void)
1999 u32 reg32;
2001 reg32 = mchbar_read32(WCC);
2002 reg32 &= 0x113ff3ff;
2003 reg32 |= (4 << 29) | (3 << 25) | (1 << 10);
2004 mchbar_write32(WCC, reg32);
2006 mchbar_setbits32(SMVREFC, 1 << 6);
2008 mchbar_clrbits32(MMARB0, 3 << 17);
2009 mchbar_setbits32(MMARB0, 1 << 21 | 1 << 16);
2011 mchbar_clrbits32(MMARB1, 7 << 8);
2012 mchbar_setbits32(MMARB1, 3 << 8);
2014 /* Adaptive Idle Timer Control */
2015 mchbar_write32(C0AIT + 0, 0x000006c4);
2016 mchbar_write32(C0AIT + 4, 0x871a066d);
2018 mchbar_write32(C1AIT + 0, 0x000006c4);
2019 mchbar_write32(C1AIT + 4, 0x871a066d);
2022 #define EA_DUALCHANNEL_XOR_BANK_RANK_MODE (0xd4 << 24)
2023 #define EA_DUALCHANNEL_XOR_BANK_MODE (0xf4 << 24)
2024 #define EA_DUALCHANNEL_BANK_RANK_MODE (0xc2 << 24)
2025 #define EA_DUALCHANNEL_BANK_MODE (0xe2 << 24)
2026 #define EA_SINGLECHANNEL_XOR_BANK_RANK_MODE (0x91 << 24)
2027 #define EA_SINGLECHANNEL_XOR_BANK_MODE (0xb1 << 24)
2028 #define EA_SINGLECHANNEL_BANK_RANK_MODE (0x80 << 24)
2029 #define EA_SINGLECHANNEL_BANK_MODE (0xa0 << 24)
2031 static void sdram_enhanced_addressing_mode(struct sys_info *sysinfo)
2033 u32 chan0 = 0, chan1 = 0;
2034 bool chan0_dualsided, chan1_dualsided, chan0_populated, chan1_populated;
2036 chan0_populated = (sysinfo->dimm[0] != SYSINFO_DIMM_NOT_POPULATED ||
2037 sysinfo->dimm[1] != SYSINFO_DIMM_NOT_POPULATED);
2038 chan1_populated = (sysinfo->dimm[2] != SYSINFO_DIMM_NOT_POPULATED ||
2039 sysinfo->dimm[3] != SYSINFO_DIMM_NOT_POPULATED);
2040 chan0_dualsided = (sysinfo->banksize[1] || sysinfo->banksize[3]);
2041 chan1_dualsided = (sysinfo->banksize[5] || sysinfo->banksize[7]);
2043 if (sdram_capabilities_enhanced_addressing_xor()) {
2044 if (!sysinfo->interleaved) {
2045 /* Single Channel & Dual Channel Asymmetric */
2046 if (chan0_populated) {
2047 if (chan0_dualsided)
2048 chan0 = EA_SINGLECHANNEL_XOR_BANK_RANK_MODE;
2049 else
2050 chan0 = EA_SINGLECHANNEL_XOR_BANK_MODE;
2052 if (chan1_populated) {
2053 if (chan1_dualsided)
2054 chan1 = EA_SINGLECHANNEL_XOR_BANK_RANK_MODE;
2055 else
2056 chan1 = EA_SINGLECHANNEL_XOR_BANK_MODE;
2058 } else {
2059 /* Interleaved has always both channels populated */
2060 if (chan0_dualsided)
2061 chan0 = EA_DUALCHANNEL_XOR_BANK_RANK_MODE;
2062 else
2063 chan0 = EA_DUALCHANNEL_XOR_BANK_MODE;
2065 if (chan1_dualsided)
2066 chan1 = EA_DUALCHANNEL_XOR_BANK_RANK_MODE;
2067 else
2068 chan1 = EA_DUALCHANNEL_XOR_BANK_MODE;
2070 } else {
2071 if (!sysinfo->interleaved) {
2072 /* Single Channel & Dual Channel Asymmetric */
2073 if (chan0_populated) {
2074 if (chan0_dualsided)
2075 chan0 = EA_SINGLECHANNEL_BANK_RANK_MODE;
2076 else
2077 chan0 = EA_SINGLECHANNEL_BANK_MODE;
2079 if (chan1_populated) {
2080 if (chan1_dualsided)
2081 chan1 = EA_SINGLECHANNEL_BANK_RANK_MODE;
2082 else
2083 chan1 = EA_SINGLECHANNEL_BANK_MODE;
2085 } else {
2086 /* Interleaved has always both channels populated */
2087 if (chan0_dualsided)
2088 chan0 = EA_DUALCHANNEL_BANK_RANK_MODE;
2089 else
2090 chan0 = EA_DUALCHANNEL_BANK_MODE;
2092 if (chan1_dualsided)
2093 chan1 = EA_DUALCHANNEL_BANK_RANK_MODE;
2094 else
2095 chan1 = EA_DUALCHANNEL_BANK_MODE;
2099 mchbar_clrbits32(C0DRC1, 0xff << 24);
2100 mchbar_setbits32(C0DRC1, chan0);
2101 mchbar_clrbits32(C1DRC1, 0xff << 24);
2102 mchbar_setbits32(C1DRC1, chan1);
2105 static void sdram_post_jedec_initialization(struct sys_info *sysinfo)
2107 u32 reg32;
2109 /* Enable Channel XORing for Dual Channel Interleave */
2110 if (sysinfo->interleaved) {
2111 reg32 = mchbar_read32(DCC);
2112 reg32 &= ~(1 << 10);
2113 reg32 |= (1 << 9);
2114 mchbar_write32(DCC, reg32);
2117 /* DRAM mode optimizations */
2118 sdram_enhanced_addressing_mode(sysinfo);
2120 reg32 = mchbar_read32(FSBPMC3);
2121 reg32 &= ~(1 << 1);
2122 mchbar_write32(FSBPMC3, reg32);
2124 reg32 = mchbar_read32(SBTEST);
2125 reg32 &= ~(1 << 2);
2126 mchbar_write32(SBTEST, reg32);
2128 reg32 = mchbar_read32(SBOCC);
2129 reg32 &= 0xffbdb6ff;
2130 reg32 |= (0xbdb6 << 8) | (1 << 0);
2131 mchbar_write32(SBOCC, reg32);
2134 static void sdram_power_management(struct sys_info *sysinfo)
2136 u16 reg16;
2137 u32 reg32;
2138 bool integrated_graphics = true;
2139 int i;
2141 if (!(pci_read_config8(HOST_BRIDGE, DEVEN) & (DEVEN_D2F0 | DEVEN_D2F1)))
2142 integrated_graphics = false;
2144 reg32 = mchbar_read32(C0DRT2);
2145 reg32 &= 0xffffff00;
2146 /* Idle timer = 8 clocks, CKE idle timer = 16 clocks */
2147 reg32 |= (1 << 5) | (1 << 4);
2148 mchbar_write32(C0DRT2, reg32);
2150 reg32 = mchbar_read32(C1DRT2);
2151 reg32 &= 0xffffff00;
2152 /* Idle timer = 8 clocks, CKE idle timer = 16 clocks */
2153 reg32 |= (1 << 5) | (1 << 4);
2154 mchbar_write32(C1DRT2, reg32);
2156 reg32 = mchbar_read32(C0DRC1);
2158 reg32 |= (1 << 12) | (1 << 11);
2159 mchbar_write32(C0DRC1, reg32);
2161 reg32 = mchbar_read32(C1DRC1);
2163 reg32 |= (1 << 12) | (1 << 11);
2164 mchbar_write32(C1DRC1, reg32);
2166 if (CONFIG(NORTHBRIDGE_INTEL_SUBTYPE_I945GM)) {
2167 if (i945_silicon_revision() > 1) {
2168 /* FIXME bits 5 and 0 only if PCIe graphics is disabled */
2169 u16 peg_bits = (1 << 5) | (1 << 0);
2171 mchbar_write16(UPMC1, 0x1010 | peg_bits);
2172 } else {
2173 /* FIXME bits 5 and 0 only if PCIe graphics is disabled */
2174 u16 peg_bits = (1 << 5) | (1 << 0);
2176 /* Rev 0 and 1 */
2177 mchbar_write16(UPMC1, 0x0010 | peg_bits);
2181 reg16 = mchbar_read16(UPMC2);
2182 reg16 &= 0xfc00;
2183 reg16 |= 0x0100;
2184 mchbar_write16(UPMC2, reg16);
2186 mchbar_write32(UPMC3, 0x000f06ff);
2188 for (i = 0; i < 5; i++) {
2189 mchbar_clrbits32(UPMC3, 1 << 16);
2190 mchbar_setbits32(UPMC3, 1 << 16);
2193 mchbar_write32(GIPMC1, 0x8000000c);
2195 reg16 = mchbar_read16(CPCTL);
2196 reg16 &= ~(7 << 11);
2197 if (i945_silicon_revision() > 2)
2198 reg16 |= (6 << 11);
2199 else
2200 reg16 |= (4 << 11);
2201 mchbar_write16(CPCTL, reg16);
2203 #if 0
2204 if ((mchbar_read32(ECO) & (1 << 16)) != 0) {
2205 #else
2206 if (i945_silicon_revision() != 0) {
2207 #endif
2208 switch (sysinfo->fsb_frequency) {
2209 case 667:
2210 mchbar_write32(HGIPMC2, 0x0d590d59);
2211 break;
2212 case 533:
2213 mchbar_write32(HGIPMC2, 0x155b155b);
2214 break;
2216 } else {
2217 switch (sysinfo->fsb_frequency) {
2218 case 667:
2219 mchbar_write32(HGIPMC2, 0x09c409c4);
2220 break;
2221 case 533:
2222 mchbar_write32(HGIPMC2, 0x0fa00fa0);
2223 break;
2227 mchbar_write32(FSBPMC1, 0x8000000c);
2229 reg32 = mchbar_read32(C2C3TT);
2230 reg32 &= 0xffff0000;
2231 switch (sysinfo->fsb_frequency) {
2232 case 667:
2233 reg32 |= 0x0600;
2234 break;
2235 case 533:
2236 reg32 |= 0x0480;
2237 break;
2239 mchbar_write32(C2C3TT, reg32);
2241 reg32 = mchbar_read32(C3C4TT);
2242 reg32 &= 0xffff0000;
2243 switch (sysinfo->fsb_frequency) {
2244 case 667:
2245 reg32 |= 0x0b80;
2246 break;
2247 case 533:
2248 reg32 |= 0x0980;
2249 break;
2251 mchbar_write32(C3C4TT, reg32);
2253 if (i945_silicon_revision() == 0)
2254 mchbar_clrbits32(ECO, 1 << 16);
2255 else
2256 mchbar_setbits32(ECO, 1 << 16);
2258 mchbar_clrbits32(FSBPMC3, 1 << 29);
2260 mchbar_setbits32(FSBPMC3, 1 << 21);
2262 mchbar_clrbits32(FSBPMC3, 1 << 19);
2264 mchbar_clrbits32(FSBPMC3, 1 << 13);
2266 reg32 = mchbar_read32(FSBPMC4);
2267 reg32 &= ~(3 << 24);
2268 reg32 |= (2 << 24);
2269 mchbar_write32(FSBPMC4, reg32);
2271 mchbar_setbits32(FSBPMC4, 1 << 21);
2273 mchbar_setbits32(FSBPMC4, 1 << 5);
2275 if ((i945_silicon_revision() < 2)) { /* || cpuid() = 0x6e8 */
2276 /* stepping 0 and 1 or CPUID 6e8 */
2277 mchbar_clrbits32(FSBPMC4, 1 << 4);
2278 } else {
2279 mchbar_setbits32(FSBPMC4, 1 << 4);
2282 pci_or_config8(HOST_BRIDGE, 0xfc, 1 << 4);
2284 pci_or_config8(IGD_DEV, 0xc1, 1 << 2);
2286 if (integrated_graphics) {
2287 mchbar_write16(MIPMC4, 0x04f8);
2288 mchbar_write16(MIPMC5, 0x04fc);
2289 mchbar_write16(MIPMC6, 0x04fc);
2290 } else {
2291 mchbar_write16(MIPMC4, 0x64f8);
2292 mchbar_write16(MIPMC5, 0x64fc);
2293 mchbar_write16(MIPMC6, 0x64fc);
2296 reg32 = mchbar_read32(PMCFG);
2297 reg32 &= ~(3 << 17);
2298 reg32 |= (2 << 17);
2299 mchbar_write32(PMCFG, reg32);
2301 mchbar_setbits32(PMCFG, 1 << 4);
2303 reg32 = mchbar_read32(UPMC4);
2304 reg32 &= 0xffffff00;
2305 reg32 |= 0x01;
2306 mchbar_write32(UPMC4, reg32);
2308 mchbar_clrbits32(0xb18, 1 << 21);
2311 static void sdram_thermal_management(void)
2313 mchbar_write8(TCO1, 0);
2314 mchbar_write8(TCO0, 0);
2316 /* The Thermal Sensors for DIMMs at 0x50, 0x52 are at I2C addr 0x30/0x32. */
2318 /* TODO This is not implemented yet. Volunteers? */
2321 static void sdram_save_receive_enable(void)
2323 int i;
2324 u32 reg32;
2325 u8 values[4];
2327 /* The following values are stored to an unused CMOS area and restored instead of
2328 * recalculated in case of an S3 resume.
2330 * C0WL0REOST [7:0] -> 8 bit
2331 * C1WL0REOST [7:0] -> 8 bit
2332 * RCVENMT [11:8] [3:0] -> 8 bit
2333 * C0DRT1 [27:24] -> 4 bit
2334 * C1DRT1 [27:24] -> 4 bit
2337 values[0] = mchbar_read8(C0WL0REOST);
2338 values[1] = mchbar_read8(C1WL0REOST);
2340 reg32 = mchbar_read32(RCVENMT);
2341 values[2] = (u8)((reg32 >> (8 - 4)) & 0xf0) | (reg32 & 0x0f);
2343 reg32 = mchbar_read32(C0DRT1);
2344 values[3] = (reg32 >> 24) & 0x0f;
2345 reg32 = mchbar_read32(C1DRT1);
2346 values[3] |= (reg32 >> (24 - 4)) & 0xf0;
2348 /* coreboot only uses bytes 0 - 127 for its CMOS values so far
2349 * so we grab bytes 128 - 131 to save the receive enable values
2352 for (i = 0; i < 4; i++)
2353 cmos_write(values[i], 128 + i);
2356 static void sdram_recover_receive_enable(void)
2358 int i;
2359 u32 reg32;
2360 u8 values[4];
2362 for (i = 0; i < 4; i++)
2363 values[i] = cmos_read(128 + i);
2365 mchbar_write8(C0WL0REOST, values[0]);
2366 mchbar_write8(C1WL0REOST, values[1]);
2368 reg32 = mchbar_read32(RCVENMT);
2369 reg32 &= ~((0x0f << 8) | (0x0f << 0));
2370 reg32 |= ((u32)(values[2] & 0xf0) << (8 - 4)) | (values[2] & 0x0f);
2371 mchbar_write32(RCVENMT, reg32);
2373 reg32 = mchbar_read32(C0DRT1) & ~(0x0f << 24);
2374 reg32 |= (u32)(values[3] & 0x0f) << 24;
2375 mchbar_write32(C0DRT1, reg32);
2377 reg32 = mchbar_read32(C1DRT1) & ~(0x0f << 24);
2378 reg32 |= (u32)(values[3] & 0xf0) << (24 - 4);
2379 mchbar_write32(C1DRT1, reg32);
2382 static void sdram_program_receive_enable(struct sys_info *sysinfo)
2384 mchbar_setbits32(REPC, 1 << 0);
2386 /* Program Receive Enable Timings */
2387 if (sysinfo->boot_path == BOOT_PATH_RESUME) {
2388 sdram_recover_receive_enable();
2389 } else {
2390 receive_enable_adjust(sysinfo);
2391 sdram_save_receive_enable();
2394 mchbar_setbits32(C0DRC1, 1 << 6);
2395 mchbar_setbits32(C1DRC1, 1 << 6);
2396 mchbar_clrbits32(C0DRC1, 1 << 6);
2397 mchbar_clrbits32(C1DRC1, 1 << 6);
2399 mchbar_setbits32(MIPMC3, 0x0f << 0);
2403 * @brief Enable On-Die Termination for DDR2.
2407 static void sdram_on_die_termination(struct sys_info *sysinfo)
2409 static const u32 odt[] = {
2410 0x00024911, 0xe0010000,
2411 0x00049211, 0xe0020000,
2412 0x0006db11, 0xe0030000,
2415 u32 reg32;
2416 int cas;
2418 reg32 = mchbar_read32(ODTC);
2419 reg32 &= ~(3 << 16);
2420 reg32 |= (1 << 14) | (1 << 6) | (2 << 16);
2421 mchbar_write32(ODTC, reg32);
2423 if (sysinfo->dimm[0] == SYSINFO_DIMM_NOT_POPULATED ||
2424 sysinfo->dimm[1] == SYSINFO_DIMM_NOT_POPULATED) {
2425 printk(BIOS_DEBUG, "one dimm per channel config..\n");
2427 reg32 = mchbar_read32(C0ODT);
2428 reg32 &= ~(7 << 28);
2429 mchbar_write32(C0ODT, reg32);
2430 reg32 = mchbar_read32(C1ODT);
2431 reg32 &= ~(7 << 28);
2432 mchbar_write32(C1ODT, reg32);
2435 cas = sysinfo->cas;
2437 reg32 = mchbar_read32(C0ODT) & 0xfff00000;
2438 reg32 |= odt[(cas - 3) * 2];
2439 mchbar_write32(C0ODT, reg32);
2441 reg32 = mchbar_read32(C1ODT) & 0xfff00000;
2442 reg32 |= odt[(cas - 3) * 2];
2443 mchbar_write32(C1ODT, reg32);
2445 reg32 = mchbar_read32(C0ODT + 4) & 0x1fc8ffff;
2446 reg32 |= odt[((cas - 3) * 2) + 1];
2447 mchbar_write32(C0ODT + 4, reg32);
2449 reg32 = mchbar_read32(C1ODT + 4) & 0x1fc8ffff;
2450 reg32 |= odt[((cas - 3) * 2) + 1];
2451 mchbar_write32(C1ODT + 4, reg32);
2455 * @brief Enable clocks to populated sockets
2458 static void sdram_enable_memory_clocks(struct sys_info *sysinfo)
2460 u8 clocks[2] = { 0, 0 };
2462 #if CONFIG(NORTHBRIDGE_INTEL_SUBTYPE_I945GM)
2463 #define CLOCKS_WIDTH 2
2464 #elif CONFIG(NORTHBRIDGE_INTEL_SUBTYPE_I945GC)
2465 #define CLOCKS_WIDTH 3
2466 #endif
2467 if (sysinfo->dimm[0] != SYSINFO_DIMM_NOT_POPULATED)
2468 clocks[0] |= (1 << CLOCKS_WIDTH) - 1;
2470 if (sysinfo->dimm[1] != SYSINFO_DIMM_NOT_POPULATED)
2471 clocks[0] |= ((1 << CLOCKS_WIDTH) - 1) << CLOCKS_WIDTH;
2473 if (sysinfo->dimm[2] != SYSINFO_DIMM_NOT_POPULATED)
2474 clocks[1] |= (1 << CLOCKS_WIDTH) - 1;
2476 if (sysinfo->dimm[3] != SYSINFO_DIMM_NOT_POPULATED)
2477 clocks[1] |= ((1 << CLOCKS_WIDTH) - 1) << CLOCKS_WIDTH;
2479 #if CONFIG(OVERRIDE_CLOCK_DISABLE)
2480 /* Usually system firmware turns off system memory clock signals to unused SO-DIMM slots
2481 * to reduce EMI and power consumption.
2482 * However, the Kontron 986LCD-M does not like unused clock signals to be disabled.
2485 clocks[0] = 0xf; /* force all clock gate pairs to enable */
2486 clocks[1] = 0xf; /* force all clock gate pairs to enable */
2487 #endif
2489 mchbar_write8(C0DCLKDIS, clocks[0]);
2490 mchbar_write8(C1DCLKDIS, clocks[1]);
2493 #define RTT_ODT_NONE 0
2494 #define RTT_ODT_50_OHM ((1 << 9) | (1 << 5))
2495 #define RTT_ODT_75_OHM (1 << 5)
2496 #define RTT_ODT_150_OHM (1 << 9)
2498 #define EMRS_OCD_DEFAULT ((1 << 12) | (1 << 11) | (1 << 10))
2500 #define MRS_CAS_3 (3 << 7)
2501 #define MRS_CAS_4 (4 << 7)
2502 #define MRS_CAS_5 (5 << 7)
2504 #define MRS_TWR_3 (2 << 12)
2505 #define MRS_TWR_4 (3 << 12)
2506 #define MRS_TWR_5 (4 << 12)
2508 #define MRS_BT (1 << 6)
2510 #define MRS_BL4 (2 << 3)
2511 #define MRS_BL8 (3 << 3)
2513 static void sdram_jedec_enable(struct sys_info *sysinfo)
2515 int i, nonzero;
2516 u32 bankaddr = 0, tmpaddr, mrsaddr = 0;
2518 for (i = 0, nonzero = -1; i < 8; i++) {
2519 if (sysinfo->banksize[i] == 0)
2520 continue;
2522 printk(BIOS_DEBUG, "jedec enable sequence: bank %d\n", i);
2524 if (nonzero != -1) {
2525 if (sysinfo->interleaved && nonzero < 4 && i >= 4) {
2526 bankaddr = 0x40;
2527 } else {
2528 printk(BIOS_DEBUG, "bankaddr from bank size of rank %d\n",
2529 nonzero);
2530 bankaddr += sysinfo->banksize[nonzero] <<
2531 (sysinfo->interleaved ? 26 : 25);
2536 * We have a bank with a non-zero size... Remember it
2537 * for the next offset we have to calculate
2539 nonzero = i;
2541 /* Get CAS latency set up */
2542 switch (sysinfo->cas) {
2543 case 5:
2544 mrsaddr = MRS_CAS_5;
2545 break;
2546 case 4:
2547 mrsaddr = MRS_CAS_4;
2548 break;
2549 case 3:
2550 mrsaddr = MRS_CAS_3;
2551 break;
2552 default:
2553 die("Jedec Error (CAS).\n");
2556 /* Get tWR set */
2557 switch (sysinfo->twr) {
2558 case 5:
2559 mrsaddr |= MRS_TWR_5;
2560 break;
2561 case 4:
2562 mrsaddr |= MRS_TWR_4;
2563 break;
2564 case 3:
2565 mrsaddr |= MRS_TWR_3;
2566 break;
2567 default:
2568 die("Jedec Error (tWR).\n");
2571 /* Set "Burst Type" */
2572 mrsaddr |= MRS_BT;
2574 /* Interleaved */
2575 if (sysinfo->interleaved)
2576 mrsaddr = mrsaddr << 1;
2578 /* Only burst length 8 supported */
2579 mrsaddr |= MRS_BL8;
2581 /* Apply NOP */
2582 PRINTK_DEBUG("Apply NOP\n");
2583 do_ram_command(RAM_COMMAND_NOP);
2584 ram_read32(bankaddr);
2586 /* Precharge all banks */
2587 PRINTK_DEBUG("All Banks Precharge\n");
2588 do_ram_command(RAM_COMMAND_PRECHARGE);
2589 ram_read32(bankaddr);
2591 /* Extended Mode Register Set (2) */
2592 PRINTK_DEBUG("Extended Mode Register Set(2)\n");
2593 do_ram_command(RAM_COMMAND_EMRS | RAM_EMRS_2);
2594 ram_read32(bankaddr);
2596 /* Extended Mode Register Set (3) */
2597 PRINTK_DEBUG("Extended Mode Register Set(3)\n");
2598 do_ram_command(RAM_COMMAND_EMRS | RAM_EMRS_3);
2599 ram_read32(bankaddr);
2601 /* Extended Mode Register Set */
2602 PRINTK_DEBUG("Extended Mode Register Set\n");
2603 do_ram_command(RAM_COMMAND_EMRS | RAM_EMRS_1);
2604 tmpaddr = bankaddr;
2605 if (!sdram_capabilities_dual_channel())
2606 tmpaddr |= RTT_ODT_75_OHM;
2607 else if (sysinfo->interleaved)
2608 tmpaddr |= (RTT_ODT_150_OHM << 1);
2609 else
2610 tmpaddr |= RTT_ODT_150_OHM;
2611 ram_read32(tmpaddr);
2613 /* Mode Register Set: Reset DLLs */
2614 PRINTK_DEBUG("MRS: Reset DLLs\n");
2615 do_ram_command(RAM_COMMAND_MRS);
2616 tmpaddr = bankaddr;
2617 tmpaddr |= mrsaddr;
2618 /* Set DLL reset bit */
2619 if (sysinfo->interleaved)
2620 tmpaddr |= (1 << 12);
2621 else
2622 tmpaddr |= (1 << 11);
2623 ram_read32(tmpaddr);
2625 /* Precharge all banks */
2626 PRINTK_DEBUG("All Banks Precharge\n");
2627 do_ram_command(RAM_COMMAND_PRECHARGE);
2628 ram_read32(bankaddr);
2630 /* CAS before RAS Refresh */
2631 PRINTK_DEBUG("CAS before RAS\n");
2632 do_ram_command(RAM_COMMAND_CBR);
2634 /* CBR wants two READs */
2635 ram_read32(bankaddr);
2636 ram_read32(bankaddr);
2638 /* Mode Register Set: Enable DLLs */
2639 PRINTK_DEBUG("MRS: Enable DLLs\n");
2640 do_ram_command(RAM_COMMAND_MRS);
2642 tmpaddr = bankaddr;
2643 tmpaddr |= mrsaddr;
2644 ram_read32(tmpaddr);
2646 /* Extended Mode Register Set */
2647 PRINTK_DEBUG("Extended Mode Register Set: ODT/OCD\n");
2648 do_ram_command(RAM_COMMAND_EMRS | RAM_EMRS_1);
2650 tmpaddr = bankaddr;
2651 if (!sdram_capabilities_dual_channel())
2652 tmpaddr |= RTT_ODT_75_OHM | EMRS_OCD_DEFAULT;
2653 else if (sysinfo->interleaved)
2654 tmpaddr |= ((RTT_ODT_150_OHM | EMRS_OCD_DEFAULT) << 1);
2655 else
2656 tmpaddr |= RTT_ODT_150_OHM | EMRS_OCD_DEFAULT;
2657 ram_read32(tmpaddr);
2659 /* Extended Mode Register Set */
2660 PRINTK_DEBUG("Extended Mode Register Set: OCD Exit\n");
2661 do_ram_command(RAM_COMMAND_EMRS | RAM_EMRS_1);
2663 tmpaddr = bankaddr;
2664 if (!sdram_capabilities_dual_channel())
2665 tmpaddr |= RTT_ODT_75_OHM;
2666 else if (sysinfo->interleaved)
2667 tmpaddr |= (RTT_ODT_150_OHM << 1);
2668 else
2669 tmpaddr |= RTT_ODT_150_OHM;
2670 ram_read32(tmpaddr);
2674 static void sdram_init_complete(void)
2676 PRINTK_DEBUG("Normal Operation\n");
2677 do_ram_command(RAM_COMMAND_NORMAL);
2680 static void sdram_setup_processor_side(void)
2682 if (i945_silicon_revision() == 0)
2683 mchbar_setbits32(FSBPMC3, 1 << 2);
2685 mchbar_setbits8(0xb00, 1);
2687 if (i945_silicon_revision() == 0)
2688 mchbar_setbits32(SLPCTL, 1 << 8);
2692 * @param boot_path: 0 = normal, 1 = reset, 2 = resume from s3
2693 * @param spd_addresses pointer to a list of SPD addresses
2695 void sdram_initialize(int boot_path, const u8 *spd_addresses)
2697 struct sys_info sysinfo;
2699 timestamp_add_now(TS_INITRAM_START);
2700 printk(BIOS_DEBUG, "Setting up RAM controller.\n");
2702 memset(&sysinfo, 0, sizeof(sysinfo));
2704 sysinfo.boot_path = boot_path;
2705 sysinfo.spd_addresses = spd_addresses;
2707 /* Look at the type of DIMMs and verify all DIMMs are x8 or x16 width */
2708 sdram_get_dram_configuration(&sysinfo);
2710 /* If error, do cold boot */
2711 sdram_detect_errors(&sysinfo);
2713 /* Program PLL settings */
2714 sdram_program_pll_settings(&sysinfo);
2717 * Program Graphics Frequency
2718 * Set core display and render clock on 945GC to the max
2720 if (CONFIG(NORTHBRIDGE_INTEL_SUBTYPE_I945GM))
2721 sdram_program_graphics_frequency(&sysinfo);
2722 else
2723 pci_write_config16(IGD_DEV, GCFC, 0x0534);
2725 /* Program System Memory Frequency */
2726 sdram_program_memory_frequency(&sysinfo);
2728 /* Determine Mode of Operation (Interleaved etc) */
2729 sdram_set_channel_mode(&sysinfo);
2731 /* Program Clock Crossing values */
2732 sdram_program_clock_crossing();
2734 /* Disable fast dispatch */
2735 sdram_disable_fast_dispatch();
2737 /* Enable WIODLL Power Down in ACPI states */
2738 mchbar_setbits32(C0DMC, 1 << 24);
2739 mchbar_setbits32(C1DMC, 1 << 24);
2741 /* Program DRAM Row Boundary/Attribute Registers */
2743 /* program row size DRB and set TOLUD */
2744 sdram_program_row_boundaries(&sysinfo);
2746 /* program page size DRA */
2747 sdram_set_row_attributes(&sysinfo);
2749 /* Program CxBNKARC */
2750 sdram_set_bank_architecture(&sysinfo);
2752 /* Program DRAM Timing and Control registers based on SPD */
2753 sdram_set_timing_and_control(&sysinfo);
2755 /* On-Die Termination Adjustment */
2756 sdram_on_die_termination(&sysinfo);
2758 /* Pre Jedec Initialization */
2759 sdram_pre_jedec_initialization();
2761 /* Perform System Memory IO Initialization */
2762 sdram_initialize_system_memory_io(&sysinfo);
2764 /* Perform System Memory IO Buffer Enable */
2765 sdram_enable_system_memory_io(&sysinfo);
2767 /* Enable System Memory Clocks */
2768 sdram_enable_memory_clocks(&sysinfo);
2770 if (boot_path == BOOT_PATH_NORMAL) {
2771 /* Jedec Initialization sequence */
2772 sdram_jedec_enable(&sysinfo);
2775 /* Program Power Management Registers */
2776 sdram_power_management(&sysinfo);
2778 /* Post Jedec Init */
2779 sdram_post_jedec_initialization(&sysinfo);
2781 /* Program DRAM Throttling */
2782 sdram_thermal_management();
2784 /* Normal Operations */
2785 sdram_init_complete();
2787 /* Program Receive Enable Timings */
2788 sdram_program_receive_enable(&sysinfo);
2790 /* Enable Periodic RCOMP */
2791 sdram_enable_rcomp();
2793 /* Tell ICH7 that we're done */
2794 pci_and_config8(PCI_DEV(0, 0x1f, 0), GEN_PMCON_2, (u8)~(1 << 7));
2796 printk(BIOS_DEBUG, "RAM initialization finished.\n");
2798 sdram_setup_processor_side();
2799 timestamp_add_now(TS_INITRAM_END);