blob: ebcd368511104e366578e2fd13a0339ad169dd91 [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>
Uwe Hermann1a9c8922007-04-01 17:24:03 +000023#include <delay.h>
Carl-Daniel Hailfinger2ee67792008-10-01 12:52:52 +000024#include <stdlib.h>
Uwe Hermann1a9c8922007-04-01 17:24:03 +000025#include "i440bx.h"
Keith Hui59356ca2010-03-06 18:16:25 +000026#include "raminit.h"
Richard Smithcb8eab42006-07-24 04:25:47 +000027
Uwe Hermann1a9c8922007-04-01 17:24:03 +000028/*-----------------------------------------------------------------------------
29Macros and definitions.
30-----------------------------------------------------------------------------*/
Richard Smithcb8eab42006-07-24 04:25:47 +000031
Keith Huidf35cdc2010-09-20 23:41:37 +000032#define NB PCI_DEV(0, 0, 0)
33
Uwe Hermann1a9c8922007-04-01 17:24:03 +000034/* Debugging macros. */
Uwe Hermann01ce6012010-03-05 10:03:50 +000035#if CONFIG_DEBUG_RAM_SETUP
Uwe Hermann1a9c8922007-04-01 17:24:03 +000036#define PRINT_DEBUG(x) print_debug(x)
37#define PRINT_DEBUG_HEX8(x) print_debug_hex8(x)
38#define PRINT_DEBUG_HEX16(x) print_debug_hex16(x)
39#define PRINT_DEBUG_HEX32(x) print_debug_hex32(x)
Keith Huidf35cdc2010-09-20 23:41:37 +000040#define DUMPNORTH() dump_pci_device(NB)
Richard Smithcb8eab42006-07-24 04:25:47 +000041#else
Uwe Hermann941a6f02007-04-30 23:27:27 +000042#define PRINT_DEBUG(x)
Uwe Hermann1a9c8922007-04-01 17:24:03 +000043#define PRINT_DEBUG_HEX8(x)
44#define PRINT_DEBUG_HEX16(x)
45#define PRINT_DEBUG_HEX32(x)
46#define DUMPNORTH()
Richard Smithcb8eab42006-07-24 04:25:47 +000047#endif
48
Uwe Hermann1a9c8922007-04-01 17:24:03 +000049/* SDRAMC[7:5] - SDRAM Mode Select (SMS). */
50#define RAM_COMMAND_NORMAL 0x0
51#define RAM_COMMAND_NOP 0x1
52#define RAM_COMMAND_PRECHARGE 0x2
53#define RAM_COMMAND_MRS 0x3
54#define RAM_COMMAND_CBR 0x4
Richard Smithcb8eab42006-07-24 04:25:47 +000055
Uwe Hermann1a9c8922007-04-01 17:24:03 +000056/* Map the JEDEC SPD refresh rates (array index) to 440BX refresh rates as
57 * defined in DRAMC[2:0].
58 *
59 * [0] == Normal 15.625 us -> 15.6 us
60 * [1] == Reduced(.25X) 3.9 us -> 7.8 ns
61 * [2] == Reduced(.5X) 7.8 us -> 7.8 us
62 * [3] == Extended(2x) 31.3 us -> 31.2 us
63 * [4] == Extended(4x) 62.5 us -> 62.4 us
64 * [5] == Extended(8x) 125 us -> 124.8 us
65 */
66static const uint32_t refresh_rate_map[] = {
67 1, 5, 5, 2, 3, 4
68};
Richard Smithcb8eab42006-07-24 04:25:47 +000069
Uwe Hermann1a9c8922007-04-01 17:24:03 +000070/* Table format: register, bitmask, value. */
Keith Huidf35cdc2010-09-20 23:41:37 +000071static const u8 register_values[] = {
Uwe Hermann1a9c8922007-04-01 17:24:03 +000072 /* NBXCFG - NBX Configuration Register
Uwe Hermannf5a6fd22007-05-27 23:31:31 +000073 * 0x50 - 0x53
Uwe Hermann1a9c8922007-04-01 17:24:03 +000074 *
75 * [31:24] SDRAM Row Without ECC
76 * 0 = ECC components are populated in this row
77 * 1 = ECC components are not populated in this row
78 * [23:19] Reserved
79 * [18:18] Host Bus Fast Data Ready Enable (HBFDRE)
80 * Assertion of DRAM data on host bus occurs...
81 * 0 = ...one clock after sampling snoop results (default)
82 * 1 = ...on the same clock the snoop result is being sampled
83 * (this mode is faster by one clock cycle)
84 * [17:17] ECC - EDO static Drive mode
85 * 0 = Normal mode (default)
86 * 1 = ECC signals are always driven
87 * [16:16] IDSEL_REDIRECT
88 * 0 = IDSEL1 is allocated to this bridge (default)
89 * 1 = IDSEL7 is allocated to this bridge
90 * [15:15] WSC# Handshake Disable
91 * 1 = Uni-processor mode
92 * 0 = Dual-processor mode with external IOAPIC (default)
93 * [14:14] Intel Reserved
94 * [13:12] Host/DRAM Frequency
95 * 00 = 100 MHz
96 * 01 = Reserved
97 * 10 = 66 MHz
98 * 11 = Reserved
99 * [11:11] AGP to PCI Access Enable
100 * 1 = Enable
101 * 0 = Disable
102 * [10:10] PCI Agent to Aperture Access Disable
103 * 1 = Disable
104 * 0 = Enable (default)
105 * [09:09] Aperture Access Global Enable
106 * 1 = Enable
107 * 0 = Disable
108 * [08:07] DRAM Data Integrity Mode (DDIM)
109 * 00 = Non-ECC
110 * 01 = EC-only
111 * 10 = ECC Mode
112 * 11 = ECC Mode with hardware scrubbing enabled
113 * [06:06] ECC Diagnostic Mode Enable (EDME)
114 * 1 = Enable
115 * 0 = Normal operation mode (default)
116 * [05:05] MDA Present (MDAP)
117 * Works in conjunction with the VGA_EN bit.
118 * VGA_EN MDAP
119 * 0 x All VGA cycles are sent to PCI
120 * 1 0 All VGA cycles are sent to AGP
121 * 1 1 All VGA cycles are sent to AGP, except for
122 * cycles in the MDA range.
123 * [04:04] Reserved
124 * [03:03] USWC Write Post During I/O Bridge Access Enable (UWPIO)
125 * 1 = Enable
126 * 0 = Disable
127 * [02:02] In-Order Queue Depth (IOQD)
128 * 1 = In-order queue = maximum
129 * 0 = A7# is sampled asserted (i.e., 0)
130 * [01:00] Reserved
Richard Smithcb8eab42006-07-24 04:25:47 +0000131 */
Uwe Hermannbc3594732007-06-07 22:16:30 +0000132 NBXCFG + 0, 0x00, 0x0c,
Keith Huidf35cdc2010-09-20 23:41:37 +0000133 // TODO: Bit 15 should be 0 for multiprocessor boards
Uwe Hermannbc3594732007-06-07 22:16:30 +0000134 NBXCFG + 1, 0x00, 0x80,
135 NBXCFG + 2, 0x00, 0x00,
136 NBXCFG + 3, 0x00, 0xff,
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000137
138 /* DRAMC - DRAM Control Register
139 * 0x57
140 *
141 * [7:6] Reserved
142 * [5:5] Module Mode Configuration (MMCONFIG)
Keith Huidf35cdc2010-09-20 23:41:37 +0000143 * The combination of SDRAMPWR and this bit (which is set by an
144 * external strapping option) determine how CKE works.
145 * SDRAMPWR MMCONFIG
146 * 0 0 = 3 DIMM, CKE0[5:0] driven
147 * X 1 = 3 DIMM, CKE0 only
148 * 1 0 = 4 DIMM, GCKE only
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000149 * [4:3] DRAM Type (DT)
150 * 00 = EDO
151 * 01 = SDRAM
152 * 10 = Registered SDRAM
153 * 11 = Reserved
154 * Note: EDO, SDRAM and Registered SDRAM cannot be mixed.
155 * [2:0] DRAM Refresh Rate (DRR)
156 * 000 = Refresh disabled
157 * 001 = 15.6 us
158 * 010 = 31.2 us
159 * 011 = 62.4 us
160 * 100 = 124.8 us
161 * 101 = 249.6 us
162 * 110 = Reserved
163 * 111 = Reserved
Richard Smithcb8eab42006-07-24 04:25:47 +0000164 */
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000165 /* Choose SDRAM (not registered), and disable refresh for now. */
Uwe Hermannbc3594732007-06-07 22:16:30 +0000166 DRAMC, 0x00, 0x08,
Richard Smithcb8eab42006-07-24 04:25:47 +0000167
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000168 /*
169 * PAM[6:0] - Programmable Attribute Map Registers
Uwe Hermannf5a6fd22007-05-27 23:31:31 +0000170 * 0x59 - 0x5f
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000171 *
172 * 0x59 [3:0] Reserved
173 * 0x59 [5:4] 0xF0000 - 0xFFFFF BIOS area
174 * 0x5a [1:0] 0xC0000 - 0xC3FFF ISA add-on BIOS
175 * 0x5a [5:4] 0xC4000 - 0xC7FFF ISA add-on BIOS
176 * 0x5b [1:0] 0xC8000 - 0xCBFFF ISA add-on BIOS
177 * 0x5b [5:4] 0xCC000 - 0xCFFFF ISA add-on BIOS
178 * 0x5c [1:0] 0xD0000 - 0xD3FFF ISA add-on BIOS
179 * 0x5c [5:4] 0xD4000 - 0xD7FFF ISA add-on BIOS
180 * 0x5d [1:0] 0xD8000 - 0xDBFFF ISA add-on BIOS
181 * 0x5d [5:4] 0xDC000 - 0xDFFFF ISA add-on BIOS
182 * 0x5e [1:0] 0xE0000 - 0xE3FFF BIOS entension
183 * 0x5e [5:4] 0xE4000 - 0xE7FFF BIOS entension
184 * 0x5f [1:0] 0xE8000 - 0xEBFFF BIOS entension
185 * 0x5f [5:4] 0xEC000 - 0xEFFFF BIOS entension
186 *
187 * Bit assignment:
188 * 00 = DRAM Disabled (all access goes to memory mapped I/O space)
189 * 01 = Read Only (Reads to DRAM, writes to memory mapped I/O space)
190 * 10 = Write Only (Writes to DRAM, reads to memory mapped I/O space)
191 * 11 = Read/Write (all access goes to DRAM)
192 */
Keith Hui59356ca2010-03-06 18:16:25 +0000193
194 /*
195 * Map all legacy regions to RAM (read/write). This is required if
196 * you want to use the RAM area from 768 KB - 1 MB. If the PAM
197 * registers are not set here appropriately, the RAM in that region
198 * will not be accessible, thus a RAM check of it will also fail.
199 *
200 * TODO: This was set in sdram_set_spd_registers().
201 * Test if it still works when set here.
202 */
203 PAM0, 0x00, 0x30,
204 PAM1, 0x00, 0x33,
205 PAM2, 0x00, 0x33,
206 PAM3, 0x00, 0x33,
207 PAM4, 0x00, 0x33,
208 PAM5, 0x00, 0x33,
209 PAM6, 0x00, 0x33,
Richard Smithcb8eab42006-07-24 04:25:47 +0000210
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000211 /* DRB[0:7] - DRAM Row Boundary Registers
212 * 0x60 - 0x67
213 *
214 * An array of 8 byte registers, which hold the ending memory address
Anders Jenbo0e1e8062010-04-27 06:35:31 +0000215 * assigned to each pair of DIMMs, in 8MB granularity.
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000216 *
217 * 0x60 DRB0 = Total memory in row0 (in 8 MB)
218 * 0x61 DRB1 = Total memory in row0+1 (in 8 MB)
219 * 0x62 DRB2 = Total memory in row0+1+2 (in 8 MB)
220 * 0x63 DRB3 = Total memory in row0+1+2+3 (in 8 MB)
221 * 0x64 DRB4 = Total memory in row0+1+2+3+4 (in 8 MB)
222 * 0x65 DRB5 = Total memory in row0+1+2+3+4+5 (in 8 MB)
223 * 0x66 DRB6 = Total memory in row0+1+2+3+4+5+6 (in 8 MB)
224 * 0x67 DRB7 = Total memory in row0+1+2+3+4+5+6+7 (in 8 MB)
225 */
Uwe Hermannf5a6fd22007-05-27 23:31:31 +0000226 /* Set the DRBs to zero for now, this will be fixed later. */
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000227 DRB0, 0x00, 0x00,
228 DRB1, 0x00, 0x00,
229 DRB2, 0x00, 0x00,
230 DRB3, 0x00, 0x00,
231 DRB4, 0x00, 0x00,
232 DRB5, 0x00, 0x00,
233 DRB6, 0x00, 0x00,
234 DRB7, 0x00, 0x00,
235
236 /* FDHC - Fixed DRAM Hole Control Register
237 * 0x68
238 *
239 * Controls two fixed DRAM holes: 512 KB - 640 KB and 15 MB - 16 MB.
240 *
241 * [7:6] Hole Enable (HEN)
242 * 00 = None
243 * 01 = 512 KB - 640 KB (128 KB)
244 * 10 = 15 MB - 16 MB (1 MB)
245 * 11 = Reserved
246 * [5:0] Reserved
247 */
248 /* No memory holes. */
249 FDHC, 0x00, 0x00,
250
251 /* RPS - SDRAM Row Page Size Register
252 * 0x74 - 0x75
253 *
254 * Sets the row page size for SDRAM. For EDO memory, the page
255 * size is fixed at 2 KB.
256 *
Keith Huidf35cdc2010-09-20 23:41:37 +0000257 * Bits[1:0] Page Size
258 * 00 2 KB
259 * 01 4 KB
260 * 10 8 KB
261 * 11 Reserved
262 *
263 * RPS bits Corresponding DRB register
264 * [01:00] DRB[0], row 0
265 * [03:02] DRB[1], row 1
266 * [05:04] DRB[2], row 2
267 * [07:06] DRB[3], row 3
268 * [09:08] DRB[4], row 4
269 * [11:10] DRB[5], row 5
270 * [13:12] DRB[6], row 6
271 * [15:14] DRB[7], row 7
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000272 */
Keith Huidf35cdc2010-09-20 23:41:37 +0000273 /* Power on defaults to 2KB. Will be set later. */
274 // RPS + 0, 0x00, 0x00,
275 // RPS + 1, 0x00, 0x00,
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000276
277 /* SDRAMC - SDRAM Control Register
Uwe Hermann7ea18cf2007-05-04 00:51:17 +0000278 * 0x76 - 0x77
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000279 *
280 * [15:10] Reserved
281 * [09:08] Idle/Pipeline DRAM Leadoff Timing (IPDLT)
282 * 00 = Illegal
283 * 01 = Add a clock delay to the lead-off clock count
Keith Huidf35cdc2010-09-20 23:41:37 +0000284 * 1x = Illegal
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000285 * [07:05] SDRAM Mode Select (SMS)
286 * 000 = Normal SDRAM Operation (default)
287 * 001 = NOP Command Enable
288 * 010 = All Banks Precharge Enable
289 * 011 = Mode Register Set Enable
290 * 100 = CBR Enable
291 * 101 = Reserved
292 * 110 = Reserved
293 * 111 = Reserved
294 * [04:04] SDRAMPWR
295 * 0 = 3 DIMM configuration
296 * 1 = 4 DIMM configuration
297 * [03:03] Leadoff Command Timing (LCT)
298 * 0 = 4 CS# Clock
299 * 1 = 3 CS# Clock
300 * [02:02] CAS# Latency (CL)
301 * 0 = 3 DCLK CAS# latency
302 * 1 = 2 DCLK CAS# latency
303 * [01:01] SDRAM RAS# to CAS# Delay (SRCD)
304 * 0 = 3 clocks between a row activate and a read or write cmd.
305 * 1 = 2 clocks between a row activate and a read or write cmd.
306 * [00:00] SDRAM RAS# Precharge (SRP)
307 * 0 = 3 clocks of RAS# precharge
308 * 1 = 2 clocks of RAS# precharge
309 */
Keith Hui9c1e1f02010-03-13 20:16:48 +0000310#if CONFIG_SDRAMPWR_4DIMM
311 SDRAMC + 0, 0x00, 0x10, /* The board has 4 DIMM slots. */
312#else
Keith Huidf35cdc2010-09-20 23:41:37 +0000313 SDRAMC + 0, 0x00, 0x00, /* The board has 3 DIMM slots. */
Keith Hui9c1e1f02010-03-13 20:16:48 +0000314#endif
Mats Erik Andersson45db3662008-09-30 04:52:29 +0000315 SDRAMC + 1, 0x00, 0x00,
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000316
317 /* PGPOL - Paging Policy Register
318 * 0x78 - 0x79
319 *
320 * [15:08] Banks per Row (BPR)
Keith Huidf35cdc2010-09-20 23:41:37 +0000321 * Each bit in this field corresponds to one row of the memory
322 * array. Bit 15 corresponds to row 7 while bit 8 corresponds
323 * to row 0. Bits for empty rows are "don't care".
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000324 * 0 = 2 banks
325 * 1 = 4 banks
326 * [07:05] Reserved
327 * [04:04] Intel Reserved
328 * [03:00] DRAM Idle Timer (DIT)
329 * 0000 = 0 clocks
330 * 0001 = 2 clocks
331 * 0010 = 4 clocks
332 * 0011 = 8 clocks
333 * 0100 = 10 clocks
334 * 0101 = 12 clocks
335 * 0110 = 16 clocks
336 * 0111 = 32 clocks
337 * 1xxx = Infinite (pages are not closed for idle condition)
338 */
Uwe Hermannbc3594732007-06-07 22:16:30 +0000339 PGPOL + 0, 0x00, 0x00,
340 PGPOL + 1, 0x00, 0xff,
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000341
342 /* PMCR - Power Management Control Register
343 * 0x7a
344 *
345 * [07:07] Power Down SDRAM Enable (PDSE)
346 * 1 = Enable
347 * 0 = Disable
348 * [06:06] ACPI Control Register Enable (SCRE)
349 * 1 = Enable
350 * 0 = Disable (default)
351 * [05:05] Suspend Refresh Type (SRT)
352 * 1 = Self refresh mode
353 * 0 = CBR fresh mode
354 * [04:04] Normal Refresh Enable (NREF_EN)
355 * 1 = Enable
356 * 0 = Disable
357 * [03:03] Quick Start Mode (QSTART)
358 * 1 = Quick start mode for the processor is enabled
359 * [02:02] Gated Clock Enable (GCLKEN)
360 * 1 = Enable
361 * 0 = Disable
362 * [01:01] AGP Disable (AGP_DIS)
363 * 1 = Disable
364 * 0 = Enable
365 * [00:00] CPU reset without PCIRST enable (CRst_En)
366 * 1 = Enable
367 * 0 = Disable
368 */
369 /* Enable normal refresh and the gated clock. */
370 // TODO: Only do this later?
371 // PMCR, 0x00, 0x14,
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000372 PMCR, 0x00, 0x00,
Keith Hui59356ca2010-03-06 18:16:25 +0000373
374 /* Enable SCRR.SRRAEN and let BX choose the SRR. */
375 SCRR + 1, 0x00, 0x10,
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000376};
377
378/*-----------------------------------------------------------------------------
379SDRAM configuration functions.
380-----------------------------------------------------------------------------*/
381
382/**
383 * Send the specified RAM command to all DIMMs.
384 *
Uwe Hermann8b643cea2008-12-09 16:36:12 +0000385 * @param command The RAM command to send to the DIMM(s).
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000386 */
Uwe Hermann8b643cea2008-12-09 16:36:12 +0000387static void do_ram_command(u32 command)
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000388{
Uwe Hermann8b643cea2008-12-09 16:36:12 +0000389 int i, caslatency;
390 u8 dimm_start, dimm_end;
391 u16 reg16;
392 u32 addr, addr_offset;
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000393
394 /* Configure the RAM command. */
Uwe Hermann8b643cea2008-12-09 16:36:12 +0000395 reg16 = pci_read_config16(NB, SDRAMC);
396 reg16 &= 0xff1f; /* Clear bits 7-5. */
397 reg16 |= (u16) (command << 5); /* Write command into bits 7-5. */
398 pci_write_config16(NB, SDRAMC, reg16);
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000399
Uwe Hermann8b643cea2008-12-09 16:36:12 +0000400 /*
401 * RAM_COMMAND_NORMAL affects only the memory controller and
402 * doesn't need to be "sent" to the DIMMs.
403 */
404 if (command == RAM_COMMAND_NORMAL)
405 return;
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000406
Uwe Hermann8b643cea2008-12-09 16:36:12 +0000407 /* Send the RAM command to each row of memory. */
408 dimm_start = 0;
409 for (i = 0; i < (DIMM_SOCKETS * 2); i++) {
Keith Hui59356ca2010-03-06 18:16:25 +0000410 addr_offset = 0;
411 caslatency = 3; /* TODO: Dynamically get CAS latency later. */
Uwe Hermann8b643cea2008-12-09 16:36:12 +0000412 if (command == RAM_COMMAND_MRS) {
413 /*
414 * MAA[12:11,9:0] must be inverted when sent to DIMM
415 * 2 or 3 (no inversion if sent to DIMM 0 or 1).
416 */
417 if ((i >= 0 && i <= 3) && caslatency == 3)
418 addr_offset = 0x1d0;
419 if ((i >= 4 && i <= 7) && caslatency == 3)
420 addr_offset = 0x1e28;
421 if ((i >= 0 && i <= 3) && caslatency == 2)
422 addr_offset = 0x150;
423 if ((i >= 4 && i <= 7) && caslatency == 2)
424 addr_offset = 0x1ea8;
425 }
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000426
Uwe Hermann8b643cea2008-12-09 16:36:12 +0000427 dimm_end = pci_read_config8(NB, DRB + i);
428
429 addr = (dimm_start * 8 * 1024 * 1024) + addr_offset;
430 if (dimm_end > dimm_start) {
431#if 0
432 PRINT_DEBUG(" Sending RAM command 0x");
433 PRINT_DEBUG_HEX16(reg16);
434 PRINT_DEBUG(" to 0x");
435 PRINT_DEBUG_HEX32(addr);
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000436 PRINT_DEBUG("\n");
Uwe Hermann8b643cea2008-12-09 16:36:12 +0000437#endif
438
439 read32(addr);
440 }
441
442 /* Set the start of the next DIMM. */
443 dimm_start = dimm_end;
444 }
Richard Smithcb8eab42006-07-24 04:25:47 +0000445}
446
Keith Hui59356ca2010-03-06 18:16:25 +0000447static void set_dram_buffer_strength(void)
448{
Keith Huib48ba662010-03-17 02:15:07 +0000449 /* To give some breathing room for romcc,
Anders Jenbo0e1e8062010-04-27 06:35:31 +0000450 * mbsc0 doubles as drb
Keith Huib48ba662010-03-17 02:15:07 +0000451 * mbsc1 doubles as drb1
452 * mbfs0 doubles as i and reg
Keith Hui59356ca2010-03-06 18:16:25 +0000453 */
Keith Huib48ba662010-03-17 02:15:07 +0000454 uint8_t mbsc0,mbsc1,mbsc3,mbsc4,mbfs0,mbfs2,fsb;
Keith Hui59356ca2010-03-06 18:16:25 +0000455
Anders Jenbo0e1e8062010-04-27 06:35:31 +0000456 /* Tally how many rows between rows 0-3 and rows 4-7 are populated.
Keith Huib48ba662010-03-17 02:15:07 +0000457 * This determines how to program MBFS and MBSC.
458 */
459 uint8_t dimm03 = 0;
460 uint8_t dimm47 = 0;
461
462 mbsc0 = 0;
463 for (mbfs0 = DRB0; mbfs0 <= DRB7; mbfs0++) {
464 mbsc1 = pci_read_config8(NB, mbfs0);
465 if (mbsc0 != mbsc1) {
466 if (mbfs0 <= DRB3) {
467 dimm03++;
468 } else {
469 dimm47++;
470 }
471 mbsc0 = mbsc1;
472 }
473 }
474
Keith Huidf35cdc2010-09-20 23:41:37 +0000475 /* Algorithm bitmap for programming MBSC[39:0] and MBFS[23:0].
Keith Huib48ba662010-03-17 02:15:07 +0000476 *
Keith Huidf35cdc2010-09-20 23:41:37 +0000477 * The 440BX datasheet says buffer frequency is independent from bus
478 * frequency and mismatch both ways are possible. This is how it is
479 * programmed in the ASUS P2B-LS mainboard.
Keith Huib48ba662010-03-17 02:15:07 +0000480 *
481 * There are four main conditions to check when programming DRAM buffer
482 * frequency and strength:
483 *
484 * a: >2 rows populated across DIMM0,1
485 * b: >2 rows populated across DIMM2,3
486 * c: >4 rows populated across all DIMM slots
487 * and either one of:
488 * 1: NBXCFG[13] strapped as 100MHz, or
489 * 6: NBXCFG[13] strapped as 66MHz
490 *
491 * CKE0/FENA ----------------------------------------------------------+
492 * CKE1/GCKE -------------------[ MBFS ]------------------------+|
493 * DQMA/CASA[764320]# ----------[ 0 = 66MHz ]-----------------------+||
494 * DQMB1/CASB1# ----------------[ 1 = 100MHz ]----------------------+|||
495 * DQMB5/CASB5# ---------------------------------------------------+||||
496 * DQMA1/CASA1# --------------------------------------------------+|||||
497 * DQMA5/CASA5# -------------------------------------------------+||||||
498 * CSA0-5#,CSB0-5# ----------------------------------------++++++|||||||
499 * CSA6#/CKE2# -------------------------------------------+|||||||||||||
500 * CSB6#/CKE4# ------------------------------------------+||||||||||||||
501 * CSA7#/CKE3# -----------------------------------------+|||||||||||||||
502 * CSB7#/CKE5# ----------------------------------------+||||||||||||||||
503 * MECC[7:0] #2/#1 (100MHz) -------------------------++|||||||||||||||||
504 * MD[63:0] #2/#1 (100MHz) ------------------------++|||||||||||||||||||
505 * MAB[12:11,9:0]#,MAB[13,10],WEB#,SRASB#,SCASB# -+|||||||||||||||||||||
506 * MAA[13:0],WEA#,SRASA#,SCASA# -----------------+||||||||||||||||||||||
507 * Reserved ------------------------------------+|||||||||||||||||||||||
508 * ||||||||||||||||||||||||
509 * 3 32 21 10 0 * 2 21 10 0
510 * 9876543210987654321098765432109876543210 * 321098765432109876543210
511 * a 10------------------------1010---------- * -1---------------11----- a
512 *!a 11------------------------1111---------- * -0---------------00----- !a
513 * b --10--------------------------1010------ * --1----------------11--- b
514 *!b --11--------------------------1111------ * --0----------------00--- !b
515 * c ----------------------------------1100-- * ----------------------1- c
516 *!c ----------------------------------1011-- * ----------------------0- !c
517 * 1 ----1010101000000000000000------------00 * ---11111111111111----1-0 1
518 * 6 ----000000000000000000000010101010----00 * ---1111111111111100000-0 6
519 * | | | | | | | | | | ||||||| | | | | | |
520 * | | | | | | | | | | ||||||| | | | | | +- CKE0/FENA
521 * | | | | | | | | | | ||||||| | | | | +--- CKE1/GCKE
522 * | | | | | | | | | | ||||||| | | | +----- DQMA/CASA[764320]#
523 * | | | | | | | | | | ||||||| | | +------- DQMB1/CASB1#
524 * | | | | | | | | | | ||||||| | +--------- DQMB5/CASB5#
525 * | | | | | | | | | | ||||||| +----------- DQMA1/CASA1#
526 * | | | | | | | | | | ||||||+------------- DQMA5/CASA5#
527 * | | | | | | | | | | ++++++-------------- CSA0-5#,CSB0-5# [ 0=1x;1=2x ]
528 * | | | | | | | | | +--------------------- CSA6#/CKE2#
529 * | | | | | | | | +---[ MBSC ]------ CSB6#/CKE4#
530 * | | | | | | | +-----[ 00 = 1x ]------ CSA7#/CKE3#
531 * | | | | | | +-------[ 01 invalid ]------ CSB7#/CKE5#
532 * | | | | | +---------[ 10 = 2x ]------ MECC[7:0] #1 (2x)
533 * | | | | +-----------[ 11 = 3x ]------ MECC[7:0] #2 (2x)
534 * | | | +--------------------------------- MD[63:0] #1 (2x)
535 * | | +----------------------------------- MD[63:0] #2 (2x)
536 * | +------------------------------------- MAB[12:11,9:0]#,MAB[13,10],WEB#,SRASB#,SCASB#
537 * +--------------------------------------- MAA[13:0],WEA#,SRASA#,SCASA#
538 * MBSC[47:40] and MBFS[23] are reserved.
539 *
Keith Huidf35cdc2010-09-20 23:41:37 +0000540 * This algorithm is checked against the ASUS P2B-LS (which has
541 * 4 DIMM slots) factory BIOS.
Keith Huib48ba662010-03-17 02:15:07 +0000542 * Therefore it assumes a board with 4 slots, and will need testing
543 * on boards with 3 DIMM slots.
544 */
Anders Jenbo0e1e8062010-04-27 06:35:31 +0000545
Keith Huib48ba662010-03-17 02:15:07 +0000546 mbsc0 = 0x80;
547 mbsc1 = 0x2a;
548 mbfs2 = 0x1f;
549 if (pci_read_config8(NB, NBXCFG + 1) & 0x30) {
550 fsb = 66;
551 mbsc3 = 0x00;
552 mbsc4 = 0x00;
553 mbfs0 = 0x80;
554 } else {
555 fsb = 100;
556 mbsc3 = 0xa0;
557 mbsc4 = 0x0a;
558 mbfs0 = 0x84;
559 }
Anders Jenbo0e1e8062010-04-27 06:35:31 +0000560
561 if (dimm03 > 2) {
562 mbsc4 = mbsc4 | 0x80;
Keith Huib48ba662010-03-17 02:15:07 +0000563 mbsc1 = mbsc1 | 0x28;
564 mbfs2 = mbfs2 | 0x40;
565 mbfs0 = mbfs0 | 0x60;
Anders Jenbo0e1e8062010-04-27 06:35:31 +0000566 } else {
567 mbsc4 = mbsc4 | 0xc0;
Keith Huib48ba662010-03-17 02:15:07 +0000568 if (fsb == 100) {
569 mbsc1 = mbsc1 | 0x3c;
570 }
Anders Jenbo0e1e8062010-04-27 06:35:31 +0000571 }
572 if (dimm47 > 2) {
573 mbsc4 = mbsc4 | 0x20;
574 mbsc1 = mbsc1 | 0x02;
Keith Huib48ba662010-03-17 02:15:07 +0000575 mbsc0 = mbsc0 | 0x80;
576 mbfs2 = mbfs2 | 0x20;
577 mbfs0 = mbfs0 | 0x18;
Anders Jenbo0e1e8062010-04-27 06:35:31 +0000578 } else {
Keith Huib48ba662010-03-17 02:15:07 +0000579 mbsc4 = mbsc4 | 0x30;
580 if (fsb == 100) {
Anders Jenbo0e1e8062010-04-27 06:35:31 +0000581 mbsc1 = mbsc1 | 0x03;
Keith Huib48ba662010-03-17 02:15:07 +0000582 mbsc0 = mbsc0 | 0xc0;
583 }
584 }
Anders Jenbo0e1e8062010-04-27 06:35:31 +0000585 if ((dimm03 + dimm47) > 4) {
Keith Huib48ba662010-03-17 02:15:07 +0000586 mbsc0 = mbsc0 | 0x30;
587 mbfs0 = mbfs0 | 0x02;
Anders Jenbo0e1e8062010-04-27 06:35:31 +0000588 } else {
589 mbsc0 = mbsc0 | 0x2c;
Keith Huib48ba662010-03-17 02:15:07 +0000590 }
591
592 pci_write_config8(NB, MBSC + 0, mbsc0);
593 pci_write_config8(NB, MBSC + 1, mbsc1);
594 pci_write_config8(NB, MBSC + 2, 0x00);
595 pci_write_config8(NB, MBSC + 3, mbsc3);
596 pci_write_config8(NB, MBSC + 4, mbsc4);
597 pci_write_config8(NB, MBFS + 0, mbfs0);
598 pci_write_config8(NB, MBFS + 1, 0xff);
599 pci_write_config8(NB, MBFS + 2, mbfs2);
Keith Hui59356ca2010-03-06 18:16:25 +0000600}
601
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000602/*-----------------------------------------------------------------------------
603DIMM-independant configuration functions.
604-----------------------------------------------------------------------------*/
Richard Smithcb8eab42006-07-24 04:25:47 +0000605
Uwe Hermann1683cef2008-11-27 00:47:07 +0000606static void spd_enable_refresh(void)
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000607{
608 int i, value;
609 uint8_t reg;
610
Uwe Hermann1683cef2008-11-27 00:47:07 +0000611 reg = pci_read_config8(NB, DRAMC);
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000612
613 for (i = 0; i < DIMM_SOCKETS; i++) {
Uwe Hermann1683cef2008-11-27 00:47:07 +0000614 value = spd_read_byte(DIMM_SPD_BASE + i, SPD_REFRESH);
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000615 if (value < 0)
616 continue;
617 reg = (reg & 0xf8) | refresh_rate_map[(value & 0x7f)];
618
619 PRINT_DEBUG(" Enabling refresh (DRAMC = 0x");
620 PRINT_DEBUG_HEX8(reg);
621 PRINT_DEBUG(") for DIMM ");
622 PRINT_DEBUG_HEX8(i);
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000623 PRINT_DEBUG("\n");
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000624 }
625
Uwe Hermann1683cef2008-11-27 00:47:07 +0000626 pci_write_config8(NB, DRAMC, reg);
Richard Smithcb8eab42006-07-24 04:25:47 +0000627}
628
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000629/*-----------------------------------------------------------------------------
630Public interface.
631-----------------------------------------------------------------------------*/
632
Uwe Hermann1683cef2008-11-27 00:47:07 +0000633static void sdram_set_registers(void)
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000634{
635 int i, max;
Uwe Hermannbc3594732007-06-07 22:16:30 +0000636 uint8_t reg;
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000637
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000638 PRINT_DEBUG("Northbridge prior to SDRAM init:\n");
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000639 DUMPNORTH();
640
Carl-Daniel Hailfinger2ee67792008-10-01 12:52:52 +0000641 max = ARRAY_SIZE(register_values);
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000642
Uwe Hermannf5a6fd22007-05-27 23:31:31 +0000643 /* Set registers as specified in the register_values[] array. */
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000644 for (i = 0; i < max; i += 3) {
Uwe Hermann1683cef2008-11-27 00:47:07 +0000645 reg = pci_read_config8(NB, register_values[i]);
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000646 reg &= register_values[i + 1];
647 reg |= register_values[i + 2] & ~(register_values[i + 1]);
Uwe Hermann1683cef2008-11-27 00:47:07 +0000648 pci_write_config8(NB, register_values[i], reg);
Keith Hui59356ca2010-03-06 18:16:25 +0000649#if 0
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000650 PRINT_DEBUG(" Set register 0x");
Uwe Hermannbc3594732007-06-07 22:16:30 +0000651 PRINT_DEBUG_HEX8(register_values[i]);
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000652 PRINT_DEBUG(" to 0x");
Uwe Hermannbc3594732007-06-07 22:16:30 +0000653 PRINT_DEBUG_HEX8(reg);
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000654 PRINT_DEBUG("\n");
Keith Hui59356ca2010-03-06 18:16:25 +0000655#endif
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000656 }
657}
658
Keith Hui59356ca2010-03-06 18:16:25 +0000659struct dimm_size {
660 unsigned long side1;
661 unsigned long side2;
662};
663
664static struct dimm_size spd_get_dimm_size(unsigned int device)
665{
666 struct dimm_size sz;
667 int i, module_density, dimm_banks;
668 sz.side1 = 0;
669 module_density = spd_read_byte(device, SPD_DENSITY_OF_EACH_ROW_ON_MODULE);
670 dimm_banks = spd_read_byte(device, SPD_NUM_DIMM_BANKS);
671
672 /* Find the size of side1. */
673 /* Find the larger value. The larger value is always side1. */
674 for (i = 512; i >= 0; i >>= 1) {
675 if ((module_density & i) == i) {
676 sz.side1 = i;
677 break;
678 }
679 }
680
681 /* Set to 0 in case it's single sided. */
682 sz.side2 = 0;
683
684 /* Test if it's a dual-sided DIMM. */
685 if (dimm_banks > 1) {
686 /* Test if there's a second value. If so it's asymmetrical. */
687 if (module_density != i) {
688 /*
689 * Find second value, picking up where we left off.
690 * i >>= 1 done initially to make sure we don't get
691 * the same value again.
692 */
693 for (i >>= 1; i >= 0; i >>= 1) {
694 if (module_density == (sz.side1 | i)) {
695 sz.side2 = i;
696 break;
697 }
698 }
699 /* If not, it's symmetrical. */
700 } else {
701 sz.side2 = sz.side1;
702 }
703 }
704
705 /*
706 * SPD byte 31 is the memory size divided by 4 so we
707 * need to muliply by 4 to get the total size.
708 */
709 sz.side1 *= 4;
710 sz.side2 *= 4;
711
Anders Jenbo771b0e42010-04-27 08:45:30 +0000712 /* It is possible to partially use larger then supported
713 * modules by setting them to a supported size.
714 */
715 if(sz.side1 > 128) {
716 PRINT_DEBUG("Side1 was 0x");
717 PRINT_DEBUG_HEX16(sz.side1);
718 PRINT_DEBUG(" but only 128MB will be used.\n");
719 sz.side1 = 128;
720
721 if(sz.side2 > 128) {
722 PRINT_DEBUG("Side2 was 0x");
723 PRINT_DEBUG_HEX16(sz.side2);
724 PRINT_DEBUG(" but only 128MB will be used.\n");
725 sz.side2 = 128;
726 }
727 }
728
Keith Hui59356ca2010-03-06 18:16:25 +0000729 return sz;
730}
731/*
732 * Sets DRAM attributes one DIMM at a time, based on SPD data.
733 * Northbridge settings that are set: NBXCFG[31:24], DRB0-DRB7, RPS, DRAMC.
734 */
735static void set_dram_row_attributes(void)
736{
737 int i, dra, drb, col, width, value, rps, edosd, ecc, nbxecc;
738 u8 bpr; /* Top 8 bits of PGPOL */
739
740 edosd = 0;
741 rps = 0;
742 drb = 0;
743 bpr = 0;
744 nbxecc = 0xff;
745
746 for (i = 0; i < DIMM_SOCKETS; i++) {
747 unsigned int device;
748 device = DIMM_SPD_BASE + i;
749 bpr >>= 2;
750
751 /* First check if a DIMM is actually present. */
752 value = spd_read_byte(device, SPD_MEMORY_TYPE);
753 /* This is 440BX! We do EDO too! */
754 if (value == SPD_MEMORY_TYPE_EDO
755 || value == SPD_MEMORY_TYPE_SDRAM) {
756
757 PRINT_DEBUG("Found ");
758 if (value == SPD_MEMORY_TYPE_EDO) {
Anders Jenbo0e1e8062010-04-27 06:35:31 +0000759 edosd |= 0x02;
760 } else if (value == SPD_MEMORY_TYPE_SDRAM) {
761 edosd |= 0x04;
Keith Hui59356ca2010-03-06 18:16:25 +0000762 }
763 PRINT_DEBUG("DIMM in slot ");
764 PRINT_DEBUG_HEX8(i);
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000765 PRINT_DEBUG("\n");
Keith Hui59356ca2010-03-06 18:16:25 +0000766
Anders Jenbo0e1e8062010-04-27 06:35:31 +0000767 if (edosd == 0x06) {
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000768 print_err("Mixing EDO/SDRAM unsupported!\n");
769 die("HALT\n");
Keith Hui59356ca2010-03-06 18:16:25 +0000770 }
771
772 /* "DRA" is our RPS for the two rows on this DIMM. */
773 dra = 0;
774
775 /* Columns */
776 col = spd_read_byte(device, SPD_NUM_COLUMNS);
777
778 /*
779 * Is this an ECC DIMM? Actually will be a 2 if so.
780 * TODO: Other register than NBXCFG also needs this
781 * ECC information.
782 */
783 ecc = spd_read_byte(device, SPD_DIMM_CONFIG_TYPE);
784
785 /* Data width */
786 width = spd_read_byte(device, SPD_MODULE_DATA_WIDTH_LSB);
Anders Jenbo0e1e8062010-04-27 06:35:31 +0000787
Keith Hui59356ca2010-03-06 18:16:25 +0000788 /* Exclude error checking data width from page size calculations */
789 if (ecc) {
790 value = spd_read_byte(device,
791 SPD_ERROR_CHECKING_SDRAM_WIDTH);
792 width -= value;
793 /* ### ECC */
794 /* Clear top 2 bits to help set up NBXCFG. */
795 ecc &= 0x3f;
796 } else {
797 /* Without ECC, top 2 bits should be 11. */
798 ecc |= 0xc0;
799 }
800
801 /* Calculate page size in bits. */
802 value = ((1 << col) * width);
803
804 /* Convert to KB. */
805 dra = (value >> 13);
806
807 /* Number of banks of DIMM (single or double sided). */
808 value = spd_read_byte(device, SPD_NUM_DIMM_BANKS);
809
810 /* Once we have dra, col is done and can be reused.
811 * So it's reused for number of banks.
812 */
813 col = spd_read_byte(device, SPD_NUM_BANKS_PER_SDRAM);
814
815 if (value == 1) {
816 /*
817 * Second bank of 1-bank DIMMs "doesn't have
818 * ECC" - or anything.
819 */
820 ecc |= 0x80;
821 if (dra == 2) {
822 dra = 0x0; /* 2KB */
823 } else if (dra == 4) {
824 dra = 0x1; /* 4KB */
825 } else if (dra == 8) {
826 dra = 0x2; /* 8KB */
Anders Jenbo771b0e42010-04-27 08:45:30 +0000827 } else if (dra >= 16) {
828 /* Page sizes larger than supported are
829 * set to 8KB to use module partially.
830 */
831 PRINT_DEBUG("Page size forced to 8KB.\n");
832 dra = 0x2; /* 8KB */
Keith Hui59356ca2010-03-06 18:16:25 +0000833 } else {
834 dra = -1;
835 }
836 /*
837 * Sets a flag in PGPOL[BPR] if this DIMM has
838 * 4 banks per row.
839 */
840 if (col == 4)
841 bpr |= 0x40;
842 } else if (value == 2) {
843 if (dra == 2) {
844 dra = 0x0; /* 2KB */
845 } else if (dra == 4) {
846 dra = 0x05; /* 4KB */
847 } else if (dra == 8) {
848 dra = 0x0a; /* 8KB */
Anders Jenbo771b0e42010-04-27 08:45:30 +0000849 } else if (dra >= 16) {
850 /* Ditto */
851 PRINT_DEBUG("Page size forced to 8KB.\n");
852 dra = 0x0a; /* 8KB */
Keith Hui59356ca2010-03-06 18:16:25 +0000853 } else {
854 dra = -1;
855 }
856 /* Ditto */
857 if (col == 4)
858 bpr |= 0xc0;
859 } else {
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000860 print_err("# of banks of DIMM unsupported!\n");
861 die("HALT\n");
Keith Hui59356ca2010-03-06 18:16:25 +0000862 }
863 if (dra == -1) {
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000864 print_err("Page size not supported\n");
865 die("HALT\n");
Keith Hui59356ca2010-03-06 18:16:25 +0000866 }
867
868 /*
869 * 440BX supports asymmetrical dual-sided DIMMs,
870 * but can't handle DIMMs smaller than 8MB per
Anders Jenbo771b0e42010-04-27 08:45:30 +0000871 * side.
Keith Hui59356ca2010-03-06 18:16:25 +0000872 */
873 struct dimm_size sz = spd_get_dimm_size(device);
874 if ((sz.side1 < 8)) {
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000875 print_err("DIMMs smaller than 8MB per side\n"
876 "are not supported on this NB.\n");
877 die("HALT\n");
Keith Hui59356ca2010-03-06 18:16:25 +0000878 }
Keith Hui59356ca2010-03-06 18:16:25 +0000879
880 /* Divide size by 8 to set up the DRB registers. */
881 drb += (sz.side1 / 8);
882
883 /*
884 * Build the DRB for the next row in MSB so it gets
885 * placed in DRB[n+1] where it belongs when written
886 * as a 16-bit word.
887 */
888 drb &= 0xff;
889 drb |= (drb + (sz.side2 / 8)) << 8;
890 } else {
891#if 0
892 PRINT_DEBUG("No DIMM found in slot ");
893 PRINT_DEBUG_HEX8(i);
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000894 PRINT_DEBUG("\n");
Keith Hui59356ca2010-03-06 18:16:25 +0000895#endif
896
897 /* If there's no DIMM in the slot, set dra to 0x00. */
898 dra = 0x00;
899 ecc = 0xc0;
900 /* Still have to propagate DRB over. */
901 drb &= 0xff;
902 drb |= (drb << 8);
903 }
904
905 pci_write_config16(NB, DRB + (2 * i), drb);
906#if 0
907 PRINT_DEBUG("DRB has been set to 0x");
908 PRINT_DEBUG_HEX16(drb);
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000909 PRINT_DEBUG("\n");
Keith Hui59356ca2010-03-06 18:16:25 +0000910#endif
911
912 /* Brings the upper DRB back down to be base for
913 * DRB calculations for the next two rows.
914 */
915 drb >>= 8;
916
917 rps |= (dra & 0x0f) << (i * 4);
918 nbxecc = (nbxecc >> 2) | (ecc & 0xc0);
919 }
920
921 /* Set paging policy register. */
922 pci_write_config8(NB, PGPOL + 1, bpr);
923 PRINT_DEBUG("PGPOL[BPR] has been set to 0x");
924 PRINT_DEBUG_HEX8(bpr);
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000925 PRINT_DEBUG("\n");
Keith Hui59356ca2010-03-06 18:16:25 +0000926
927 /* Set DRAM row page size register. */
928 pci_write_config16(NB, RPS, rps);
929 PRINT_DEBUG("RPS has been set to 0x");
930 PRINT_DEBUG_HEX16(rps);
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000931 PRINT_DEBUG("\n");
Keith Hui59356ca2010-03-06 18:16:25 +0000932
933 /* ### ECC */
934 pci_write_config8(NB, NBXCFG + 3, nbxecc);
935 PRINT_DEBUG("NBXECC[31:24] has been set to 0x");
936 PRINT_DEBUG_HEX8(nbxecc);
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000937 PRINT_DEBUG("\n");
Keith Hui59356ca2010-03-06 18:16:25 +0000938
939 /* Set DRAMC[4:3] to proper memory type (EDO/SDRAM).
940 * TODO: Registered SDRAM support.
941 */
942 edosd &= 0x07;
943 if (edosd & 0x02) {
944 edosd |= 0x00;
945 } else if (edosd & 0x04) {
946 edosd |= 0x08;
947 }
948 edosd &= 0x18;
949
950 /* edosd is now in the form needed for DRAMC[4:3]. */
951 value = pci_read_config8(NB, DRAMC) & 0xe7;
952 value |= edosd;
953 pci_write_config8(NB, DRAMC, value);
954 PRINT_DEBUG("DRAMC has been set to 0x");
955 PRINT_DEBUG_HEX8(value);
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000956 PRINT_DEBUG("\n");
Keith Hui59356ca2010-03-06 18:16:25 +0000957}
958
Uwe Hermann1683cef2008-11-27 00:47:07 +0000959static void sdram_set_spd_registers(void)
Richard Smithcb8eab42006-07-24 04:25:47 +0000960{
Keith Hui59356ca2010-03-06 18:16:25 +0000961 /* Setup DRAM row boundary registers and other attributes. */
962 set_dram_row_attributes();
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000963
Keith Huidf35cdc2010-09-20 23:41:37 +0000964 /* Setup DRAM buffer strength. */
Keith Hui59356ca2010-03-06 18:16:25 +0000965 set_dram_buffer_strength();
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000966
967 /* TODO: Set PMCR? */
Uwe Hermann1683cef2008-11-27 00:47:07 +0000968 // pci_write_config8(NB, PMCR, 0x14);
969 pci_write_config8(NB, PMCR, 0x10);
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000970
Keith Huidf35cdc2010-09-20 23:41:37 +0000971 /* TODO: This is for EDO memory only. */
Uwe Hermann1683cef2008-11-27 00:47:07 +0000972 pci_write_config8(NB, DRAMT, 0x03);
Richard Smithcb8eab42006-07-24 04:25:47 +0000973}
974
Uwe Hermann1683cef2008-11-27 00:47:07 +0000975static void sdram_enable(void)
Richard Smithcb8eab42006-07-24 04:25:47 +0000976{
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000977 int i;
Richard Smithcb8eab42006-07-24 04:25:47 +0000978
Uwe Hermann861f9642007-05-28 14:37:06 +0000979 /* 0. Wait until power/voltages and clocks are stable (200us). */
980 udelay(200);
Richard Smithcb8eab42006-07-24 04:25:47 +0000981
Uwe Hermann861f9642007-05-28 14:37:06 +0000982 /* 1. Apply NOP. Wait 200 clock cycles (200us should do). */
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000983 PRINT_DEBUG("RAM Enable 1: Apply NOP\n");
Uwe Hermann8b643cea2008-12-09 16:36:12 +0000984 do_ram_command(RAM_COMMAND_NOP);
Uwe Hermann861f9642007-05-28 14:37:06 +0000985 udelay(200);
Richard Smithcb8eab42006-07-24 04:25:47 +0000986
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000987 /* 2. Precharge all. Wait tRP. */
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000988 PRINT_DEBUG("RAM Enable 2: Precharge all\n");
Uwe Hermann8b643cea2008-12-09 16:36:12 +0000989 do_ram_command(RAM_COMMAND_PRECHARGE);
Uwe Hermann861f9642007-05-28 14:37:06 +0000990 udelay(1);
Richard Smithcb8eab42006-07-24 04:25:47 +0000991
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000992 /* 3. Perform 8 refresh cycles. Wait tRC each time. */
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000993 PRINT_DEBUG("RAM Enable 3: CBR\n");
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000994 for (i = 0; i < 8; i++) {
Uwe Hermann8b643cea2008-12-09 16:36:12 +0000995 do_ram_command(RAM_COMMAND_CBR);
Uwe Hermann861f9642007-05-28 14:37:06 +0000996 udelay(1);
Richard Smithcb8eab42006-07-24 04:25:47 +0000997 }
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000998
999 /* 4. Mode register set. Wait two memory cycles. */
Stefan Reinauer64ed2b72010-03-31 14:47:43 +00001000 PRINT_DEBUG("RAM Enable 4: Mode register set\n");
Uwe Hermann8b643cea2008-12-09 16:36:12 +00001001 do_ram_command(RAM_COMMAND_MRS);
Uwe Hermann861f9642007-05-28 14:37:06 +00001002 udelay(2);
Uwe Hermann1a9c8922007-04-01 17:24:03 +00001003
1004 /* 5. Normal operation. */
Stefan Reinauer64ed2b72010-03-31 14:47:43 +00001005 PRINT_DEBUG("RAM Enable 5: Normal operation\n");
Uwe Hermann8b643cea2008-12-09 16:36:12 +00001006 do_ram_command(RAM_COMMAND_NORMAL);
Uwe Hermann861f9642007-05-28 14:37:06 +00001007 udelay(1);
Uwe Hermann1a9c8922007-04-01 17:24:03 +00001008
1009 /* 6. Finally enable refresh. */
Stefan Reinauer64ed2b72010-03-31 14:47:43 +00001010 PRINT_DEBUG("RAM Enable 6: Enable refresh\n");
Uwe Hermann1683cef2008-11-27 00:47:07 +00001011 // pci_write_config8(NB, PMCR, 0x10);
1012 spd_enable_refresh();
Uwe Hermann861f9642007-05-28 14:37:06 +00001013 udelay(1);
Uwe Hermann1a9c8922007-04-01 17:24:03 +00001014
Stefan Reinauer64ed2b72010-03-31 14:47:43 +00001015 PRINT_DEBUG("Northbridge following SDRAM init:\n");
Uwe Hermann1a9c8922007-04-01 17:24:03 +00001016 DUMPNORTH();
Richard Smithcb8eab42006-07-24 04:25:47 +00001017}