blob: 789ea82db9eccc22e72be0a7cc72ed72fbec6e16 [file] [log] [blame]
Richard Smithcb8eab42006-07-24 04:25:47 +00001/*
Stefan Reinauer7e61e452008-01-18 10:35:56 +00002 * This file is part of the coreboot project.
Uwe Hermann1a9c8922007-04-01 17:24:03 +00003 *
Uwe Hermann1683cef2008-11-27 00:47:07 +00004 * Copyright (C) 2007-2008 Uwe Hermann <uwe@hermann-uwe.de>
Keith Hui59356ca2010-03-06 18:16:25 +00005 * Copyright (C) 2010 Keith Hui <buurin@gmail.com>
Uwe Hermann1a9c8922007-04-01 17:24:03 +00006 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Richard Smithcb8eab42006-07-24 04:25:47 +000020 */
21
Uwe Hermann1a9c8922007-04-01 17:24:03 +000022#include <spd.h>
23#include <sdram_mode.h>
24#include <delay.h>
Carl-Daniel Hailfinger2ee67792008-10-01 12:52:52 +000025#include <stdlib.h>
Uwe Hermann1a9c8922007-04-01 17:24:03 +000026#include "i440bx.h"
Keith Hui59356ca2010-03-06 18:16:25 +000027#include "raminit.h"
Richard Smithcb8eab42006-07-24 04:25:47 +000028
Uwe Hermann1a9c8922007-04-01 17:24:03 +000029/*-----------------------------------------------------------------------------
30Macros and definitions.
31-----------------------------------------------------------------------------*/
Richard Smithcb8eab42006-07-24 04:25:47 +000032
Uwe Hermann1a9c8922007-04-01 17:24:03 +000033/* Debugging macros. */
Uwe Hermann01ce6012010-03-05 10:03:50 +000034#if CONFIG_DEBUG_RAM_SETUP
Uwe Hermann1a9c8922007-04-01 17:24:03 +000035#define PRINT_DEBUG(x) print_debug(x)
36#define PRINT_DEBUG_HEX8(x) print_debug_hex8(x)
37#define PRINT_DEBUG_HEX16(x) print_debug_hex16(x)
38#define PRINT_DEBUG_HEX32(x) print_debug_hex32(x)
Stefan Reinauer3ac400e2010-03-30 22:12:59 +000039// no dump_pci_device in src/northbridge/intel/i440bx
40// #define DUMPNORTH() dump_pci_device(PCI_DEV(0, 0, 0))
41#define DUMPNORTH()
Richard Smithcb8eab42006-07-24 04:25:47 +000042#else
Uwe Hermann941a6f02007-04-30 23:27:27 +000043#define PRINT_DEBUG(x)
Uwe Hermann1a9c8922007-04-01 17:24:03 +000044#define PRINT_DEBUG_HEX8(x)
45#define PRINT_DEBUG_HEX16(x)
46#define PRINT_DEBUG_HEX32(x)
47#define DUMPNORTH()
Richard Smithcb8eab42006-07-24 04:25:47 +000048#endif
49
Uwe Hermann1683cef2008-11-27 00:47:07 +000050#define NB PCI_DEV(0, 0, 0)
51
Uwe Hermann1a9c8922007-04-01 17:24:03 +000052/* SDRAMC[7:5] - SDRAM Mode Select (SMS). */
53#define RAM_COMMAND_NORMAL 0x0
54#define RAM_COMMAND_NOP 0x1
55#define RAM_COMMAND_PRECHARGE 0x2
56#define RAM_COMMAND_MRS 0x3
57#define RAM_COMMAND_CBR 0x4
Richard Smithcb8eab42006-07-24 04:25:47 +000058
Uwe Hermann1a9c8922007-04-01 17:24:03 +000059/* Map the JEDEC SPD refresh rates (array index) to 440BX refresh rates as
60 * defined in DRAMC[2:0].
61 *
62 * [0] == Normal 15.625 us -> 15.6 us
63 * [1] == Reduced(.25X) 3.9 us -> 7.8 ns
64 * [2] == Reduced(.5X) 7.8 us -> 7.8 us
65 * [3] == Extended(2x) 31.3 us -> 31.2 us
66 * [4] == Extended(4x) 62.5 us -> 62.4 us
67 * [5] == Extended(8x) 125 us -> 124.8 us
68 */
69static const uint32_t refresh_rate_map[] = {
70 1, 5, 5, 2, 3, 4
71};
Richard Smithcb8eab42006-07-24 04:25:47 +000072
Uwe Hermann1a9c8922007-04-01 17:24:03 +000073/* Table format: register, bitmask, value. */
74static const long register_values[] = {
75 /* NBXCFG - NBX Configuration Register
Uwe Hermannf5a6fd22007-05-27 23:31:31 +000076 * 0x50 - 0x53
Uwe Hermann1a9c8922007-04-01 17:24:03 +000077 *
78 * [31:24] SDRAM Row Without ECC
79 * 0 = ECC components are populated in this row
80 * 1 = ECC components are not populated in this row
81 * [23:19] Reserved
82 * [18:18] Host Bus Fast Data Ready Enable (HBFDRE)
83 * Assertion of DRAM data on host bus occurs...
84 * 0 = ...one clock after sampling snoop results (default)
85 * 1 = ...on the same clock the snoop result is being sampled
86 * (this mode is faster by one clock cycle)
87 * [17:17] ECC - EDO static Drive mode
88 * 0 = Normal mode (default)
89 * 1 = ECC signals are always driven
90 * [16:16] IDSEL_REDIRECT
91 * 0 = IDSEL1 is allocated to this bridge (default)
92 * 1 = IDSEL7 is allocated to this bridge
93 * [15:15] WSC# Handshake Disable
94 * 1 = Uni-processor mode
95 * 0 = Dual-processor mode with external IOAPIC (default)
96 * [14:14] Intel Reserved
97 * [13:12] Host/DRAM Frequency
98 * 00 = 100 MHz
99 * 01 = Reserved
100 * 10 = 66 MHz
101 * 11 = Reserved
102 * [11:11] AGP to PCI Access Enable
103 * 1 = Enable
104 * 0 = Disable
105 * [10:10] PCI Agent to Aperture Access Disable
106 * 1 = Disable
107 * 0 = Enable (default)
108 * [09:09] Aperture Access Global Enable
109 * 1 = Enable
110 * 0 = Disable
111 * [08:07] DRAM Data Integrity Mode (DDIM)
112 * 00 = Non-ECC
113 * 01 = EC-only
114 * 10 = ECC Mode
115 * 11 = ECC Mode with hardware scrubbing enabled
116 * [06:06] ECC Diagnostic Mode Enable (EDME)
117 * 1 = Enable
118 * 0 = Normal operation mode (default)
119 * [05:05] MDA Present (MDAP)
120 * Works in conjunction with the VGA_EN bit.
121 * VGA_EN MDAP
122 * 0 x All VGA cycles are sent to PCI
123 * 1 0 All VGA cycles are sent to AGP
124 * 1 1 All VGA cycles are sent to AGP, except for
125 * cycles in the MDA range.
126 * [04:04] Reserved
127 * [03:03] USWC Write Post During I/O Bridge Access Enable (UWPIO)
128 * 1 = Enable
129 * 0 = Disable
130 * [02:02] In-Order Queue Depth (IOQD)
131 * 1 = In-order queue = maximum
132 * 0 = A7# is sampled asserted (i.e., 0)
133 * [01:00] Reserved
Richard Smithcb8eab42006-07-24 04:25:47 +0000134 */
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000135 // TODO
Uwe Hermannbc3594732007-06-07 22:16:30 +0000136 NBXCFG + 0, 0x00, 0x0c,
137 // NBXCFG + 1, 0x00, 0xa0,
138 NBXCFG + 1, 0x00, 0x80,
139 NBXCFG + 2, 0x00, 0x00,
140 NBXCFG + 3, 0x00, 0xff,
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000141
142 /* DRAMC - DRAM Control Register
143 * 0x57
144 *
145 * [7:6] Reserved
146 * [5:5] Module Mode Configuration (MMCONFIG)
147 * TODO
148 * [4:3] DRAM Type (DT)
149 * 00 = EDO
150 * 01 = SDRAM
151 * 10 = Registered SDRAM
152 * 11 = Reserved
153 * Note: EDO, SDRAM and Registered SDRAM cannot be mixed.
154 * [2:0] DRAM Refresh Rate (DRR)
155 * 000 = Refresh disabled
156 * 001 = 15.6 us
157 * 010 = 31.2 us
158 * 011 = 62.4 us
159 * 100 = 124.8 us
160 * 101 = 249.6 us
161 * 110 = Reserved
162 * 111 = Reserved
Richard Smithcb8eab42006-07-24 04:25:47 +0000163 */
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000164 /* Choose SDRAM (not registered), and disable refresh for now. */
Uwe Hermannbc3594732007-06-07 22:16:30 +0000165 DRAMC, 0x00, 0x08,
Richard Smithcb8eab42006-07-24 04:25:47 +0000166
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000167 /*
168 * PAM[6:0] - Programmable Attribute Map Registers
Uwe Hermannf5a6fd22007-05-27 23:31:31 +0000169 * 0x59 - 0x5f
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000170 *
171 * 0x59 [3:0] Reserved
172 * 0x59 [5:4] 0xF0000 - 0xFFFFF BIOS area
173 * 0x5a [1:0] 0xC0000 - 0xC3FFF ISA add-on BIOS
174 * 0x5a [5:4] 0xC4000 - 0xC7FFF ISA add-on BIOS
175 * 0x5b [1:0] 0xC8000 - 0xCBFFF ISA add-on BIOS
176 * 0x5b [5:4] 0xCC000 - 0xCFFFF ISA add-on BIOS
177 * 0x5c [1:0] 0xD0000 - 0xD3FFF ISA add-on BIOS
178 * 0x5c [5:4] 0xD4000 - 0xD7FFF ISA add-on BIOS
179 * 0x5d [1:0] 0xD8000 - 0xDBFFF ISA add-on BIOS
180 * 0x5d [5:4] 0xDC000 - 0xDFFFF ISA add-on BIOS
181 * 0x5e [1:0] 0xE0000 - 0xE3FFF BIOS entension
182 * 0x5e [5:4] 0xE4000 - 0xE7FFF BIOS entension
183 * 0x5f [1:0] 0xE8000 - 0xEBFFF BIOS entension
184 * 0x5f [5:4] 0xEC000 - 0xEFFFF BIOS entension
185 *
186 * Bit assignment:
187 * 00 = DRAM Disabled (all access goes to memory mapped I/O space)
188 * 01 = Read Only (Reads to DRAM, writes to memory mapped I/O space)
189 * 10 = Write Only (Writes to DRAM, reads to memory mapped I/O space)
190 * 11 = Read/Write (all access goes to DRAM)
191 */
Keith Hui59356ca2010-03-06 18:16:25 +0000192
193 /*
194 * Map all legacy regions to RAM (read/write). This is required if
195 * you want to use the RAM area from 768 KB - 1 MB. If the PAM
196 * registers are not set here appropriately, the RAM in that region
197 * will not be accessible, thus a RAM check of it will also fail.
198 *
199 * TODO: This was set in sdram_set_spd_registers().
200 * Test if it still works when set here.
201 */
202 PAM0, 0x00, 0x30,
203 PAM1, 0x00, 0x33,
204 PAM2, 0x00, 0x33,
205 PAM3, 0x00, 0x33,
206 PAM4, 0x00, 0x33,
207 PAM5, 0x00, 0x33,
208 PAM6, 0x00, 0x33,
Richard Smithcb8eab42006-07-24 04:25:47 +0000209
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000210 /* DRB[0:7] - DRAM Row Boundary Registers
211 * 0x60 - 0x67
212 *
213 * An array of 8 byte registers, which hold the ending memory address
214 * assigned to each pair of DIMMs, in 8MB granularity.
215 *
216 * 0x60 DRB0 = Total memory in row0 (in 8 MB)
217 * 0x61 DRB1 = Total memory in row0+1 (in 8 MB)
218 * 0x62 DRB2 = Total memory in row0+1+2 (in 8 MB)
219 * 0x63 DRB3 = Total memory in row0+1+2+3 (in 8 MB)
220 * 0x64 DRB4 = Total memory in row0+1+2+3+4 (in 8 MB)
221 * 0x65 DRB5 = Total memory in row0+1+2+3+4+5 (in 8 MB)
222 * 0x66 DRB6 = Total memory in row0+1+2+3+4+5+6 (in 8 MB)
223 * 0x67 DRB7 = Total memory in row0+1+2+3+4+5+6+7 (in 8 MB)
224 */
Uwe Hermannf5a6fd22007-05-27 23:31:31 +0000225 /* Set the DRBs to zero for now, this will be fixed later. */
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000226 DRB0, 0x00, 0x00,
227 DRB1, 0x00, 0x00,
228 DRB2, 0x00, 0x00,
229 DRB3, 0x00, 0x00,
230 DRB4, 0x00, 0x00,
231 DRB5, 0x00, 0x00,
232 DRB6, 0x00, 0x00,
233 DRB7, 0x00, 0x00,
234
235 /* FDHC - Fixed DRAM Hole Control Register
236 * 0x68
237 *
238 * Controls two fixed DRAM holes: 512 KB - 640 KB and 15 MB - 16 MB.
239 *
240 * [7:6] Hole Enable (HEN)
241 * 00 = None
242 * 01 = 512 KB - 640 KB (128 KB)
243 * 10 = 15 MB - 16 MB (1 MB)
244 * 11 = Reserved
245 * [5:0] Reserved
246 */
247 /* No memory holes. */
248 FDHC, 0x00, 0x00,
249
250 /* RPS - SDRAM Row Page Size Register
251 * 0x74 - 0x75
252 *
253 * Sets the row page size for SDRAM. For EDO memory, the page
254 * size is fixed at 2 KB.
255 *
256 * [15:0] Page Size (PS)
257 * TODO
258 */
259 // TODO
Uwe Hermannbc3594732007-06-07 22:16:30 +0000260 RPS + 0, 0x00, 0x00,
261 RPS + 1, 0x00, 0x00,
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000262
263 /* SDRAMC - SDRAM Control Register
Uwe Hermann7ea18cf2007-05-04 00:51:17 +0000264 * 0x76 - 0x77
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000265 *
266 * [15:10] Reserved
267 * [09:08] Idle/Pipeline DRAM Leadoff Timing (IPDLT)
268 * 00 = Illegal
269 * 01 = Add a clock delay to the lead-off clock count
270 * 10 = Illegal
271 * 11 = Illegal
272 * [07:05] SDRAM Mode Select (SMS)
273 * 000 = Normal SDRAM Operation (default)
274 * 001 = NOP Command Enable
275 * 010 = All Banks Precharge Enable
276 * 011 = Mode Register Set Enable
277 * 100 = CBR Enable
278 * 101 = Reserved
279 * 110 = Reserved
280 * 111 = Reserved
281 * [04:04] SDRAMPWR
282 * 0 = 3 DIMM configuration
283 * 1 = 4 DIMM configuration
284 * [03:03] Leadoff Command Timing (LCT)
285 * 0 = 4 CS# Clock
286 * 1 = 3 CS# Clock
287 * [02:02] CAS# Latency (CL)
288 * 0 = 3 DCLK CAS# latency
289 * 1 = 2 DCLK CAS# latency
290 * [01:01] SDRAM RAS# to CAS# Delay (SRCD)
291 * 0 = 3 clocks between a row activate and a read or write cmd.
292 * 1 = 2 clocks between a row activate and a read or write cmd.
293 * [00:00] SDRAM RAS# Precharge (SRP)
294 * 0 = 3 clocks of RAS# precharge
295 * 1 = 2 clocks of RAS# precharge
296 */
Keith Hui9c1e1f02010-03-13 20:16:48 +0000297#if CONFIG_SDRAMPWR_4DIMM
298 SDRAMC + 0, 0x00, 0x10, /* The board has 4 DIMM slots. */
299#else
300 SDRAMC + 0, 0x00, 0x00, /* The board has 3 DIMM slots.*/
301#endif
Mats Erik Andersson45db3662008-09-30 04:52:29 +0000302 SDRAMC + 1, 0x00, 0x00,
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000303
304 /* PGPOL - Paging Policy Register
305 * 0x78 - 0x79
306 *
307 * [15:08] Banks per Row (BPR)
308 * TODO
309 * 0 = 2 banks
310 * 1 = 4 banks
311 * [07:05] Reserved
312 * [04:04] Intel Reserved
313 * [03:00] DRAM Idle Timer (DIT)
314 * 0000 = 0 clocks
315 * 0001 = 2 clocks
316 * 0010 = 4 clocks
317 * 0011 = 8 clocks
318 * 0100 = 10 clocks
319 * 0101 = 12 clocks
320 * 0110 = 16 clocks
321 * 0111 = 32 clocks
322 * 1xxx = Infinite (pages are not closed for idle condition)
323 */
324 // TODO
Uwe Hermannbc3594732007-06-07 22:16:30 +0000325 PGPOL + 0, 0x00, 0x00,
326 PGPOL + 1, 0x00, 0xff,
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000327
328 /* PMCR - Power Management Control Register
329 * 0x7a
330 *
331 * [07:07] Power Down SDRAM Enable (PDSE)
332 * 1 = Enable
333 * 0 = Disable
334 * [06:06] ACPI Control Register Enable (SCRE)
335 * 1 = Enable
336 * 0 = Disable (default)
337 * [05:05] Suspend Refresh Type (SRT)
338 * 1 = Self refresh mode
339 * 0 = CBR fresh mode
340 * [04:04] Normal Refresh Enable (NREF_EN)
341 * 1 = Enable
342 * 0 = Disable
343 * [03:03] Quick Start Mode (QSTART)
344 * 1 = Quick start mode for the processor is enabled
345 * [02:02] Gated Clock Enable (GCLKEN)
346 * 1 = Enable
347 * 0 = Disable
348 * [01:01] AGP Disable (AGP_DIS)
349 * 1 = Disable
350 * 0 = Enable
351 * [00:00] CPU reset without PCIRST enable (CRst_En)
352 * 1 = Enable
353 * 0 = Disable
354 */
355 /* Enable normal refresh and the gated clock. */
356 // TODO: Only do this later?
357 // PMCR, 0x00, 0x14,
358 // PMCR, 0x00, 0x10,
359 PMCR, 0x00, 0x00,
Keith Hui59356ca2010-03-06 18:16:25 +0000360
361 /* Enable SCRR.SRRAEN and let BX choose the SRR. */
362 SCRR + 1, 0x00, 0x10,
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000363};
364
365/*-----------------------------------------------------------------------------
366SDRAM configuration functions.
367-----------------------------------------------------------------------------*/
368
369/**
370 * Send the specified RAM command to all DIMMs.
371 *
Uwe Hermann8b643cea2008-12-09 16:36:12 +0000372 * @param command The RAM command to send to the DIMM(s).
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000373 */
Uwe Hermann8b643cea2008-12-09 16:36:12 +0000374static void do_ram_command(u32 command)
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000375{
Uwe Hermann8b643cea2008-12-09 16:36:12 +0000376 int i, caslatency;
377 u8 dimm_start, dimm_end;
378 u16 reg16;
379 u32 addr, addr_offset;
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000380
381 /* Configure the RAM command. */
Uwe Hermann8b643cea2008-12-09 16:36:12 +0000382 reg16 = pci_read_config16(NB, SDRAMC);
383 reg16 &= 0xff1f; /* Clear bits 7-5. */
384 reg16 |= (u16) (command << 5); /* Write command into bits 7-5. */
385 pci_write_config16(NB, SDRAMC, reg16);
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000386
Uwe Hermann8b643cea2008-12-09 16:36:12 +0000387 /*
388 * RAM_COMMAND_NORMAL affects only the memory controller and
389 * doesn't need to be "sent" to the DIMMs.
390 */
391 if (command == RAM_COMMAND_NORMAL)
392 return;
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000393
Uwe Hermann8b643cea2008-12-09 16:36:12 +0000394 /* Send the RAM command to each row of memory. */
395 dimm_start = 0;
396 for (i = 0; i < (DIMM_SOCKETS * 2); i++) {
Keith Hui59356ca2010-03-06 18:16:25 +0000397 addr_offset = 0;
398 caslatency = 3; /* TODO: Dynamically get CAS latency later. */
Uwe Hermann8b643cea2008-12-09 16:36:12 +0000399 if (command == RAM_COMMAND_MRS) {
400 /*
401 * MAA[12:11,9:0] must be inverted when sent to DIMM
402 * 2 or 3 (no inversion if sent to DIMM 0 or 1).
403 */
404 if ((i >= 0 && i <= 3) && caslatency == 3)
405 addr_offset = 0x1d0;
406 if ((i >= 4 && i <= 7) && caslatency == 3)
407 addr_offset = 0x1e28;
408 if ((i >= 0 && i <= 3) && caslatency == 2)
409 addr_offset = 0x150;
410 if ((i >= 4 && i <= 7) && caslatency == 2)
411 addr_offset = 0x1ea8;
412 }
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000413
Uwe Hermann8b643cea2008-12-09 16:36:12 +0000414 dimm_end = pci_read_config8(NB, DRB + i);
415
416 addr = (dimm_start * 8 * 1024 * 1024) + addr_offset;
417 if (dimm_end > dimm_start) {
418#if 0
419 PRINT_DEBUG(" Sending RAM command 0x");
420 PRINT_DEBUG_HEX16(reg16);
421 PRINT_DEBUG(" to 0x");
422 PRINT_DEBUG_HEX32(addr);
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000423 PRINT_DEBUG("\n");
Uwe Hermann8b643cea2008-12-09 16:36:12 +0000424#endif
425
426 read32(addr);
427 }
428
429 /* Set the start of the next DIMM. */
430 dimm_start = dimm_end;
431 }
Richard Smithcb8eab42006-07-24 04:25:47 +0000432}
433
Keith Hui59356ca2010-03-06 18:16:25 +0000434static void set_dram_buffer_strength(void)
435{
Keith Huib48ba662010-03-17 02:15:07 +0000436 /* To give some breathing room for romcc,
437 * mbsc0 doubles as drb
438 * mbsc1 doubles as drb1
439 * mbfs0 doubles as i and reg
Keith Hui59356ca2010-03-06 18:16:25 +0000440 */
Keith Huib48ba662010-03-17 02:15:07 +0000441 uint8_t mbsc0,mbsc1,mbsc3,mbsc4,mbfs0,mbfs2,fsb;
Keith Hui59356ca2010-03-06 18:16:25 +0000442
Keith Huib48ba662010-03-17 02:15:07 +0000443 /* Tally how many rows between rows 0-3 and rows 4-7 are populated.
444 * This determines how to program MBFS and MBSC.
445 */
446 uint8_t dimm03 = 0;
447 uint8_t dimm47 = 0;
448
449 mbsc0 = 0;
450 for (mbfs0 = DRB0; mbfs0 <= DRB7; mbfs0++) {
451 mbsc1 = pci_read_config8(NB, mbfs0);
452 if (mbsc0 != mbsc1) {
453 if (mbfs0 <= DRB3) {
454 dimm03++;
455 } else {
456 dimm47++;
457 }
458 mbsc0 = mbsc1;
459 }
460 }
461
462 /* Algorithm bitmap for programming MBSC[39:0] and MBFS[23:0]
463 *
464 * 440BX datasheet says buffer frequency is independent from bus frequency
465 * and mismatch both ways are possible. This is how it is programmed
466 * in ASUS P2B-LS.
467 *
468 * There are four main conditions to check when programming DRAM buffer
469 * frequency and strength:
470 *
471 * a: >2 rows populated across DIMM0,1
472 * b: >2 rows populated across DIMM2,3
473 * c: >4 rows populated across all DIMM slots
474 * and either one of:
475 * 1: NBXCFG[13] strapped as 100MHz, or
476 * 6: NBXCFG[13] strapped as 66MHz
477 *
478 * CKE0/FENA ----------------------------------------------------------+
479 * CKE1/GCKE -------------------[ MBFS ]------------------------+|
480 * DQMA/CASA[764320]# ----------[ 0 = 66MHz ]-----------------------+||
481 * DQMB1/CASB1# ----------------[ 1 = 100MHz ]----------------------+|||
482 * DQMB5/CASB5# ---------------------------------------------------+||||
483 * DQMA1/CASA1# --------------------------------------------------+|||||
484 * DQMA5/CASA5# -------------------------------------------------+||||||
485 * CSA0-5#,CSB0-5# ----------------------------------------++++++|||||||
486 * CSA6#/CKE2# -------------------------------------------+|||||||||||||
487 * CSB6#/CKE4# ------------------------------------------+||||||||||||||
488 * CSA7#/CKE3# -----------------------------------------+|||||||||||||||
489 * CSB7#/CKE5# ----------------------------------------+||||||||||||||||
490 * MECC[7:0] #2/#1 (100MHz) -------------------------++|||||||||||||||||
491 * MD[63:0] #2/#1 (100MHz) ------------------------++|||||||||||||||||||
492 * MAB[12:11,9:0]#,MAB[13,10],WEB#,SRASB#,SCASB# -+|||||||||||||||||||||
493 * MAA[13:0],WEA#,SRASA#,SCASA# -----------------+||||||||||||||||||||||
494 * Reserved ------------------------------------+|||||||||||||||||||||||
495 * ||||||||||||||||||||||||
496 * 3 32 21 10 0 * 2 21 10 0
497 * 9876543210987654321098765432109876543210 * 321098765432109876543210
498 * a 10------------------------1010---------- * -1---------------11----- a
499 *!a 11------------------------1111---------- * -0---------------00----- !a
500 * b --10--------------------------1010------ * --1----------------11--- b
501 *!b --11--------------------------1111------ * --0----------------00--- !b
502 * c ----------------------------------1100-- * ----------------------1- c
503 *!c ----------------------------------1011-- * ----------------------0- !c
504 * 1 ----1010101000000000000000------------00 * ---11111111111111----1-0 1
505 * 6 ----000000000000000000000010101010----00 * ---1111111111111100000-0 6
506 * | | | | | | | | | | ||||||| | | | | | |
507 * | | | | | | | | | | ||||||| | | | | | +- CKE0/FENA
508 * | | | | | | | | | | ||||||| | | | | +--- CKE1/GCKE
509 * | | | | | | | | | | ||||||| | | | +----- DQMA/CASA[764320]#
510 * | | | | | | | | | | ||||||| | | +------- DQMB1/CASB1#
511 * | | | | | | | | | | ||||||| | +--------- DQMB5/CASB5#
512 * | | | | | | | | | | ||||||| +----------- DQMA1/CASA1#
513 * | | | | | | | | | | ||||||+------------- DQMA5/CASA5#
514 * | | | | | | | | | | ++++++-------------- CSA0-5#,CSB0-5# [ 0=1x;1=2x ]
515 * | | | | | | | | | +--------------------- CSA6#/CKE2#
516 * | | | | | | | | +---[ MBSC ]------ CSB6#/CKE4#
517 * | | | | | | | +-----[ 00 = 1x ]------ CSA7#/CKE3#
518 * | | | | | | +-------[ 01 invalid ]------ CSB7#/CKE5#
519 * | | | | | +---------[ 10 = 2x ]------ MECC[7:0] #1 (2x)
520 * | | | | +-----------[ 11 = 3x ]------ MECC[7:0] #2 (2x)
521 * | | | +--------------------------------- MD[63:0] #1 (2x)
522 * | | +----------------------------------- MD[63:0] #2 (2x)
523 * | +------------------------------------- MAB[12:11,9:0]#,MAB[13,10],WEB#,SRASB#,SCASB#
524 * +--------------------------------------- MAA[13:0],WEA#,SRASA#,SCASA#
525 * MBSC[47:40] and MBFS[23] are reserved.
526 *
527 * This algorithm is checked against P2B-LS factory BIOS. It has 4 DIMM slots.
528 * Therefore it assumes a board with 4 slots, and will need testing
529 * on boards with 3 DIMM slots.
530 */
531
532 mbsc0 = 0x80;
533 mbsc1 = 0x2a;
534 mbfs2 = 0x1f;
535 if (pci_read_config8(NB, NBXCFG + 1) & 0x30) {
536 fsb = 66;
537 mbsc3 = 0x00;
538 mbsc4 = 0x00;
539 mbfs0 = 0x80;
540 } else {
541 fsb = 100;
542 mbsc3 = 0xa0;
543 mbsc4 = 0x0a;
544 mbfs0 = 0x84;
545 }
546
547 if (dimm03 > 2) {
548 mbsc4 = mbsc4 | 0x80;
549 mbsc1 = mbsc1 | 0x28;
550 mbfs2 = mbfs2 | 0x40;
551 mbfs0 = mbfs0 | 0x60;
552 } else {
553 mbsc4 = mbsc4 | 0xc0;
554 if (fsb == 100) {
555 mbsc1 = mbsc1 | 0x3c;
556 }
557 }
558 if (dimm47 > 2) {
559 mbsc4 = mbsc4 | 0x20;
560 mbsc1 = mbsc1 | 0x02;
561 mbsc0 = mbsc0 | 0x80;
562 mbfs2 = mbfs2 | 0x20;
563 mbfs0 = mbfs0 | 0x18;
564 } else {
565 mbsc4 = mbsc4 | 0x30;
566 if (fsb == 100) {
567 mbsc1 = mbsc1 | 0x03;
568 mbsc0 = mbsc0 | 0xc0;
569 }
570 }
571 if ((dimm03 + dimm47) > 4) {
572 mbsc0 = mbsc0 | 0x30;
573 mbfs0 = mbfs0 | 0x02;
574 } else {
575 mbsc0 = mbsc0 | 0x2c;
576 }
577
578 pci_write_config8(NB, MBSC + 0, mbsc0);
579 pci_write_config8(NB, MBSC + 1, mbsc1);
580 pci_write_config8(NB, MBSC + 2, 0x00);
581 pci_write_config8(NB, MBSC + 3, mbsc3);
582 pci_write_config8(NB, MBSC + 4, mbsc4);
583 pci_write_config8(NB, MBFS + 0, mbfs0);
584 pci_write_config8(NB, MBFS + 1, 0xff);
585 pci_write_config8(NB, MBFS + 2, mbfs2);
Keith Hui59356ca2010-03-06 18:16:25 +0000586}
587
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000588/*-----------------------------------------------------------------------------
589DIMM-independant configuration functions.
590-----------------------------------------------------------------------------*/
Richard Smithcb8eab42006-07-24 04:25:47 +0000591
Uwe Hermann1683cef2008-11-27 00:47:07 +0000592static void spd_enable_refresh(void)
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000593{
594 int i, value;
595 uint8_t reg;
596
Uwe Hermann1683cef2008-11-27 00:47:07 +0000597 reg = pci_read_config8(NB, DRAMC);
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000598
599 for (i = 0; i < DIMM_SOCKETS; i++) {
Uwe Hermann1683cef2008-11-27 00:47:07 +0000600 value = spd_read_byte(DIMM_SPD_BASE + i, SPD_REFRESH);
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000601 if (value < 0)
602 continue;
603 reg = (reg & 0xf8) | refresh_rate_map[(value & 0x7f)];
604
605 PRINT_DEBUG(" Enabling refresh (DRAMC = 0x");
606 PRINT_DEBUG_HEX8(reg);
607 PRINT_DEBUG(") for DIMM ");
608 PRINT_DEBUG_HEX8(i);
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000609 PRINT_DEBUG("\n");
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000610 }
611
Uwe Hermann1683cef2008-11-27 00:47:07 +0000612 pci_write_config8(NB, DRAMC, reg);
Richard Smithcb8eab42006-07-24 04:25:47 +0000613}
614
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000615/*-----------------------------------------------------------------------------
616Public interface.
617-----------------------------------------------------------------------------*/
618
Uwe Hermann1683cef2008-11-27 00:47:07 +0000619static void sdram_set_registers(void)
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000620{
621 int i, max;
Uwe Hermannbc3594732007-06-07 22:16:30 +0000622 uint8_t reg;
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000623
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000624 PRINT_DEBUG("Northbridge prior to SDRAM init:\n");
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000625 DUMPNORTH();
626
Carl-Daniel Hailfinger2ee67792008-10-01 12:52:52 +0000627 max = ARRAY_SIZE(register_values);
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000628
Uwe Hermannf5a6fd22007-05-27 23:31:31 +0000629 /* Set registers as specified in the register_values[] array. */
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000630 for (i = 0; i < max; i += 3) {
Uwe Hermann1683cef2008-11-27 00:47:07 +0000631 reg = pci_read_config8(NB, register_values[i]);
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000632 reg &= register_values[i + 1];
633 reg |= register_values[i + 2] & ~(register_values[i + 1]);
Uwe Hermann1683cef2008-11-27 00:47:07 +0000634 pci_write_config8(NB, register_values[i], reg);
Keith Hui59356ca2010-03-06 18:16:25 +0000635#if 0
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000636 PRINT_DEBUG(" Set register 0x");
Uwe Hermannbc3594732007-06-07 22:16:30 +0000637 PRINT_DEBUG_HEX8(register_values[i]);
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000638 PRINT_DEBUG(" to 0x");
Uwe Hermannbc3594732007-06-07 22:16:30 +0000639 PRINT_DEBUG_HEX8(reg);
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000640 PRINT_DEBUG("\n");
Keith Hui59356ca2010-03-06 18:16:25 +0000641#endif
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000642 }
643}
644
Keith Hui59356ca2010-03-06 18:16:25 +0000645struct dimm_size {
646 unsigned long side1;
647 unsigned long side2;
648};
649
650static struct dimm_size spd_get_dimm_size(unsigned int device)
651{
652 struct dimm_size sz;
653 int i, module_density, dimm_banks;
654 sz.side1 = 0;
655 module_density = spd_read_byte(device, SPD_DENSITY_OF_EACH_ROW_ON_MODULE);
656 dimm_banks = spd_read_byte(device, SPD_NUM_DIMM_BANKS);
657
658 /* Find the size of side1. */
659 /* Find the larger value. The larger value is always side1. */
660 for (i = 512; i >= 0; i >>= 1) {
661 if ((module_density & i) == i) {
662 sz.side1 = i;
663 break;
664 }
665 }
666
667 /* Set to 0 in case it's single sided. */
668 sz.side2 = 0;
669
670 /* Test if it's a dual-sided DIMM. */
671 if (dimm_banks > 1) {
672 /* Test if there's a second value. If so it's asymmetrical. */
673 if (module_density != i) {
674 /*
675 * Find second value, picking up where we left off.
676 * i >>= 1 done initially to make sure we don't get
677 * the same value again.
678 */
679 for (i >>= 1; i >= 0; i >>= 1) {
680 if (module_density == (sz.side1 | i)) {
681 sz.side2 = i;
682 break;
683 }
684 }
685 /* If not, it's symmetrical. */
686 } else {
687 sz.side2 = sz.side1;
688 }
689 }
690
691 /*
692 * SPD byte 31 is the memory size divided by 4 so we
693 * need to muliply by 4 to get the total size.
694 */
695 sz.side1 *= 4;
696 sz.side2 *= 4;
697
698 return sz;
699}
700/*
701 * Sets DRAM attributes one DIMM at a time, based on SPD data.
702 * Northbridge settings that are set: NBXCFG[31:24], DRB0-DRB7, RPS, DRAMC.
703 */
704static void set_dram_row_attributes(void)
705{
706 int i, dra, drb, col, width, value, rps, edosd, ecc, nbxecc;
707 u8 bpr; /* Top 8 bits of PGPOL */
708
709 edosd = 0;
710 rps = 0;
711 drb = 0;
712 bpr = 0;
713 nbxecc = 0xff;
714
715 for (i = 0; i < DIMM_SOCKETS; i++) {
716 unsigned int device;
717 device = DIMM_SPD_BASE + i;
718 bpr >>= 2;
719
720 /* First check if a DIMM is actually present. */
721 value = spd_read_byte(device, SPD_MEMORY_TYPE);
722 /* This is 440BX! We do EDO too! */
723 if (value == SPD_MEMORY_TYPE_EDO
724 || value == SPD_MEMORY_TYPE_SDRAM) {
725
726 PRINT_DEBUG("Found ");
727 if (value == SPD_MEMORY_TYPE_EDO) {
728 edosd |= 0x02;
729 } else if (value == SPD_MEMORY_TYPE_SDRAM) {
730 edosd |= 0x04;
731 }
732 PRINT_DEBUG("DIMM in slot ");
733 PRINT_DEBUG_HEX8(i);
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000734 PRINT_DEBUG("\n");
Keith Hui59356ca2010-03-06 18:16:25 +0000735
736 if (edosd == 0x06) {
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000737 print_err("Mixing EDO/SDRAM unsupported!\n");
738 die("HALT\n");
Keith Hui59356ca2010-03-06 18:16:25 +0000739 }
740
741 /* "DRA" is our RPS for the two rows on this DIMM. */
742 dra = 0;
743
744 /* Columns */
745 col = spd_read_byte(device, SPD_NUM_COLUMNS);
746
747 /*
748 * Is this an ECC DIMM? Actually will be a 2 if so.
749 * TODO: Other register than NBXCFG also needs this
750 * ECC information.
751 */
752 ecc = spd_read_byte(device, SPD_DIMM_CONFIG_TYPE);
753
754 /* Data width */
755 width = spd_read_byte(device, SPD_MODULE_DATA_WIDTH_LSB);
756
757 /* Exclude error checking data width from page size calculations */
758 if (ecc) {
759 value = spd_read_byte(device,
760 SPD_ERROR_CHECKING_SDRAM_WIDTH);
761 width -= value;
762 /* ### ECC */
763 /* Clear top 2 bits to help set up NBXCFG. */
764 ecc &= 0x3f;
765 } else {
766 /* Without ECC, top 2 bits should be 11. */
767 ecc |= 0xc0;
768 }
769
770 /* Calculate page size in bits. */
771 value = ((1 << col) * width);
772
773 /* Convert to KB. */
774 dra = (value >> 13);
775
776 /* Number of banks of DIMM (single or double sided). */
777 value = spd_read_byte(device, SPD_NUM_DIMM_BANKS);
778
779 /* Once we have dra, col is done and can be reused.
780 * So it's reused for number of banks.
781 */
782 col = spd_read_byte(device, SPD_NUM_BANKS_PER_SDRAM);
783
784 if (value == 1) {
785 /*
786 * Second bank of 1-bank DIMMs "doesn't have
787 * ECC" - or anything.
788 */
789 ecc |= 0x80;
790 if (dra == 2) {
791 dra = 0x0; /* 2KB */
792 } else if (dra == 4) {
793 dra = 0x1; /* 4KB */
794 } else if (dra == 8) {
795 dra = 0x2; /* 8KB */
796 } else {
797 dra = -1;
798 }
799 /*
800 * Sets a flag in PGPOL[BPR] if this DIMM has
801 * 4 banks per row.
802 */
803 if (col == 4)
804 bpr |= 0x40;
805 } else if (value == 2) {
806 if (dra == 2) {
807 dra = 0x0; /* 2KB */
808 } else if (dra == 4) {
809 dra = 0x05; /* 4KB */
810 } else if (dra == 8) {
811 dra = 0x0a; /* 8KB */
812 } else {
813 dra = -1;
814 }
815 /* Ditto */
816 if (col == 4)
817 bpr |= 0xc0;
818 } else {
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000819 print_err("# of banks of DIMM unsupported!\n");
820 die("HALT\n");
Keith Hui59356ca2010-03-06 18:16:25 +0000821 }
822 if (dra == -1) {
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000823 print_err("Page size not supported\n");
824 die("HALT\n");
Keith Hui59356ca2010-03-06 18:16:25 +0000825 }
826
827 /*
828 * 440BX supports asymmetrical dual-sided DIMMs,
829 * but can't handle DIMMs smaller than 8MB per
830 * side or larger than 128MB per side.
831 */
832 struct dimm_size sz = spd_get_dimm_size(device);
833 if ((sz.side1 < 8)) {
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000834 print_err("DIMMs smaller than 8MB per side\n"
835 "are not supported on this NB.\n");
836 die("HALT\n");
Keith Hui59356ca2010-03-06 18:16:25 +0000837 }
838 if ((sz.side1 > 128)) {
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000839 print_err("DIMMs > 128MB per side\n"
840 "are not supported on this NB\n");
841 die("HALT\n");
Keith Hui59356ca2010-03-06 18:16:25 +0000842 }
843
844 /* Divide size by 8 to set up the DRB registers. */
845 drb += (sz.side1 / 8);
846
847 /*
848 * Build the DRB for the next row in MSB so it gets
849 * placed in DRB[n+1] where it belongs when written
850 * as a 16-bit word.
851 */
852 drb &= 0xff;
853 drb |= (drb + (sz.side2 / 8)) << 8;
854 } else {
855#if 0
856 PRINT_DEBUG("No DIMM found in slot ");
857 PRINT_DEBUG_HEX8(i);
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000858 PRINT_DEBUG("\n");
Keith Hui59356ca2010-03-06 18:16:25 +0000859#endif
860
861 /* If there's no DIMM in the slot, set dra to 0x00. */
862 dra = 0x00;
863 ecc = 0xc0;
864 /* Still have to propagate DRB over. */
865 drb &= 0xff;
866 drb |= (drb << 8);
867 }
868
869 pci_write_config16(NB, DRB + (2 * i), drb);
870#if 0
871 PRINT_DEBUG("DRB has been set to 0x");
872 PRINT_DEBUG_HEX16(drb);
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000873 PRINT_DEBUG("\n");
Keith Hui59356ca2010-03-06 18:16:25 +0000874#endif
875
876 /* Brings the upper DRB back down to be base for
877 * DRB calculations for the next two rows.
878 */
879 drb >>= 8;
880
881 rps |= (dra & 0x0f) << (i * 4);
882 nbxecc = (nbxecc >> 2) | (ecc & 0xc0);
883 }
884
885 /* Set paging policy register. */
886 pci_write_config8(NB, PGPOL + 1, bpr);
887 PRINT_DEBUG("PGPOL[BPR] has been set to 0x");
888 PRINT_DEBUG_HEX8(bpr);
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000889 PRINT_DEBUG("\n");
Keith Hui59356ca2010-03-06 18:16:25 +0000890
891 /* Set DRAM row page size register. */
892 pci_write_config16(NB, RPS, rps);
893 PRINT_DEBUG("RPS has been set to 0x");
894 PRINT_DEBUG_HEX16(rps);
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000895 PRINT_DEBUG("\n");
Keith Hui59356ca2010-03-06 18:16:25 +0000896
897 /* ### ECC */
898 pci_write_config8(NB, NBXCFG + 3, nbxecc);
899 PRINT_DEBUG("NBXECC[31:24] has been set to 0x");
900 PRINT_DEBUG_HEX8(nbxecc);
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000901 PRINT_DEBUG("\n");
Keith Hui59356ca2010-03-06 18:16:25 +0000902
903 /* Set DRAMC[4:3] to proper memory type (EDO/SDRAM).
904 * TODO: Registered SDRAM support.
905 */
906 edosd &= 0x07;
907 if (edosd & 0x02) {
908 edosd |= 0x00;
909 } else if (edosd & 0x04) {
910 edosd |= 0x08;
911 }
912 edosd &= 0x18;
913
914 /* edosd is now in the form needed for DRAMC[4:3]. */
915 value = pci_read_config8(NB, DRAMC) & 0xe7;
916 value |= edosd;
917 pci_write_config8(NB, DRAMC, value);
918 PRINT_DEBUG("DRAMC has been set to 0x");
919 PRINT_DEBUG_HEX8(value);
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000920 PRINT_DEBUG("\n");
Keith Hui59356ca2010-03-06 18:16:25 +0000921}
922
Uwe Hermann1683cef2008-11-27 00:47:07 +0000923static void sdram_set_spd_registers(void)
Richard Smithcb8eab42006-07-24 04:25:47 +0000924{
Keith Hui59356ca2010-03-06 18:16:25 +0000925 /* Setup DRAM row boundary registers and other attributes. */
926 set_dram_row_attributes();
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000927
928 /* TODO: Set SDRAMC. */
Uwe Hermann8b643cea2008-12-09 16:36:12 +0000929 pci_write_config16(NB, SDRAMC, 0x0010); /* SDRAMPWR=1: 4 DIMM config */
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000930
Keith Hui59356ca2010-03-06 18:16:25 +0000931 /* TODO */
932 set_dram_buffer_strength();
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000933
934 /* TODO: Set PMCR? */
Uwe Hermann1683cef2008-11-27 00:47:07 +0000935 // pci_write_config8(NB, PMCR, 0x14);
936 pci_write_config8(NB, PMCR, 0x10);
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000937
938 /* TODO? */
Uwe Hermann1683cef2008-11-27 00:47:07 +0000939 pci_write_config8(NB, DRAMT, 0x03);
Richard Smithcb8eab42006-07-24 04:25:47 +0000940}
941
Uwe Hermann1683cef2008-11-27 00:47:07 +0000942static void sdram_enable(void)
Richard Smithcb8eab42006-07-24 04:25:47 +0000943{
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000944 int i;
Richard Smithcb8eab42006-07-24 04:25:47 +0000945
Uwe Hermann861f9642007-05-28 14:37:06 +0000946 /* 0. Wait until power/voltages and clocks are stable (200us). */
947 udelay(200);
Richard Smithcb8eab42006-07-24 04:25:47 +0000948
Uwe Hermann861f9642007-05-28 14:37:06 +0000949 /* 1. Apply NOP. Wait 200 clock cycles (200us should do). */
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000950 PRINT_DEBUG("RAM Enable 1: Apply NOP\n");
Uwe Hermann8b643cea2008-12-09 16:36:12 +0000951 do_ram_command(RAM_COMMAND_NOP);
Uwe Hermann861f9642007-05-28 14:37:06 +0000952 udelay(200);
Richard Smithcb8eab42006-07-24 04:25:47 +0000953
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000954 /* 2. Precharge all. Wait tRP. */
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000955 PRINT_DEBUG("RAM Enable 2: Precharge all\n");
Uwe Hermann8b643cea2008-12-09 16:36:12 +0000956 do_ram_command(RAM_COMMAND_PRECHARGE);
Uwe Hermann861f9642007-05-28 14:37:06 +0000957 udelay(1);
Richard Smithcb8eab42006-07-24 04:25:47 +0000958
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000959 /* 3. Perform 8 refresh cycles. Wait tRC each time. */
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000960 PRINT_DEBUG("RAM Enable 3: CBR\n");
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000961 for (i = 0; i < 8; i++) {
Uwe Hermann8b643cea2008-12-09 16:36:12 +0000962 do_ram_command(RAM_COMMAND_CBR);
Uwe Hermann861f9642007-05-28 14:37:06 +0000963 udelay(1);
Richard Smithcb8eab42006-07-24 04:25:47 +0000964 }
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000965
966 /* 4. Mode register set. Wait two memory cycles. */
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000967 PRINT_DEBUG("RAM Enable 4: Mode register set\n");
Uwe Hermann8b643cea2008-12-09 16:36:12 +0000968 do_ram_command(RAM_COMMAND_MRS);
Uwe Hermann861f9642007-05-28 14:37:06 +0000969 udelay(2);
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000970
971 /* 5. Normal operation. */
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000972 PRINT_DEBUG("RAM Enable 5: Normal operation\n");
Uwe Hermann8b643cea2008-12-09 16:36:12 +0000973 do_ram_command(RAM_COMMAND_NORMAL);
Uwe Hermann861f9642007-05-28 14:37:06 +0000974 udelay(1);
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000975
976 /* 6. Finally enable refresh. */
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000977 PRINT_DEBUG("RAM Enable 6: Enable refresh\n");
Uwe Hermann1683cef2008-11-27 00:47:07 +0000978 // pci_write_config8(NB, PMCR, 0x10);
979 spd_enable_refresh();
Uwe Hermann861f9642007-05-28 14:37:06 +0000980 udelay(1);
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000981
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000982 PRINT_DEBUG("Northbridge following SDRAM init:\n");
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000983 DUMPNORTH();
Richard Smithcb8eab42006-07-24 04:25:47 +0000984}