blob: 205d40f4d104da156b609233e17a830ac3e14ab2 [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>
Uwe Hermann115c5b92010-10-09 17:00:18 +000024#include <stdint.h>
Carl-Daniel Hailfinger2ee67792008-10-01 12:52:52 +000025#include <stdlib.h>
Uwe Hermann115c5b92010-10-09 17:00:18 +000026#include <arch/io.h>
27#include <arch/romcc_io.h>
28#include <device/pci_def.h>
29#include <console/console.h>
Uwe Hermann1a9c8922007-04-01 17:24:03 +000030#include "i440bx.h"
Keith Hui59356ca2010-03-06 18:16:25 +000031#include "raminit.h"
Richard Smithcb8eab42006-07-24 04:25:47 +000032
Uwe Hermann1a9c8922007-04-01 17:24:03 +000033/*-----------------------------------------------------------------------------
34Macros and definitions.
35-----------------------------------------------------------------------------*/
Richard Smithcb8eab42006-07-24 04:25:47 +000036
Keith Huidf35cdc2010-09-20 23:41:37 +000037#define NB PCI_DEV(0, 0, 0)
38
Uwe Hermann1a9c8922007-04-01 17:24:03 +000039/* Debugging macros. */
Uwe Hermann01ce6012010-03-05 10:03:50 +000040#if CONFIG_DEBUG_RAM_SETUP
Uwe Hermann1a9c8922007-04-01 17:24:03 +000041#define PRINT_DEBUG(x) print_debug(x)
42#define PRINT_DEBUG_HEX8(x) print_debug_hex8(x)
43#define PRINT_DEBUG_HEX16(x) print_debug_hex16(x)
44#define PRINT_DEBUG_HEX32(x) print_debug_hex32(x)
Keith Huidf35cdc2010-09-20 23:41:37 +000045#define DUMPNORTH() dump_pci_device(NB)
Richard Smithcb8eab42006-07-24 04:25:47 +000046#else
Uwe Hermann941a6f02007-04-30 23:27:27 +000047#define PRINT_DEBUG(x)
Uwe Hermann1a9c8922007-04-01 17:24:03 +000048#define PRINT_DEBUG_HEX8(x)
49#define PRINT_DEBUG_HEX16(x)
50#define PRINT_DEBUG_HEX32(x)
51#define DUMPNORTH()
Richard Smithcb8eab42006-07-24 04:25:47 +000052#endif
53
Uwe Hermann1a9c8922007-04-01 17:24:03 +000054/* SDRAMC[7:5] - SDRAM Mode Select (SMS). */
55#define RAM_COMMAND_NORMAL 0x0
56#define RAM_COMMAND_NOP 0x1
57#define RAM_COMMAND_PRECHARGE 0x2
58#define RAM_COMMAND_MRS 0x3
59#define RAM_COMMAND_CBR 0x4
Richard Smithcb8eab42006-07-24 04:25:47 +000060
Uwe Hermann1a9c8922007-04-01 17:24:03 +000061/* Map the JEDEC SPD refresh rates (array index) to 440BX refresh rates as
62 * defined in DRAMC[2:0].
63 *
64 * [0] == Normal 15.625 us -> 15.6 us
65 * [1] == Reduced(.25X) 3.9 us -> 7.8 ns
66 * [2] == Reduced(.5X) 7.8 us -> 7.8 us
67 * [3] == Extended(2x) 31.3 us -> 31.2 us
68 * [4] == Extended(4x) 62.5 us -> 62.4 us
69 * [5] == Extended(8x) 125 us -> 124.8 us
70 */
71static const uint32_t refresh_rate_map[] = {
72 1, 5, 5, 2, 3, 4
73};
Richard Smithcb8eab42006-07-24 04:25:47 +000074
Uwe Hermann1a9c8922007-04-01 17:24:03 +000075/* Table format: register, bitmask, value. */
Keith Huidf35cdc2010-09-20 23:41:37 +000076static const u8 register_values[] = {
Uwe Hermann1a9c8922007-04-01 17:24:03 +000077 /* NBXCFG - NBX Configuration Register
Uwe Hermannf5a6fd22007-05-27 23:31:31 +000078 * 0x50 - 0x53
Uwe Hermann1a9c8922007-04-01 17:24:03 +000079 *
80 * [31:24] SDRAM Row Without ECC
81 * 0 = ECC components are populated in this row
82 * 1 = ECC components are not populated in this row
83 * [23:19] Reserved
84 * [18:18] Host Bus Fast Data Ready Enable (HBFDRE)
85 * Assertion of DRAM data on host bus occurs...
86 * 0 = ...one clock after sampling snoop results (default)
87 * 1 = ...on the same clock the snoop result is being sampled
88 * (this mode is faster by one clock cycle)
89 * [17:17] ECC - EDO static Drive mode
90 * 0 = Normal mode (default)
91 * 1 = ECC signals are always driven
92 * [16:16] IDSEL_REDIRECT
93 * 0 = IDSEL1 is allocated to this bridge (default)
94 * 1 = IDSEL7 is allocated to this bridge
95 * [15:15] WSC# Handshake Disable
96 * 1 = Uni-processor mode
97 * 0 = Dual-processor mode with external IOAPIC (default)
98 * [14:14] Intel Reserved
99 * [13:12] Host/DRAM Frequency
100 * 00 = 100 MHz
101 * 01 = Reserved
102 * 10 = 66 MHz
103 * 11 = Reserved
104 * [11:11] AGP to PCI Access Enable
105 * 1 = Enable
106 * 0 = Disable
107 * [10:10] PCI Agent to Aperture Access Disable
108 * 1 = Disable
109 * 0 = Enable (default)
110 * [09:09] Aperture Access Global Enable
111 * 1 = Enable
112 * 0 = Disable
113 * [08:07] DRAM Data Integrity Mode (DDIM)
114 * 00 = Non-ECC
115 * 01 = EC-only
116 * 10 = ECC Mode
117 * 11 = ECC Mode with hardware scrubbing enabled
118 * [06:06] ECC Diagnostic Mode Enable (EDME)
119 * 1 = Enable
120 * 0 = Normal operation mode (default)
121 * [05:05] MDA Present (MDAP)
122 * Works in conjunction with the VGA_EN bit.
123 * VGA_EN MDAP
124 * 0 x All VGA cycles are sent to PCI
125 * 1 0 All VGA cycles are sent to AGP
126 * 1 1 All VGA cycles are sent to AGP, except for
127 * cycles in the MDA range.
128 * [04:04] Reserved
129 * [03:03] USWC Write Post During I/O Bridge Access Enable (UWPIO)
130 * 1 = Enable
131 * 0 = Disable
132 * [02:02] In-Order Queue Depth (IOQD)
133 * 1 = In-order queue = maximum
134 * 0 = A7# is sampled asserted (i.e., 0)
135 * [01:00] Reserved
Richard Smithcb8eab42006-07-24 04:25:47 +0000136 */
Uwe Hermannbc3594732007-06-07 22:16:30 +0000137 NBXCFG + 0, 0x00, 0x0c,
Keith Huidf35cdc2010-09-20 23:41:37 +0000138 // TODO: Bit 15 should be 0 for multiprocessor boards
Uwe Hermannbc3594732007-06-07 22:16:30 +0000139 NBXCFG + 1, 0x00, 0x80,
140 NBXCFG + 2, 0x00, 0x00,
141 NBXCFG + 3, 0x00, 0xff,
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000142
143 /* DRAMC - DRAM Control Register
144 * 0x57
145 *
146 * [7:6] Reserved
147 * [5:5] Module Mode Configuration (MMCONFIG)
Keith Huidf35cdc2010-09-20 23:41:37 +0000148 * The combination of SDRAMPWR and this bit (which is set by an
149 * external strapping option) determine how CKE works.
150 * SDRAMPWR MMCONFIG
151 * 0 0 = 3 DIMM, CKE0[5:0] driven
152 * X 1 = 3 DIMM, CKE0 only
153 * 1 0 = 4 DIMM, GCKE only
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000154 * [4:3] DRAM Type (DT)
155 * 00 = EDO
156 * 01 = SDRAM
157 * 10 = Registered SDRAM
158 * 11 = Reserved
159 * Note: EDO, SDRAM and Registered SDRAM cannot be mixed.
160 * [2:0] DRAM Refresh Rate (DRR)
161 * 000 = Refresh disabled
162 * 001 = 15.6 us
163 * 010 = 31.2 us
164 * 011 = 62.4 us
165 * 100 = 124.8 us
166 * 101 = 249.6 us
167 * 110 = Reserved
168 * 111 = Reserved
Richard Smithcb8eab42006-07-24 04:25:47 +0000169 */
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000170 /* Choose SDRAM (not registered), and disable refresh for now. */
Uwe Hermannbc3594732007-06-07 22:16:30 +0000171 DRAMC, 0x00, 0x08,
Richard Smithcb8eab42006-07-24 04:25:47 +0000172
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000173 /*
174 * PAM[6:0] - Programmable Attribute Map Registers
Uwe Hermannf5a6fd22007-05-27 23:31:31 +0000175 * 0x59 - 0x5f
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000176 *
177 * 0x59 [3:0] Reserved
178 * 0x59 [5:4] 0xF0000 - 0xFFFFF BIOS area
179 * 0x5a [1:0] 0xC0000 - 0xC3FFF ISA add-on BIOS
180 * 0x5a [5:4] 0xC4000 - 0xC7FFF ISA add-on BIOS
181 * 0x5b [1:0] 0xC8000 - 0xCBFFF ISA add-on BIOS
182 * 0x5b [5:4] 0xCC000 - 0xCFFFF ISA add-on BIOS
183 * 0x5c [1:0] 0xD0000 - 0xD3FFF ISA add-on BIOS
184 * 0x5c [5:4] 0xD4000 - 0xD7FFF ISA add-on BIOS
185 * 0x5d [1:0] 0xD8000 - 0xDBFFF ISA add-on BIOS
186 * 0x5d [5:4] 0xDC000 - 0xDFFFF ISA add-on BIOS
187 * 0x5e [1:0] 0xE0000 - 0xE3FFF BIOS entension
188 * 0x5e [5:4] 0xE4000 - 0xE7FFF BIOS entension
189 * 0x5f [1:0] 0xE8000 - 0xEBFFF BIOS entension
190 * 0x5f [5:4] 0xEC000 - 0xEFFFF BIOS entension
191 *
192 * Bit assignment:
193 * 00 = DRAM Disabled (all access goes to memory mapped I/O space)
194 * 01 = Read Only (Reads to DRAM, writes to memory mapped I/O space)
195 * 10 = Write Only (Writes to DRAM, reads to memory mapped I/O space)
196 * 11 = Read/Write (all access goes to DRAM)
197 */
Keith Hui59356ca2010-03-06 18:16:25 +0000198
199 /*
200 * Map all legacy regions to RAM (read/write). This is required if
201 * you want to use the RAM area from 768 KB - 1 MB. If the PAM
202 * registers are not set here appropriately, the RAM in that region
203 * will not be accessible, thus a RAM check of it will also fail.
204 *
205 * TODO: This was set in sdram_set_spd_registers().
206 * Test if it still works when set here.
207 */
208 PAM0, 0x00, 0x30,
209 PAM1, 0x00, 0x33,
210 PAM2, 0x00, 0x33,
211 PAM3, 0x00, 0x33,
212 PAM4, 0x00, 0x33,
213 PAM5, 0x00, 0x33,
214 PAM6, 0x00, 0x33,
Richard Smithcb8eab42006-07-24 04:25:47 +0000215
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000216 /* DRB[0:7] - DRAM Row Boundary Registers
217 * 0x60 - 0x67
218 *
219 * An array of 8 byte registers, which hold the ending memory address
Anders Jenbo0e1e8062010-04-27 06:35:31 +0000220 * assigned to each pair of DIMMs, in 8MB granularity.
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000221 *
222 * 0x60 DRB0 = Total memory in row0 (in 8 MB)
223 * 0x61 DRB1 = Total memory in row0+1 (in 8 MB)
224 * 0x62 DRB2 = Total memory in row0+1+2 (in 8 MB)
225 * 0x63 DRB3 = Total memory in row0+1+2+3 (in 8 MB)
226 * 0x64 DRB4 = Total memory in row0+1+2+3+4 (in 8 MB)
227 * 0x65 DRB5 = Total memory in row0+1+2+3+4+5 (in 8 MB)
228 * 0x66 DRB6 = Total memory in row0+1+2+3+4+5+6 (in 8 MB)
229 * 0x67 DRB7 = Total memory in row0+1+2+3+4+5+6+7 (in 8 MB)
230 */
Uwe Hermannf5a6fd22007-05-27 23:31:31 +0000231 /* Set the DRBs to zero for now, this will be fixed later. */
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000232 DRB0, 0x00, 0x00,
233 DRB1, 0x00, 0x00,
234 DRB2, 0x00, 0x00,
235 DRB3, 0x00, 0x00,
236 DRB4, 0x00, 0x00,
237 DRB5, 0x00, 0x00,
238 DRB6, 0x00, 0x00,
239 DRB7, 0x00, 0x00,
240
241 /* FDHC - Fixed DRAM Hole Control Register
242 * 0x68
243 *
244 * Controls two fixed DRAM holes: 512 KB - 640 KB and 15 MB - 16 MB.
245 *
246 * [7:6] Hole Enable (HEN)
247 * 00 = None
248 * 01 = 512 KB - 640 KB (128 KB)
249 * 10 = 15 MB - 16 MB (1 MB)
250 * 11 = Reserved
251 * [5:0] Reserved
252 */
253 /* No memory holes. */
254 FDHC, 0x00, 0x00,
255
256 /* RPS - SDRAM Row Page Size Register
257 * 0x74 - 0x75
258 *
259 * Sets the row page size for SDRAM. For EDO memory, the page
260 * size is fixed at 2 KB.
261 *
Keith Huidf35cdc2010-09-20 23:41:37 +0000262 * Bits[1:0] Page Size
263 * 00 2 KB
264 * 01 4 KB
265 * 10 8 KB
266 * 11 Reserved
267 *
268 * RPS bits Corresponding DRB register
269 * [01:00] DRB[0], row 0
270 * [03:02] DRB[1], row 1
271 * [05:04] DRB[2], row 2
272 * [07:06] DRB[3], row 3
273 * [09:08] DRB[4], row 4
274 * [11:10] DRB[5], row 5
275 * [13:12] DRB[6], row 6
276 * [15:14] DRB[7], row 7
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000277 */
Keith Huidf35cdc2010-09-20 23:41:37 +0000278 /* Power on defaults to 2KB. Will be set later. */
279 // RPS + 0, 0x00, 0x00,
280 // RPS + 1, 0x00, 0x00,
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000281
282 /* SDRAMC - SDRAM Control Register
Uwe Hermann7ea18cf2007-05-04 00:51:17 +0000283 * 0x76 - 0x77
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000284 *
285 * [15:10] Reserved
286 * [09:08] Idle/Pipeline DRAM Leadoff Timing (IPDLT)
287 * 00 = Illegal
288 * 01 = Add a clock delay to the lead-off clock count
Keith Huidf35cdc2010-09-20 23:41:37 +0000289 * 1x = Illegal
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000290 * [07:05] SDRAM Mode Select (SMS)
291 * 000 = Normal SDRAM Operation (default)
292 * 001 = NOP Command Enable
293 * 010 = All Banks Precharge Enable
294 * 011 = Mode Register Set Enable
295 * 100 = CBR Enable
296 * 101 = Reserved
297 * 110 = Reserved
298 * 111 = Reserved
299 * [04:04] SDRAMPWR
300 * 0 = 3 DIMM configuration
301 * 1 = 4 DIMM configuration
302 * [03:03] Leadoff Command Timing (LCT)
303 * 0 = 4 CS# Clock
304 * 1 = 3 CS# Clock
305 * [02:02] CAS# Latency (CL)
306 * 0 = 3 DCLK CAS# latency
307 * 1 = 2 DCLK CAS# latency
308 * [01:01] SDRAM RAS# to CAS# Delay (SRCD)
309 * 0 = 3 clocks between a row activate and a read or write cmd.
310 * 1 = 2 clocks between a row activate and a read or write cmd.
311 * [00:00] SDRAM RAS# Precharge (SRP)
312 * 0 = 3 clocks of RAS# precharge
313 * 1 = 2 clocks of RAS# precharge
314 */
Keith Hui9c1e1f02010-03-13 20:16:48 +0000315#if CONFIG_SDRAMPWR_4DIMM
316 SDRAMC + 0, 0x00, 0x10, /* The board has 4 DIMM slots. */
317#else
Keith Huidf35cdc2010-09-20 23:41:37 +0000318 SDRAMC + 0, 0x00, 0x00, /* The board has 3 DIMM slots. */
Keith Hui9c1e1f02010-03-13 20:16:48 +0000319#endif
Mats Erik Andersson45db3662008-09-30 04:52:29 +0000320 SDRAMC + 1, 0x00, 0x00,
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000321
322 /* PGPOL - Paging Policy Register
323 * 0x78 - 0x79
324 *
325 * [15:08] Banks per Row (BPR)
Keith Huidf35cdc2010-09-20 23:41:37 +0000326 * Each bit in this field corresponds to one row of the memory
327 * array. Bit 15 corresponds to row 7 while bit 8 corresponds
328 * to row 0. Bits for empty rows are "don't care".
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000329 * 0 = 2 banks
330 * 1 = 4 banks
331 * [07:05] Reserved
332 * [04:04] Intel Reserved
333 * [03:00] DRAM Idle Timer (DIT)
334 * 0000 = 0 clocks
335 * 0001 = 2 clocks
336 * 0010 = 4 clocks
337 * 0011 = 8 clocks
338 * 0100 = 10 clocks
339 * 0101 = 12 clocks
340 * 0110 = 16 clocks
341 * 0111 = 32 clocks
342 * 1xxx = Infinite (pages are not closed for idle condition)
343 */
Uwe Hermannbc3594732007-06-07 22:16:30 +0000344 PGPOL + 0, 0x00, 0x00,
345 PGPOL + 1, 0x00, 0xff,
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000346
347 /* PMCR - Power Management Control Register
348 * 0x7a
349 *
350 * [07:07] Power Down SDRAM Enable (PDSE)
351 * 1 = Enable
352 * 0 = Disable
353 * [06:06] ACPI Control Register Enable (SCRE)
354 * 1 = Enable
355 * 0 = Disable (default)
356 * [05:05] Suspend Refresh Type (SRT)
357 * 1 = Self refresh mode
358 * 0 = CBR fresh mode
359 * [04:04] Normal Refresh Enable (NREF_EN)
360 * 1 = Enable
361 * 0 = Disable
362 * [03:03] Quick Start Mode (QSTART)
363 * 1 = Quick start mode for the processor is enabled
364 * [02:02] Gated Clock Enable (GCLKEN)
365 * 1 = Enable
366 * 0 = Disable
367 * [01:01] AGP Disable (AGP_DIS)
368 * 1 = Disable
369 * 0 = Enable
370 * [00:00] CPU reset without PCIRST enable (CRst_En)
371 * 1 = Enable
372 * 0 = Disable
373 */
374 /* Enable normal refresh and the gated clock. */
375 // TODO: Only do this later?
376 // PMCR, 0x00, 0x14,
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000377 PMCR, 0x00, 0x00,
Keith Hui59356ca2010-03-06 18:16:25 +0000378
379 /* Enable SCRR.SRRAEN and let BX choose the SRR. */
380 SCRR + 1, 0x00, 0x10,
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000381};
382
383/*-----------------------------------------------------------------------------
384SDRAM configuration functions.
385-----------------------------------------------------------------------------*/
386
387/**
388 * Send the specified RAM command to all DIMMs.
389 *
Uwe Hermann8b643cea2008-12-09 16:36:12 +0000390 * @param command The RAM command to send to the DIMM(s).
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000391 */
Uwe Hermann8b643cea2008-12-09 16:36:12 +0000392static void do_ram_command(u32 command)
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000393{
Uwe Hermann8b643cea2008-12-09 16:36:12 +0000394 int i, caslatency;
395 u8 dimm_start, dimm_end;
396 u16 reg16;
397 u32 addr, addr_offset;
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000398
399 /* Configure the RAM command. */
Uwe Hermann8b643cea2008-12-09 16:36:12 +0000400 reg16 = pci_read_config16(NB, SDRAMC);
401 reg16 &= 0xff1f; /* Clear bits 7-5. */
402 reg16 |= (u16) (command << 5); /* Write command into bits 7-5. */
403 pci_write_config16(NB, SDRAMC, reg16);
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000404
Uwe Hermann8b643cea2008-12-09 16:36:12 +0000405 /*
406 * RAM_COMMAND_NORMAL affects only the memory controller and
407 * doesn't need to be "sent" to the DIMMs.
408 */
409 if (command == RAM_COMMAND_NORMAL)
410 return;
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000411
Uwe Hermann8b643cea2008-12-09 16:36:12 +0000412 /* Send the RAM command to each row of memory. */
413 dimm_start = 0;
414 for (i = 0; i < (DIMM_SOCKETS * 2); i++) {
Keith Hui59356ca2010-03-06 18:16:25 +0000415 addr_offset = 0;
416 caslatency = 3; /* TODO: Dynamically get CAS latency later. */
Uwe Hermann8b643cea2008-12-09 16:36:12 +0000417 if (command == RAM_COMMAND_MRS) {
418 /*
419 * MAA[12:11,9:0] must be inverted when sent to DIMM
420 * 2 or 3 (no inversion if sent to DIMM 0 or 1).
421 */
422 if ((i >= 0 && i <= 3) && caslatency == 3)
423 addr_offset = 0x1d0;
424 if ((i >= 4 && i <= 7) && caslatency == 3)
425 addr_offset = 0x1e28;
426 if ((i >= 0 && i <= 3) && caslatency == 2)
427 addr_offset = 0x150;
428 if ((i >= 4 && i <= 7) && caslatency == 2)
429 addr_offset = 0x1ea8;
430 }
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000431
Uwe Hermann8b643cea2008-12-09 16:36:12 +0000432 dimm_end = pci_read_config8(NB, DRB + i);
433
434 addr = (dimm_start * 8 * 1024 * 1024) + addr_offset;
435 if (dimm_end > dimm_start) {
436#if 0
437 PRINT_DEBUG(" Sending RAM command 0x");
438 PRINT_DEBUG_HEX16(reg16);
439 PRINT_DEBUG(" to 0x");
440 PRINT_DEBUG_HEX32(addr);
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000441 PRINT_DEBUG("\n");
Uwe Hermann8b643cea2008-12-09 16:36:12 +0000442#endif
443
444 read32(addr);
445 }
446
447 /* Set the start of the next DIMM. */
448 dimm_start = dimm_end;
449 }
Richard Smithcb8eab42006-07-24 04:25:47 +0000450}
451
Keith Hui59356ca2010-03-06 18:16:25 +0000452static void set_dram_buffer_strength(void)
453{
Keith Huib48ba662010-03-17 02:15:07 +0000454 /* To give some breathing room for romcc,
Anders Jenbo0e1e8062010-04-27 06:35:31 +0000455 * mbsc0 doubles as drb
Keith Huib48ba662010-03-17 02:15:07 +0000456 * mbsc1 doubles as drb1
457 * mbfs0 doubles as i and reg
Keith Hui59356ca2010-03-06 18:16:25 +0000458 */
Keith Huib48ba662010-03-17 02:15:07 +0000459 uint8_t mbsc0,mbsc1,mbsc3,mbsc4,mbfs0,mbfs2,fsb;
Keith Hui59356ca2010-03-06 18:16:25 +0000460
Anders Jenbo0e1e8062010-04-27 06:35:31 +0000461 /* Tally how many rows between rows 0-3 and rows 4-7 are populated.
Keith Huib48ba662010-03-17 02:15:07 +0000462 * This determines how to program MBFS and MBSC.
463 */
464 uint8_t dimm03 = 0;
465 uint8_t dimm47 = 0;
466
467 mbsc0 = 0;
468 for (mbfs0 = DRB0; mbfs0 <= DRB7; mbfs0++) {
469 mbsc1 = pci_read_config8(NB, mbfs0);
470 if (mbsc0 != mbsc1) {
471 if (mbfs0 <= DRB3) {
472 dimm03++;
473 } else {
474 dimm47++;
475 }
476 mbsc0 = mbsc1;
477 }
478 }
479
Keith Huidf35cdc2010-09-20 23:41:37 +0000480 /* Algorithm bitmap for programming MBSC[39:0] and MBFS[23:0].
Keith Huib48ba662010-03-17 02:15:07 +0000481 *
Keith Huidf35cdc2010-09-20 23:41:37 +0000482 * The 440BX datasheet says buffer frequency is independent from bus
483 * frequency and mismatch both ways are possible. This is how it is
484 * programmed in the ASUS P2B-LS mainboard.
Keith Huib48ba662010-03-17 02:15:07 +0000485 *
486 * There are four main conditions to check when programming DRAM buffer
487 * frequency and strength:
488 *
489 * a: >2 rows populated across DIMM0,1
490 * b: >2 rows populated across DIMM2,3
491 * c: >4 rows populated across all DIMM slots
492 * and either one of:
493 * 1: NBXCFG[13] strapped as 100MHz, or
494 * 6: NBXCFG[13] strapped as 66MHz
495 *
496 * CKE0/FENA ----------------------------------------------------------+
497 * CKE1/GCKE -------------------[ MBFS ]------------------------+|
498 * DQMA/CASA[764320]# ----------[ 0 = 66MHz ]-----------------------+||
499 * DQMB1/CASB1# ----------------[ 1 = 100MHz ]----------------------+|||
500 * DQMB5/CASB5# ---------------------------------------------------+||||
501 * DQMA1/CASA1# --------------------------------------------------+|||||
502 * DQMA5/CASA5# -------------------------------------------------+||||||
503 * CSA0-5#,CSB0-5# ----------------------------------------++++++|||||||
504 * CSA6#/CKE2# -------------------------------------------+|||||||||||||
505 * CSB6#/CKE4# ------------------------------------------+||||||||||||||
506 * CSA7#/CKE3# -----------------------------------------+|||||||||||||||
507 * CSB7#/CKE5# ----------------------------------------+||||||||||||||||
508 * MECC[7:0] #2/#1 (100MHz) -------------------------++|||||||||||||||||
509 * MD[63:0] #2/#1 (100MHz) ------------------------++|||||||||||||||||||
510 * MAB[12:11,9:0]#,MAB[13,10],WEB#,SRASB#,SCASB# -+|||||||||||||||||||||
511 * MAA[13:0],WEA#,SRASA#,SCASA# -----------------+||||||||||||||||||||||
512 * Reserved ------------------------------------+|||||||||||||||||||||||
513 * ||||||||||||||||||||||||
514 * 3 32 21 10 0 * 2 21 10 0
515 * 9876543210987654321098765432109876543210 * 321098765432109876543210
516 * a 10------------------------1010---------- * -1---------------11----- a
517 *!a 11------------------------1111---------- * -0---------------00----- !a
518 * b --10--------------------------1010------ * --1----------------11--- b
519 *!b --11--------------------------1111------ * --0----------------00--- !b
520 * c ----------------------------------1100-- * ----------------------1- c
521 *!c ----------------------------------1011-- * ----------------------0- !c
522 * 1 ----1010101000000000000000------------00 * ---11111111111111----1-0 1
523 * 6 ----000000000000000000000010101010----00 * ---1111111111111100000-0 6
524 * | | | | | | | | | | ||||||| | | | | | |
525 * | | | | | | | | | | ||||||| | | | | | +- CKE0/FENA
526 * | | | | | | | | | | ||||||| | | | | +--- CKE1/GCKE
527 * | | | | | | | | | | ||||||| | | | +----- DQMA/CASA[764320]#
528 * | | | | | | | | | | ||||||| | | +------- DQMB1/CASB1#
529 * | | | | | | | | | | ||||||| | +--------- DQMB5/CASB5#
530 * | | | | | | | | | | ||||||| +----------- DQMA1/CASA1#
531 * | | | | | | | | | | ||||||+------------- DQMA5/CASA5#
532 * | | | | | | | | | | ++++++-------------- CSA0-5#,CSB0-5# [ 0=1x;1=2x ]
533 * | | | | | | | | | +--------------------- CSA6#/CKE2#
534 * | | | | | | | | +---[ MBSC ]------ CSB6#/CKE4#
535 * | | | | | | | +-----[ 00 = 1x ]------ CSA7#/CKE3#
536 * | | | | | | +-------[ 01 invalid ]------ CSB7#/CKE5#
537 * | | | | | +---------[ 10 = 2x ]------ MECC[7:0] #1 (2x)
538 * | | | | +-----------[ 11 = 3x ]------ MECC[7:0] #2 (2x)
539 * | | | +--------------------------------- MD[63:0] #1 (2x)
540 * | | +----------------------------------- MD[63:0] #2 (2x)
541 * | +------------------------------------- MAB[12:11,9:0]#,MAB[13,10],WEB#,SRASB#,SCASB#
542 * +--------------------------------------- MAA[13:0],WEA#,SRASA#,SCASA#
543 * MBSC[47:40] and MBFS[23] are reserved.
544 *
Keith Huidf35cdc2010-09-20 23:41:37 +0000545 * This algorithm is checked against the ASUS P2B-LS (which has
546 * 4 DIMM slots) factory BIOS.
Keith Huib48ba662010-03-17 02:15:07 +0000547 * Therefore it assumes a board with 4 slots, and will need testing
548 * on boards with 3 DIMM slots.
549 */
Anders Jenbo0e1e8062010-04-27 06:35:31 +0000550
Keith Huib48ba662010-03-17 02:15:07 +0000551 mbsc0 = 0x80;
552 mbsc1 = 0x2a;
553 mbfs2 = 0x1f;
554 if (pci_read_config8(NB, NBXCFG + 1) & 0x30) {
555 fsb = 66;
556 mbsc3 = 0x00;
557 mbsc4 = 0x00;
558 mbfs0 = 0x80;
559 } else {
560 fsb = 100;
561 mbsc3 = 0xa0;
562 mbsc4 = 0x0a;
563 mbfs0 = 0x84;
564 }
Anders Jenbo0e1e8062010-04-27 06:35:31 +0000565
566 if (dimm03 > 2) {
567 mbsc4 = mbsc4 | 0x80;
Keith Huib48ba662010-03-17 02:15:07 +0000568 mbsc1 = mbsc1 | 0x28;
569 mbfs2 = mbfs2 | 0x40;
570 mbfs0 = mbfs0 | 0x60;
Anders Jenbo0e1e8062010-04-27 06:35:31 +0000571 } else {
572 mbsc4 = mbsc4 | 0xc0;
Keith Huib48ba662010-03-17 02:15:07 +0000573 if (fsb == 100) {
574 mbsc1 = mbsc1 | 0x3c;
575 }
Anders Jenbo0e1e8062010-04-27 06:35:31 +0000576 }
577 if (dimm47 > 2) {
578 mbsc4 = mbsc4 | 0x20;
579 mbsc1 = mbsc1 | 0x02;
Keith Huib48ba662010-03-17 02:15:07 +0000580 mbsc0 = mbsc0 | 0x80;
581 mbfs2 = mbfs2 | 0x20;
582 mbfs0 = mbfs0 | 0x18;
Anders Jenbo0e1e8062010-04-27 06:35:31 +0000583 } else {
Keith Huib48ba662010-03-17 02:15:07 +0000584 mbsc4 = mbsc4 | 0x30;
585 if (fsb == 100) {
Anders Jenbo0e1e8062010-04-27 06:35:31 +0000586 mbsc1 = mbsc1 | 0x03;
Keith Huib48ba662010-03-17 02:15:07 +0000587 mbsc0 = mbsc0 | 0xc0;
588 }
589 }
Anders Jenbo0e1e8062010-04-27 06:35:31 +0000590 if ((dimm03 + dimm47) > 4) {
Keith Huib48ba662010-03-17 02:15:07 +0000591 mbsc0 = mbsc0 | 0x30;
592 mbfs0 = mbfs0 | 0x02;
Anders Jenbo0e1e8062010-04-27 06:35:31 +0000593 } else {
594 mbsc0 = mbsc0 | 0x2c;
Keith Huib48ba662010-03-17 02:15:07 +0000595 }
596
597 pci_write_config8(NB, MBSC + 0, mbsc0);
598 pci_write_config8(NB, MBSC + 1, mbsc1);
599 pci_write_config8(NB, MBSC + 2, 0x00);
600 pci_write_config8(NB, MBSC + 3, mbsc3);
601 pci_write_config8(NB, MBSC + 4, mbsc4);
602 pci_write_config8(NB, MBFS + 0, mbfs0);
603 pci_write_config8(NB, MBFS + 1, 0xff);
604 pci_write_config8(NB, MBFS + 2, mbfs2);
Keith Hui59356ca2010-03-06 18:16:25 +0000605}
606
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000607/*-----------------------------------------------------------------------------
608DIMM-independant configuration functions.
609-----------------------------------------------------------------------------*/
Richard Smithcb8eab42006-07-24 04:25:47 +0000610
Uwe Hermann1683cef2008-11-27 00:47:07 +0000611static void spd_enable_refresh(void)
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000612{
613 int i, value;
614 uint8_t reg;
615
Uwe Hermann1683cef2008-11-27 00:47:07 +0000616 reg = pci_read_config8(NB, DRAMC);
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000617
618 for (i = 0; i < DIMM_SOCKETS; i++) {
Uwe Hermannd773fd32010-11-20 20:23:08 +0000619 value = spd_read_byte(DIMM0 + i, SPD_REFRESH);
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000620 if (value < 0)
621 continue;
622 reg = (reg & 0xf8) | refresh_rate_map[(value & 0x7f)];
623
624 PRINT_DEBUG(" Enabling refresh (DRAMC = 0x");
625 PRINT_DEBUG_HEX8(reg);
626 PRINT_DEBUG(") for DIMM ");
627 PRINT_DEBUG_HEX8(i);
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000628 PRINT_DEBUG("\n");
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000629 }
630
Uwe Hermann1683cef2008-11-27 00:47:07 +0000631 pci_write_config8(NB, DRAMC, reg);
Richard Smithcb8eab42006-07-24 04:25:47 +0000632}
633
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000634/*-----------------------------------------------------------------------------
635Public interface.
636-----------------------------------------------------------------------------*/
637
Uwe Hermann115c5b92010-10-09 17:00:18 +0000638void sdram_set_registers(void)
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000639{
640 int i, max;
Uwe Hermannbc3594732007-06-07 22:16:30 +0000641 uint8_t reg;
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000642
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000643 PRINT_DEBUG("Northbridge prior to SDRAM init:\n");
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000644 DUMPNORTH();
645
Carl-Daniel Hailfinger2ee67792008-10-01 12:52:52 +0000646 max = ARRAY_SIZE(register_values);
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000647
Uwe Hermannf5a6fd22007-05-27 23:31:31 +0000648 /* Set registers as specified in the register_values[] array. */
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000649 for (i = 0; i < max; i += 3) {
Uwe Hermann1683cef2008-11-27 00:47:07 +0000650 reg = pci_read_config8(NB, register_values[i]);
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000651 reg &= register_values[i + 1];
652 reg |= register_values[i + 2] & ~(register_values[i + 1]);
Uwe Hermann1683cef2008-11-27 00:47:07 +0000653 pci_write_config8(NB, register_values[i], reg);
Keith Hui59356ca2010-03-06 18:16:25 +0000654#if 0
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000655 PRINT_DEBUG(" Set register 0x");
Uwe Hermannbc3594732007-06-07 22:16:30 +0000656 PRINT_DEBUG_HEX8(register_values[i]);
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000657 PRINT_DEBUG(" to 0x");
Uwe Hermannbc3594732007-06-07 22:16:30 +0000658 PRINT_DEBUG_HEX8(reg);
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000659 PRINT_DEBUG("\n");
Keith Hui59356ca2010-03-06 18:16:25 +0000660#endif
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000661 }
662}
663
Keith Hui59356ca2010-03-06 18:16:25 +0000664struct dimm_size {
665 unsigned long side1;
666 unsigned long side2;
667};
668
669static struct dimm_size spd_get_dimm_size(unsigned int device)
670{
671 struct dimm_size sz;
672 int i, module_density, dimm_banks;
673 sz.side1 = 0;
674 module_density = spd_read_byte(device, SPD_DENSITY_OF_EACH_ROW_ON_MODULE);
675 dimm_banks = spd_read_byte(device, SPD_NUM_DIMM_BANKS);
676
677 /* Find the size of side1. */
678 /* Find the larger value. The larger value is always side1. */
679 for (i = 512; i >= 0; i >>= 1) {
680 if ((module_density & i) == i) {
681 sz.side1 = i;
682 break;
683 }
684 }
685
686 /* Set to 0 in case it's single sided. */
687 sz.side2 = 0;
688
689 /* Test if it's a dual-sided DIMM. */
690 if (dimm_banks > 1) {
691 /* Test if there's a second value. If so it's asymmetrical. */
692 if (module_density != i) {
693 /*
694 * Find second value, picking up where we left off.
695 * i >>= 1 done initially to make sure we don't get
696 * the same value again.
697 */
698 for (i >>= 1; i >= 0; i >>= 1) {
699 if (module_density == (sz.side1 | i)) {
700 sz.side2 = i;
701 break;
702 }
703 }
704 /* If not, it's symmetrical. */
705 } else {
706 sz.side2 = sz.side1;
707 }
708 }
709
710 /*
711 * SPD byte 31 is the memory size divided by 4 so we
712 * need to muliply by 4 to get the total size.
713 */
714 sz.side1 *= 4;
715 sz.side2 *= 4;
716
Anders Jenbo771b0e42010-04-27 08:45:30 +0000717 /* It is possible to partially use larger then supported
718 * modules by setting them to a supported size.
719 */
720 if(sz.side1 > 128) {
721 PRINT_DEBUG("Side1 was 0x");
722 PRINT_DEBUG_HEX16(sz.side1);
723 PRINT_DEBUG(" but only 128MB will be used.\n");
724 sz.side1 = 128;
725
726 if(sz.side2 > 128) {
727 PRINT_DEBUG("Side2 was 0x");
728 PRINT_DEBUG_HEX16(sz.side2);
729 PRINT_DEBUG(" but only 128MB will be used.\n");
730 sz.side2 = 128;
731 }
732 }
733
Keith Hui59356ca2010-03-06 18:16:25 +0000734 return sz;
735}
736/*
737 * Sets DRAM attributes one DIMM at a time, based on SPD data.
738 * Northbridge settings that are set: NBXCFG[31:24], DRB0-DRB7, RPS, DRAMC.
739 */
740static void set_dram_row_attributes(void)
741{
742 int i, dra, drb, col, width, value, rps, edosd, ecc, nbxecc;
743 u8 bpr; /* Top 8 bits of PGPOL */
744
745 edosd = 0;
746 rps = 0;
747 drb = 0;
748 bpr = 0;
749 nbxecc = 0xff;
750
751 for (i = 0; i < DIMM_SOCKETS; i++) {
752 unsigned int device;
Uwe Hermannd773fd32010-11-20 20:23:08 +0000753 device = DIMM0 + i;
Keith Hui59356ca2010-03-06 18:16:25 +0000754 bpr >>= 2;
755
756 /* First check if a DIMM is actually present. */
757 value = spd_read_byte(device, SPD_MEMORY_TYPE);
758 /* This is 440BX! We do EDO too! */
759 if (value == SPD_MEMORY_TYPE_EDO
760 || value == SPD_MEMORY_TYPE_SDRAM) {
761
762 PRINT_DEBUG("Found ");
763 if (value == SPD_MEMORY_TYPE_EDO) {
Anders Jenbo0e1e8062010-04-27 06:35:31 +0000764 edosd |= 0x02;
765 } else if (value == SPD_MEMORY_TYPE_SDRAM) {
766 edosd |= 0x04;
Keith Hui59356ca2010-03-06 18:16:25 +0000767 }
768 PRINT_DEBUG("DIMM in slot ");
769 PRINT_DEBUG_HEX8(i);
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000770 PRINT_DEBUG("\n");
Keith Hui59356ca2010-03-06 18:16:25 +0000771
Anders Jenbo0e1e8062010-04-27 06:35:31 +0000772 if (edosd == 0x06) {
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000773 print_err("Mixing EDO/SDRAM unsupported!\n");
774 die("HALT\n");
Keith Hui59356ca2010-03-06 18:16:25 +0000775 }
776
777 /* "DRA" is our RPS for the two rows on this DIMM. */
778 dra = 0;
779
780 /* Columns */
781 col = spd_read_byte(device, SPD_NUM_COLUMNS);
782
783 /*
784 * Is this an ECC DIMM? Actually will be a 2 if so.
785 * TODO: Other register than NBXCFG also needs this
786 * ECC information.
787 */
788 ecc = spd_read_byte(device, SPD_DIMM_CONFIG_TYPE);
789
790 /* Data width */
791 width = spd_read_byte(device, SPD_MODULE_DATA_WIDTH_LSB);
Anders Jenbo0e1e8062010-04-27 06:35:31 +0000792
Keith Hui59356ca2010-03-06 18:16:25 +0000793 /* Exclude error checking data width from page size calculations */
794 if (ecc) {
795 value = spd_read_byte(device,
796 SPD_ERROR_CHECKING_SDRAM_WIDTH);
797 width -= value;
798 /* ### ECC */
799 /* Clear top 2 bits to help set up NBXCFG. */
800 ecc &= 0x3f;
801 } else {
802 /* Without ECC, top 2 bits should be 11. */
803 ecc |= 0xc0;
804 }
805
806 /* Calculate page size in bits. */
807 value = ((1 << col) * width);
808
809 /* Convert to KB. */
810 dra = (value >> 13);
811
812 /* Number of banks of DIMM (single or double sided). */
813 value = spd_read_byte(device, SPD_NUM_DIMM_BANKS);
814
815 /* Once we have dra, col is done and can be reused.
816 * So it's reused for number of banks.
817 */
818 col = spd_read_byte(device, SPD_NUM_BANKS_PER_SDRAM);
819
820 if (value == 1) {
821 /*
822 * Second bank of 1-bank DIMMs "doesn't have
823 * ECC" - or anything.
824 */
825 ecc |= 0x80;
826 if (dra == 2) {
827 dra = 0x0; /* 2KB */
828 } else if (dra == 4) {
829 dra = 0x1; /* 4KB */
830 } else if (dra == 8) {
831 dra = 0x2; /* 8KB */
Anders Jenbo771b0e42010-04-27 08:45:30 +0000832 } else if (dra >= 16) {
833 /* Page sizes larger than supported are
834 * set to 8KB to use module partially.
835 */
836 PRINT_DEBUG("Page size forced to 8KB.\n");
837 dra = 0x2; /* 8KB */
Keith Hui59356ca2010-03-06 18:16:25 +0000838 } else {
839 dra = -1;
840 }
841 /*
842 * Sets a flag in PGPOL[BPR] if this DIMM has
843 * 4 banks per row.
844 */
845 if (col == 4)
846 bpr |= 0x40;
847 } else if (value == 2) {
848 if (dra == 2) {
849 dra = 0x0; /* 2KB */
850 } else if (dra == 4) {
851 dra = 0x05; /* 4KB */
852 } else if (dra == 8) {
853 dra = 0x0a; /* 8KB */
Anders Jenbo771b0e42010-04-27 08:45:30 +0000854 } else if (dra >= 16) {
855 /* Ditto */
856 PRINT_DEBUG("Page size forced to 8KB.\n");
857 dra = 0x0a; /* 8KB */
Keith Hui59356ca2010-03-06 18:16:25 +0000858 } else {
859 dra = -1;
860 }
861 /* Ditto */
862 if (col == 4)
863 bpr |= 0xc0;
864 } else {
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000865 print_err("# of banks of DIMM unsupported!\n");
866 die("HALT\n");
Keith Hui59356ca2010-03-06 18:16:25 +0000867 }
868 if (dra == -1) {
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000869 print_err("Page size not supported\n");
870 die("HALT\n");
Keith Hui59356ca2010-03-06 18:16:25 +0000871 }
872
873 /*
874 * 440BX supports asymmetrical dual-sided DIMMs,
875 * but can't handle DIMMs smaller than 8MB per
Anders Jenbo771b0e42010-04-27 08:45:30 +0000876 * side.
Keith Hui59356ca2010-03-06 18:16:25 +0000877 */
878 struct dimm_size sz = spd_get_dimm_size(device);
879 if ((sz.side1 < 8)) {
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000880 print_err("DIMMs smaller than 8MB per side\n"
881 "are not supported on this NB.\n");
882 die("HALT\n");
Keith Hui59356ca2010-03-06 18:16:25 +0000883 }
Keith Hui59356ca2010-03-06 18:16:25 +0000884
885 /* Divide size by 8 to set up the DRB registers. */
886 drb += (sz.side1 / 8);
887
888 /*
889 * Build the DRB for the next row in MSB so it gets
890 * placed in DRB[n+1] where it belongs when written
891 * as a 16-bit word.
892 */
893 drb &= 0xff;
894 drb |= (drb + (sz.side2 / 8)) << 8;
895 } else {
896#if 0
897 PRINT_DEBUG("No DIMM found in slot ");
898 PRINT_DEBUG_HEX8(i);
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000899 PRINT_DEBUG("\n");
Keith Hui59356ca2010-03-06 18:16:25 +0000900#endif
901
902 /* If there's no DIMM in the slot, set dra to 0x00. */
903 dra = 0x00;
904 ecc = 0xc0;
905 /* Still have to propagate DRB over. */
906 drb &= 0xff;
907 drb |= (drb << 8);
908 }
909
910 pci_write_config16(NB, DRB + (2 * i), drb);
911#if 0
912 PRINT_DEBUG("DRB has been set to 0x");
913 PRINT_DEBUG_HEX16(drb);
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000914 PRINT_DEBUG("\n");
Keith Hui59356ca2010-03-06 18:16:25 +0000915#endif
916
917 /* Brings the upper DRB back down to be base for
918 * DRB calculations for the next two rows.
919 */
920 drb >>= 8;
921
922 rps |= (dra & 0x0f) << (i * 4);
923 nbxecc = (nbxecc >> 2) | (ecc & 0xc0);
924 }
925
926 /* Set paging policy register. */
927 pci_write_config8(NB, PGPOL + 1, bpr);
928 PRINT_DEBUG("PGPOL[BPR] has been set to 0x");
929 PRINT_DEBUG_HEX8(bpr);
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000930 PRINT_DEBUG("\n");
Keith Hui59356ca2010-03-06 18:16:25 +0000931
932 /* Set DRAM row page size register. */
933 pci_write_config16(NB, RPS, rps);
934 PRINT_DEBUG("RPS has been set to 0x");
935 PRINT_DEBUG_HEX16(rps);
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000936 PRINT_DEBUG("\n");
Keith Hui59356ca2010-03-06 18:16:25 +0000937
938 /* ### ECC */
939 pci_write_config8(NB, NBXCFG + 3, nbxecc);
940 PRINT_DEBUG("NBXECC[31:24] has been set to 0x");
941 PRINT_DEBUG_HEX8(nbxecc);
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000942 PRINT_DEBUG("\n");
Keith Hui59356ca2010-03-06 18:16:25 +0000943
944 /* Set DRAMC[4:3] to proper memory type (EDO/SDRAM).
945 * TODO: Registered SDRAM support.
946 */
947 edosd &= 0x07;
948 if (edosd & 0x02) {
949 edosd |= 0x00;
950 } else if (edosd & 0x04) {
951 edosd |= 0x08;
952 }
953 edosd &= 0x18;
954
955 /* edosd is now in the form needed for DRAMC[4:3]. */
956 value = pci_read_config8(NB, DRAMC) & 0xe7;
957 value |= edosd;
958 pci_write_config8(NB, DRAMC, value);
959 PRINT_DEBUG("DRAMC has been set to 0x");
960 PRINT_DEBUG_HEX8(value);
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000961 PRINT_DEBUG("\n");
Keith Hui59356ca2010-03-06 18:16:25 +0000962}
963
Uwe Hermann115c5b92010-10-09 17:00:18 +0000964void sdram_set_spd_registers(void)
Richard Smithcb8eab42006-07-24 04:25:47 +0000965{
Keith Hui59356ca2010-03-06 18:16:25 +0000966 /* Setup DRAM row boundary registers and other attributes. */
967 set_dram_row_attributes();
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000968
Keith Huidf35cdc2010-09-20 23:41:37 +0000969 /* Setup DRAM buffer strength. */
Keith Hui59356ca2010-03-06 18:16:25 +0000970 set_dram_buffer_strength();
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000971
972 /* TODO: Set PMCR? */
Uwe Hermann1683cef2008-11-27 00:47:07 +0000973 // pci_write_config8(NB, PMCR, 0x14);
974 pci_write_config8(NB, PMCR, 0x10);
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000975
Keith Huidf35cdc2010-09-20 23:41:37 +0000976 /* TODO: This is for EDO memory only. */
Uwe Hermann1683cef2008-11-27 00:47:07 +0000977 pci_write_config8(NB, DRAMT, 0x03);
Richard Smithcb8eab42006-07-24 04:25:47 +0000978}
979
Uwe Hermann115c5b92010-10-09 17:00:18 +0000980void sdram_enable(void)
Richard Smithcb8eab42006-07-24 04:25:47 +0000981{
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000982 int i;
Richard Smithcb8eab42006-07-24 04:25:47 +0000983
Uwe Hermann861f9642007-05-28 14:37:06 +0000984 /* 0. Wait until power/voltages and clocks are stable (200us). */
985 udelay(200);
Richard Smithcb8eab42006-07-24 04:25:47 +0000986
Uwe Hermann861f9642007-05-28 14:37:06 +0000987 /* 1. Apply NOP. Wait 200 clock cycles (200us should do). */
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000988 PRINT_DEBUG("RAM Enable 1: Apply NOP\n");
Uwe Hermann8b643cea2008-12-09 16:36:12 +0000989 do_ram_command(RAM_COMMAND_NOP);
Uwe Hermann861f9642007-05-28 14:37:06 +0000990 udelay(200);
Richard Smithcb8eab42006-07-24 04:25:47 +0000991
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000992 /* 2. Precharge all. Wait tRP. */
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000993 PRINT_DEBUG("RAM Enable 2: Precharge all\n");
Uwe Hermann8b643cea2008-12-09 16:36:12 +0000994 do_ram_command(RAM_COMMAND_PRECHARGE);
Uwe Hermann861f9642007-05-28 14:37:06 +0000995 udelay(1);
Richard Smithcb8eab42006-07-24 04:25:47 +0000996
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000997 /* 3. Perform 8 refresh cycles. Wait tRC each time. */
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000998 PRINT_DEBUG("RAM Enable 3: CBR\n");
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000999 for (i = 0; i < 8; i++) {
Uwe Hermann8b643cea2008-12-09 16:36:12 +00001000 do_ram_command(RAM_COMMAND_CBR);
Uwe Hermann861f9642007-05-28 14:37:06 +00001001 udelay(1);
Richard Smithcb8eab42006-07-24 04:25:47 +00001002 }
Uwe Hermann1a9c8922007-04-01 17:24:03 +00001003
1004 /* 4. Mode register set. Wait two memory cycles. */
Stefan Reinauer64ed2b72010-03-31 14:47:43 +00001005 PRINT_DEBUG("RAM Enable 4: Mode register set\n");
Uwe Hermann8b643cea2008-12-09 16:36:12 +00001006 do_ram_command(RAM_COMMAND_MRS);
Uwe Hermann861f9642007-05-28 14:37:06 +00001007 udelay(2);
Uwe Hermann1a9c8922007-04-01 17:24:03 +00001008
1009 /* 5. Normal operation. */
Stefan Reinauer64ed2b72010-03-31 14:47:43 +00001010 PRINT_DEBUG("RAM Enable 5: Normal operation\n");
Uwe Hermann8b643cea2008-12-09 16:36:12 +00001011 do_ram_command(RAM_COMMAND_NORMAL);
Uwe Hermann861f9642007-05-28 14:37:06 +00001012 udelay(1);
Uwe Hermann1a9c8922007-04-01 17:24:03 +00001013
1014 /* 6. Finally enable refresh. */
Stefan Reinauer64ed2b72010-03-31 14:47:43 +00001015 PRINT_DEBUG("RAM Enable 6: Enable refresh\n");
Uwe Hermann1683cef2008-11-27 00:47:07 +00001016 // pci_write_config8(NB, PMCR, 0x10);
1017 spd_enable_refresh();
Uwe Hermann861f9642007-05-28 14:37:06 +00001018 udelay(1);
Uwe Hermann1a9c8922007-04-01 17:24:03 +00001019
Stefan Reinauer64ed2b72010-03-31 14:47:43 +00001020 PRINT_DEBUG("Northbridge following SDRAM init:\n");
Uwe Hermann1a9c8922007-04-01 17:24:03 +00001021 DUMPNORTH();
Richard Smithcb8eab42006-07-24 04:25:47 +00001022}