blob: 66282aa89413a5a9936673979f701631793f5fba [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.
Richard Smithcb8eab42006-07-24 04:25:47 +000016 */
17
Uwe Hermann1a9c8922007-04-01 17:24:03 +000018#include <spd.h>
Uwe Hermann1a9c8922007-04-01 17:24:03 +000019#include <delay.h>
Uwe Hermann115c5b92010-10-09 17:00:18 +000020#include <stdint.h>
Carl-Daniel Hailfinger2ee67792008-10-01 12:52:52 +000021#include <stdlib.h>
Uwe Hermann115c5b92010-10-09 17:00:18 +000022#include <arch/io.h>
Uwe Hermann115c5b92010-10-09 17:00:18 +000023#include <device/pci_def.h>
24#include <console/console.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
Keith Hui09f5a742010-12-23 17:12:03 +000036#define PRINT_DEBUG(x...) printk(BIOS_DEBUG, x)
Keith Huidf35cdc2010-09-20 23:41:37 +000037#define DUMPNORTH() dump_pci_device(NB)
Richard Smithcb8eab42006-07-24 04:25:47 +000038#else
Keith Hui09f5a742010-12-23 17:12:03 +000039#define PRINT_DEBUG(x...)
Uwe Hermann1a9c8922007-04-01 17:24:03 +000040#define DUMPNORTH()
Richard Smithcb8eab42006-07-24 04:25:47 +000041#endif
42
Uwe Hermann1a9c8922007-04-01 17:24:03 +000043/* SDRAMC[7:5] - SDRAM Mode Select (SMS). */
44#define RAM_COMMAND_NORMAL 0x0
45#define RAM_COMMAND_NOP 0x1
46#define RAM_COMMAND_PRECHARGE 0x2
47#define RAM_COMMAND_MRS 0x3
48#define RAM_COMMAND_CBR 0x4
Richard Smithcb8eab42006-07-24 04:25:47 +000049
Uwe Hermann1a9c8922007-04-01 17:24:03 +000050/* Map the JEDEC SPD refresh rates (array index) to 440BX refresh rates as
51 * defined in DRAMC[2:0].
52 *
53 * [0] == Normal 15.625 us -> 15.6 us
54 * [1] == Reduced(.25X) 3.9 us -> 7.8 ns
55 * [2] == Reduced(.5X) 7.8 us -> 7.8 us
56 * [3] == Extended(2x) 31.3 us -> 31.2 us
57 * [4] == Extended(4x) 62.5 us -> 62.4 us
58 * [5] == Extended(8x) 125 us -> 124.8 us
59 */
60static const uint32_t refresh_rate_map[] = {
61 1, 5, 5, 2, 3, 4
62};
Richard Smithcb8eab42006-07-24 04:25:47 +000063
Uwe Hermann1a9c8922007-04-01 17:24:03 +000064/* Table format: register, bitmask, value. */
Keith Huidf35cdc2010-09-20 23:41:37 +000065static const u8 register_values[] = {
Uwe Hermann1a9c8922007-04-01 17:24:03 +000066 /* NBXCFG - NBX Configuration Register
Uwe Hermannf5a6fd22007-05-27 23:31:31 +000067 * 0x50 - 0x53
Uwe Hermann1a9c8922007-04-01 17:24:03 +000068 *
69 * [31:24] SDRAM Row Without ECC
70 * 0 = ECC components are populated in this row
71 * 1 = ECC components are not populated in this row
72 * [23:19] Reserved
73 * [18:18] Host Bus Fast Data Ready Enable (HBFDRE)
74 * Assertion of DRAM data on host bus occurs...
75 * 0 = ...one clock after sampling snoop results (default)
76 * 1 = ...on the same clock the snoop result is being sampled
77 * (this mode is faster by one clock cycle)
78 * [17:17] ECC - EDO static Drive mode
79 * 0 = Normal mode (default)
80 * 1 = ECC signals are always driven
81 * [16:16] IDSEL_REDIRECT
82 * 0 = IDSEL1 is allocated to this bridge (default)
83 * 1 = IDSEL7 is allocated to this bridge
84 * [15:15] WSC# Handshake Disable
85 * 1 = Uni-processor mode
86 * 0 = Dual-processor mode with external IOAPIC (default)
87 * [14:14] Intel Reserved
88 * [13:12] Host/DRAM Frequency
89 * 00 = 100 MHz
90 * 01 = Reserved
91 * 10 = 66 MHz
92 * 11 = Reserved
93 * [11:11] AGP to PCI Access Enable
94 * 1 = Enable
95 * 0 = Disable
96 * [10:10] PCI Agent to Aperture Access Disable
97 * 1 = Disable
98 * 0 = Enable (default)
99 * [09:09] Aperture Access Global Enable
100 * 1 = Enable
101 * 0 = Disable
102 * [08:07] DRAM Data Integrity Mode (DDIM)
103 * 00 = Non-ECC
104 * 01 = EC-only
105 * 10 = ECC Mode
106 * 11 = ECC Mode with hardware scrubbing enabled
107 * [06:06] ECC Diagnostic Mode Enable (EDME)
108 * 1 = Enable
109 * 0 = Normal operation mode (default)
110 * [05:05] MDA Present (MDAP)
111 * Works in conjunction with the VGA_EN bit.
112 * VGA_EN MDAP
113 * 0 x All VGA cycles are sent to PCI
114 * 1 0 All VGA cycles are sent to AGP
115 * 1 1 All VGA cycles are sent to AGP, except for
116 * cycles in the MDA range.
117 * [04:04] Reserved
118 * [03:03] USWC Write Post During I/O Bridge Access Enable (UWPIO)
119 * 1 = Enable
120 * 0 = Disable
121 * [02:02] In-Order Queue Depth (IOQD)
122 * 1 = In-order queue = maximum
123 * 0 = A7# is sampled asserted (i.e., 0)
124 * [01:00] Reserved
Richard Smithcb8eab42006-07-24 04:25:47 +0000125 */
Uwe Hermannbc3594732007-06-07 22:16:30 +0000126 NBXCFG + 0, 0x00, 0x0c,
Keith Huidf35cdc2010-09-20 23:41:37 +0000127 // TODO: Bit 15 should be 0 for multiprocessor boards
Uwe Hermannbc3594732007-06-07 22:16:30 +0000128 NBXCFG + 1, 0x00, 0x80,
129 NBXCFG + 2, 0x00, 0x00,
130 NBXCFG + 3, 0x00, 0xff,
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000131
132 /* DRAMC - DRAM Control Register
133 * 0x57
134 *
135 * [7:6] Reserved
136 * [5:5] Module Mode Configuration (MMCONFIG)
Keith Huidf35cdc2010-09-20 23:41:37 +0000137 * The combination of SDRAMPWR and this bit (which is set by an
138 * external strapping option) determine how CKE works.
139 * SDRAMPWR MMCONFIG
140 * 0 0 = 3 DIMM, CKE0[5:0] driven
141 * X 1 = 3 DIMM, CKE0 only
142 * 1 0 = 4 DIMM, GCKE only
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000143 * [4:3] DRAM Type (DT)
144 * 00 = EDO
145 * 01 = SDRAM
146 * 10 = Registered SDRAM
147 * 11 = Reserved
148 * Note: EDO, SDRAM and Registered SDRAM cannot be mixed.
149 * [2:0] DRAM Refresh Rate (DRR)
150 * 000 = Refresh disabled
151 * 001 = 15.6 us
152 * 010 = 31.2 us
153 * 011 = 62.4 us
154 * 100 = 124.8 us
155 * 101 = 249.6 us
156 * 110 = Reserved
157 * 111 = Reserved
Richard Smithcb8eab42006-07-24 04:25:47 +0000158 */
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000159 /* Choose SDRAM (not registered), and disable refresh for now. */
Uwe Hermannbc3594732007-06-07 22:16:30 +0000160 DRAMC, 0x00, 0x08,
Richard Smithcb8eab42006-07-24 04:25:47 +0000161
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000162 /*
163 * PAM[6:0] - Programmable Attribute Map Registers
Uwe Hermannf5a6fd22007-05-27 23:31:31 +0000164 * 0x59 - 0x5f
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000165 *
166 * 0x59 [3:0] Reserved
167 * 0x59 [5:4] 0xF0000 - 0xFFFFF BIOS area
168 * 0x5a [1:0] 0xC0000 - 0xC3FFF ISA add-on BIOS
169 * 0x5a [5:4] 0xC4000 - 0xC7FFF ISA add-on BIOS
170 * 0x5b [1:0] 0xC8000 - 0xCBFFF ISA add-on BIOS
171 * 0x5b [5:4] 0xCC000 - 0xCFFFF ISA add-on BIOS
172 * 0x5c [1:0] 0xD0000 - 0xD3FFF ISA add-on BIOS
173 * 0x5c [5:4] 0xD4000 - 0xD7FFF ISA add-on BIOS
174 * 0x5d [1:0] 0xD8000 - 0xDBFFF ISA add-on BIOS
175 * 0x5d [5:4] 0xDC000 - 0xDFFFF ISA add-on BIOS
176 * 0x5e [1:0] 0xE0000 - 0xE3FFF BIOS entension
177 * 0x5e [5:4] 0xE4000 - 0xE7FFF BIOS entension
178 * 0x5f [1:0] 0xE8000 - 0xEBFFF BIOS entension
179 * 0x5f [5:4] 0xEC000 - 0xEFFFF BIOS entension
180 *
181 * Bit assignment:
182 * 00 = DRAM Disabled (all access goes to memory mapped I/O space)
183 * 01 = Read Only (Reads to DRAM, writes to memory mapped I/O space)
184 * 10 = Write Only (Writes to DRAM, reads to memory mapped I/O space)
185 * 11 = Read/Write (all access goes to DRAM)
186 */
Keith Hui59356ca2010-03-06 18:16:25 +0000187
188 /*
189 * Map all legacy regions to RAM (read/write). This is required if
190 * you want to use the RAM area from 768 KB - 1 MB. If the PAM
191 * registers are not set here appropriately, the RAM in that region
192 * will not be accessible, thus a RAM check of it will also fail.
193 *
194 * TODO: This was set in sdram_set_spd_registers().
195 * Test if it still works when set here.
196 */
197 PAM0, 0x00, 0x30,
198 PAM1, 0x00, 0x33,
199 PAM2, 0x00, 0x33,
200 PAM3, 0x00, 0x33,
201 PAM4, 0x00, 0x33,
202 PAM5, 0x00, 0x33,
203 PAM6, 0x00, 0x33,
Richard Smithcb8eab42006-07-24 04:25:47 +0000204
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000205 /* DRB[0:7] - DRAM Row Boundary Registers
206 * 0x60 - 0x67
207 *
208 * An array of 8 byte registers, which hold the ending memory address
Anders Jenbo0e1e8062010-04-27 06:35:31 +0000209 * assigned to each pair of DIMMs, in 8MB granularity.
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000210 *
211 * 0x60 DRB0 = Total memory in row0 (in 8 MB)
212 * 0x61 DRB1 = Total memory in row0+1 (in 8 MB)
213 * 0x62 DRB2 = Total memory in row0+1+2 (in 8 MB)
214 * 0x63 DRB3 = Total memory in row0+1+2+3 (in 8 MB)
215 * 0x64 DRB4 = Total memory in row0+1+2+3+4 (in 8 MB)
216 * 0x65 DRB5 = Total memory in row0+1+2+3+4+5 (in 8 MB)
217 * 0x66 DRB6 = Total memory in row0+1+2+3+4+5+6 (in 8 MB)
218 * 0x67 DRB7 = Total memory in row0+1+2+3+4+5+6+7 (in 8 MB)
219 */
Uwe Hermannf5a6fd22007-05-27 23:31:31 +0000220 /* Set the DRBs to zero for now, this will be fixed later. */
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000221 DRB0, 0x00, 0x00,
222 DRB1, 0x00, 0x00,
223 DRB2, 0x00, 0x00,
224 DRB3, 0x00, 0x00,
225 DRB4, 0x00, 0x00,
226 DRB5, 0x00, 0x00,
227 DRB6, 0x00, 0x00,
228 DRB7, 0x00, 0x00,
229
230 /* FDHC - Fixed DRAM Hole Control Register
231 * 0x68
232 *
233 * Controls two fixed DRAM holes: 512 KB - 640 KB and 15 MB - 16 MB.
234 *
235 * [7:6] Hole Enable (HEN)
236 * 00 = None
237 * 01 = 512 KB - 640 KB (128 KB)
238 * 10 = 15 MB - 16 MB (1 MB)
239 * 11 = Reserved
240 * [5:0] Reserved
241 */
242 /* No memory holes. */
243 FDHC, 0x00, 0x00,
244
245 /* RPS - SDRAM Row Page Size Register
246 * 0x74 - 0x75
247 *
248 * Sets the row page size for SDRAM. For EDO memory, the page
249 * size is fixed at 2 KB.
250 *
Keith Huidf35cdc2010-09-20 23:41:37 +0000251 * Bits[1:0] Page Size
252 * 00 2 KB
253 * 01 4 KB
254 * 10 8 KB
255 * 11 Reserved
Keith Huie089a3f2011-08-02 22:28:14 -0400256 *
Keith Huidf35cdc2010-09-20 23:41:37 +0000257 * RPS bits Corresponding DRB register
258 * [01:00] DRB[0], row 0
259 * [03:02] DRB[1], row 1
260 * [05:04] DRB[2], row 2
261 * [07:06] DRB[3], row 3
262 * [09:08] DRB[4], row 4
263 * [11:10] DRB[5], row 5
264 * [13:12] DRB[6], row 6
265 * [15:14] DRB[7], row 7
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000266 */
Keith Huidf35cdc2010-09-20 23:41:37 +0000267 /* Power on defaults to 2KB. Will be set later. */
268 // RPS + 0, 0x00, 0x00,
269 // RPS + 1, 0x00, 0x00,
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000270
271 /* SDRAMC - SDRAM Control Register
Uwe Hermann7ea18cf2007-05-04 00:51:17 +0000272 * 0x76 - 0x77
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000273 *
274 * [15:10] Reserved
275 * [09:08] Idle/Pipeline DRAM Leadoff Timing (IPDLT)
276 * 00 = Illegal
277 * 01 = Add a clock delay to the lead-off clock count
Keith Huidf35cdc2010-09-20 23:41:37 +0000278 * 1x = Illegal
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000279 * [07:05] SDRAM Mode Select (SMS)
280 * 000 = Normal SDRAM Operation (default)
281 * 001 = NOP Command Enable
282 * 010 = All Banks Precharge Enable
283 * 011 = Mode Register Set Enable
284 * 100 = CBR Enable
285 * 101 = Reserved
286 * 110 = Reserved
287 * 111 = Reserved
288 * [04:04] SDRAMPWR
289 * 0 = 3 DIMM configuration
290 * 1 = 4 DIMM configuration
291 * [03:03] Leadoff Command Timing (LCT)
292 * 0 = 4 CS# Clock
293 * 1 = 3 CS# Clock
294 * [02:02] CAS# Latency (CL)
295 * 0 = 3 DCLK CAS# latency
296 * 1 = 2 DCLK CAS# latency
297 * [01:01] SDRAM RAS# to CAS# Delay (SRCD)
298 * 0 = 3 clocks between a row activate and a read or write cmd.
299 * 1 = 2 clocks between a row activate and a read or write cmd.
300 * [00:00] SDRAM RAS# Precharge (SRP)
301 * 0 = 3 clocks of RAS# precharge
302 * 1 = 2 clocks of RAS# precharge
303 */
Keith Hui9c1e1f02010-03-13 20:16:48 +0000304#if CONFIG_SDRAMPWR_4DIMM
305 SDRAMC + 0, 0x00, 0x10, /* The board has 4 DIMM slots. */
306#else
Keith Huidf35cdc2010-09-20 23:41:37 +0000307 SDRAMC + 0, 0x00, 0x00, /* The board has 3 DIMM slots. */
Keith Hui9c1e1f02010-03-13 20:16:48 +0000308#endif
Mats Erik Andersson45db3662008-09-30 04:52:29 +0000309 SDRAMC + 1, 0x00, 0x00,
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000310
311 /* PGPOL - Paging Policy Register
312 * 0x78 - 0x79
313 *
314 * [15:08] Banks per Row (BPR)
Keith Huidf35cdc2010-09-20 23:41:37 +0000315 * Each bit in this field corresponds to one row of the memory
316 * array. Bit 15 corresponds to row 7 while bit 8 corresponds
317 * to row 0. Bits for empty rows are "don't care".
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000318 * 0 = 2 banks
319 * 1 = 4 banks
320 * [07:05] Reserved
321 * [04:04] Intel Reserved
322 * [03:00] DRAM Idle Timer (DIT)
323 * 0000 = 0 clocks
324 * 0001 = 2 clocks
325 * 0010 = 4 clocks
326 * 0011 = 8 clocks
327 * 0100 = 10 clocks
328 * 0101 = 12 clocks
329 * 0110 = 16 clocks
330 * 0111 = 32 clocks
331 * 1xxx = Infinite (pages are not closed for idle condition)
332 */
Uwe Hermannbc3594732007-06-07 22:16:30 +0000333 PGPOL + 0, 0x00, 0x00,
334 PGPOL + 1, 0x00, 0xff,
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000335
336 /* PMCR - Power Management Control Register
337 * 0x7a
338 *
339 * [07:07] Power Down SDRAM Enable (PDSE)
340 * 1 = Enable
341 * 0 = Disable
342 * [06:06] ACPI Control Register Enable (SCRE)
343 * 1 = Enable
344 * 0 = Disable (default)
345 * [05:05] Suspend Refresh Type (SRT)
346 * 1 = Self refresh mode
347 * 0 = CBR fresh mode
348 * [04:04] Normal Refresh Enable (NREF_EN)
349 * 1 = Enable
350 * 0 = Disable
351 * [03:03] Quick Start Mode (QSTART)
352 * 1 = Quick start mode for the processor is enabled
353 * [02:02] Gated Clock Enable (GCLKEN)
354 * 1 = Enable
355 * 0 = Disable
356 * [01:01] AGP Disable (AGP_DIS)
357 * 1 = Disable
358 * 0 = Enable
359 * [00:00] CPU reset without PCIRST enable (CRst_En)
360 * 1 = Enable
361 * 0 = Disable
362 */
363 /* Enable normal refresh and the gated clock. */
364 // TODO: Only do this later?
365 // PMCR, 0x00, 0x14,
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000366 PMCR, 0x00, 0x00,
Keith Hui59356ca2010-03-06 18:16:25 +0000367
368 /* Enable SCRR.SRRAEN and let BX choose the SRR. */
369 SCRR + 1, 0x00, 0x10,
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000370};
371
372/*-----------------------------------------------------------------------------
373SDRAM configuration functions.
374-----------------------------------------------------------------------------*/
375
376/**
377 * Send the specified RAM command to all DIMMs.
378 *
Uwe Hermann8b643cea2008-12-09 16:36:12 +0000379 * @param command The RAM command to send to the DIMM(s).
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000380 */
Uwe Hermann8b643cea2008-12-09 16:36:12 +0000381static void do_ram_command(u32 command)
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000382{
Uwe Hermann8b643cea2008-12-09 16:36:12 +0000383 int i, caslatency;
384 u8 dimm_start, dimm_end;
385 u16 reg16;
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -0800386 void *addr;
387 u32 addr_offset;
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000388
389 /* Configure the RAM command. */
Uwe Hermann8b643cea2008-12-09 16:36:12 +0000390 reg16 = pci_read_config16(NB, SDRAMC);
391 reg16 &= 0xff1f; /* Clear bits 7-5. */
392 reg16 |= (u16) (command << 5); /* Write command into bits 7-5. */
393 pci_write_config16(NB, SDRAMC, reg16);
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000394
Uwe Hermann8b643cea2008-12-09 16:36:12 +0000395 /*
396 * RAM_COMMAND_NORMAL affects only the memory controller and
397 * doesn't need to be "sent" to the DIMMs.
398 */
399 if (command == RAM_COMMAND_NORMAL)
400 return;
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000401
Uwe Hermann8b643cea2008-12-09 16:36:12 +0000402 /* Send the RAM command to each row of memory. */
403 dimm_start = 0;
404 for (i = 0; i < (DIMM_SOCKETS * 2); i++) {
Keith Hui59356ca2010-03-06 18:16:25 +0000405 addr_offset = 0;
406 caslatency = 3; /* TODO: Dynamically get CAS latency later. */
Uwe Hermann8b643cea2008-12-09 16:36:12 +0000407 if (command == RAM_COMMAND_MRS) {
408 /*
409 * MAA[12:11,9:0] must be inverted when sent to DIMM
410 * 2 or 3 (no inversion if sent to DIMM 0 or 1).
411 */
412 if ((i >= 0 && i <= 3) && caslatency == 3)
413 addr_offset = 0x1d0;
414 if ((i >= 4 && i <= 7) && caslatency == 3)
415 addr_offset = 0x1e28;
416 if ((i >= 0 && i <= 3) && caslatency == 2)
417 addr_offset = 0x150;
418 if ((i >= 4 && i <= 7) && caslatency == 2)
419 addr_offset = 0x1ea8;
420 }
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000421
Uwe Hermann8b643cea2008-12-09 16:36:12 +0000422 dimm_end = pci_read_config8(NB, DRB + i);
423
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -0800424 addr = (void *)((dimm_start * 8 * 1024 * 1024) + addr_offset);
Uwe Hermann8b643cea2008-12-09 16:36:12 +0000425 if (dimm_end > dimm_start) {
426#if 0
Stefan Reinauerfc01e5e2010-12-27 14:31:05 +0000427 PRINT_DEBUG(" Sending RAM command 0x%04x to 0x%08x\n",
428 reg16, addr);
Uwe Hermann8b643cea2008-12-09 16:36:12 +0000429#endif
430
431 read32(addr);
432 }
433
434 /* Set the start of the next DIMM. */
435 dimm_start = dimm_end;
436 }
Richard Smithcb8eab42006-07-24 04:25:47 +0000437}
438
Keith Hui59356ca2010-03-06 18:16:25 +0000439static void set_dram_buffer_strength(void)
440{
Keith Huib48ba662010-03-17 02:15:07 +0000441 /* To give some breathing room for romcc,
Anders Jenbo0e1e8062010-04-27 06:35:31 +0000442 * mbsc0 doubles as drb
Keith Huib48ba662010-03-17 02:15:07 +0000443 * mbsc1 doubles as drb1
444 * mbfs0 doubles as i and reg
Keith Hui59356ca2010-03-06 18:16:25 +0000445 */
Keith Huib48ba662010-03-17 02:15:07 +0000446 uint8_t mbsc0,mbsc1,mbsc3,mbsc4,mbfs0,mbfs2,fsb;
Keith Hui59356ca2010-03-06 18:16:25 +0000447
Anders Jenbo0e1e8062010-04-27 06:35:31 +0000448 /* Tally how many rows between rows 0-3 and rows 4-7 are populated.
Keith Huib48ba662010-03-17 02:15:07 +0000449 * This determines how to program MBFS and MBSC.
450 */
451 uint8_t dimm03 = 0;
452 uint8_t dimm47 = 0;
453
454 mbsc0 = 0;
455 for (mbfs0 = DRB0; mbfs0 <= DRB7; mbfs0++) {
456 mbsc1 = pci_read_config8(NB, mbfs0);
457 if (mbsc0 != mbsc1) {
458 if (mbfs0 <= DRB3) {
459 dimm03++;
460 } else {
461 dimm47++;
462 }
463 mbsc0 = mbsc1;
464 }
465 }
466
Keith Huidf35cdc2010-09-20 23:41:37 +0000467 /* Algorithm bitmap for programming MBSC[39:0] and MBFS[23:0].
Keith Huib48ba662010-03-17 02:15:07 +0000468 *
Keith Huidf35cdc2010-09-20 23:41:37 +0000469 * The 440BX datasheet says buffer frequency is independent from bus
470 * frequency and mismatch both ways are possible. This is how it is
471 * programmed in the ASUS P2B-LS mainboard.
Keith Huib48ba662010-03-17 02:15:07 +0000472 *
473 * There are four main conditions to check when programming DRAM buffer
474 * frequency and strength:
475 *
476 * a: >2 rows populated across DIMM0,1
477 * b: >2 rows populated across DIMM2,3
478 * c: >4 rows populated across all DIMM slots
479 * and either one of:
480 * 1: NBXCFG[13] strapped as 100MHz, or
481 * 6: NBXCFG[13] strapped as 66MHz
482 *
483 * CKE0/FENA ----------------------------------------------------------+
484 * CKE1/GCKE -------------------[ MBFS ]------------------------+|
485 * DQMA/CASA[764320]# ----------[ 0 = 66MHz ]-----------------------+||
486 * DQMB1/CASB1# ----------------[ 1 = 100MHz ]----------------------+|||
487 * DQMB5/CASB5# ---------------------------------------------------+||||
488 * DQMA1/CASA1# --------------------------------------------------+|||||
489 * DQMA5/CASA5# -------------------------------------------------+||||||
490 * CSA0-5#,CSB0-5# ----------------------------------------++++++|||||||
491 * CSA6#/CKE2# -------------------------------------------+|||||||||||||
492 * CSB6#/CKE4# ------------------------------------------+||||||||||||||
493 * CSA7#/CKE3# -----------------------------------------+|||||||||||||||
494 * CSB7#/CKE5# ----------------------------------------+||||||||||||||||
495 * MECC[7:0] #2/#1 (100MHz) -------------------------++|||||||||||||||||
496 * MD[63:0] #2/#1 (100MHz) ------------------------++|||||||||||||||||||
497 * MAB[12:11,9:0]#,MAB[13,10],WEB#,SRASB#,SCASB# -+|||||||||||||||||||||
498 * MAA[13:0],WEA#,SRASA#,SCASA# -----------------+||||||||||||||||||||||
499 * Reserved ------------------------------------+|||||||||||||||||||||||
500 * ||||||||||||||||||||||||
501 * 3 32 21 10 0 * 2 21 10 0
502 * 9876543210987654321098765432109876543210 * 321098765432109876543210
503 * a 10------------------------1010---------- * -1---------------11----- a
504 *!a 11------------------------1111---------- * -0---------------00----- !a
505 * b --10--------------------------1010------ * --1----------------11--- b
506 *!b --11--------------------------1111------ * --0----------------00--- !b
507 * c ----------------------------------1100-- * ----------------------1- c
508 *!c ----------------------------------1011-- * ----------------------0- !c
509 * 1 ----1010101000000000000000------------00 * ---11111111111111----1-0 1
510 * 6 ----000000000000000000000010101010----00 * ---1111111111111100000-0 6
511 * | | | | | | | | | | ||||||| | | | | | |
512 * | | | | | | | | | | ||||||| | | | | | +- CKE0/FENA
513 * | | | | | | | | | | ||||||| | | | | +--- CKE1/GCKE
514 * | | | | | | | | | | ||||||| | | | +----- DQMA/CASA[764320]#
515 * | | | | | | | | | | ||||||| | | +------- DQMB1/CASB1#
516 * | | | | | | | | | | ||||||| | +--------- DQMB5/CASB5#
517 * | | | | | | | | | | ||||||| +----------- DQMA1/CASA1#
518 * | | | | | | | | | | ||||||+------------- DQMA5/CASA5#
519 * | | | | | | | | | | ++++++-------------- CSA0-5#,CSB0-5# [ 0=1x;1=2x ]
520 * | | | | | | | | | +--------------------- CSA6#/CKE2#
521 * | | | | | | | | +---[ MBSC ]------ CSB6#/CKE4#
522 * | | | | | | | +-----[ 00 = 1x ]------ CSA7#/CKE3#
523 * | | | | | | +-------[ 01 invalid ]------ CSB7#/CKE5#
524 * | | | | | +---------[ 10 = 2x ]------ MECC[7:0] #1 (2x)
525 * | | | | +-----------[ 11 = 3x ]------ MECC[7:0] #2 (2x)
526 * | | | +--------------------------------- MD[63:0] #1 (2x)
527 * | | +----------------------------------- MD[63:0] #2 (2x)
528 * | +------------------------------------- MAB[12:11,9:0]#,MAB[13,10],WEB#,SRASB#,SCASB#
529 * +--------------------------------------- MAA[13:0],WEA#,SRASA#,SCASA#
530 * MBSC[47:40] and MBFS[23] are reserved.
531 *
Keith Huidf35cdc2010-09-20 23:41:37 +0000532 * This algorithm is checked against the ASUS P2B-LS (which has
533 * 4 DIMM slots) factory BIOS.
Keith Huib48ba662010-03-17 02:15:07 +0000534 * Therefore it assumes a board with 4 slots, and will need testing
535 * on boards with 3 DIMM slots.
536 */
Anders Jenbo0e1e8062010-04-27 06:35:31 +0000537
Keith Huib48ba662010-03-17 02:15:07 +0000538 mbsc0 = 0x80;
539 mbsc1 = 0x2a;
540 mbfs2 = 0x1f;
541 if (pci_read_config8(NB, NBXCFG + 1) & 0x30) {
542 fsb = 66;
543 mbsc3 = 0x00;
544 mbsc4 = 0x00;
545 mbfs0 = 0x80;
546 } else {
547 fsb = 100;
548 mbsc3 = 0xa0;
549 mbsc4 = 0x0a;
550 mbfs0 = 0x84;
551 }
Anders Jenbo0e1e8062010-04-27 06:35:31 +0000552
553 if (dimm03 > 2) {
554 mbsc4 = mbsc4 | 0x80;
Keith Huib48ba662010-03-17 02:15:07 +0000555 mbsc1 = mbsc1 | 0x28;
556 mbfs2 = mbfs2 | 0x40;
557 mbfs0 = mbfs0 | 0x60;
Anders Jenbo0e1e8062010-04-27 06:35:31 +0000558 } else {
559 mbsc4 = mbsc4 | 0xc0;
Keith Huib48ba662010-03-17 02:15:07 +0000560 if (fsb == 100) {
561 mbsc1 = mbsc1 | 0x3c;
562 }
Anders Jenbo0e1e8062010-04-27 06:35:31 +0000563 }
564 if (dimm47 > 2) {
565 mbsc4 = mbsc4 | 0x20;
566 mbsc1 = mbsc1 | 0x02;
Keith Huib48ba662010-03-17 02:15:07 +0000567 mbsc0 = mbsc0 | 0x80;
568 mbfs2 = mbfs2 | 0x20;
569 mbfs0 = mbfs0 | 0x18;
Anders Jenbo0e1e8062010-04-27 06:35:31 +0000570 } else {
Keith Huib48ba662010-03-17 02:15:07 +0000571 mbsc4 = mbsc4 | 0x30;
572 if (fsb == 100) {
Anders Jenbo0e1e8062010-04-27 06:35:31 +0000573 mbsc1 = mbsc1 | 0x03;
Keith Huib48ba662010-03-17 02:15:07 +0000574 mbsc0 = mbsc0 | 0xc0;
575 }
576 }
Anders Jenbo0e1e8062010-04-27 06:35:31 +0000577 if ((dimm03 + dimm47) > 4) {
Keith Huib48ba662010-03-17 02:15:07 +0000578 mbsc0 = mbsc0 | 0x30;
579 mbfs0 = mbfs0 | 0x02;
Anders Jenbo0e1e8062010-04-27 06:35:31 +0000580 } else {
581 mbsc0 = mbsc0 | 0x2c;
Keith Huib48ba662010-03-17 02:15:07 +0000582 }
583
584 pci_write_config8(NB, MBSC + 0, mbsc0);
585 pci_write_config8(NB, MBSC + 1, mbsc1);
586 pci_write_config8(NB, MBSC + 2, 0x00);
587 pci_write_config8(NB, MBSC + 3, mbsc3);
588 pci_write_config8(NB, MBSC + 4, mbsc4);
589 pci_write_config8(NB, MBFS + 0, mbfs0);
590 pci_write_config8(NB, MBFS + 1, 0xff);
591 pci_write_config8(NB, MBFS + 2, mbfs2);
Keith Hui59356ca2010-03-06 18:16:25 +0000592}
593
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000594/*-----------------------------------------------------------------------------
595DIMM-independant configuration functions.
596-----------------------------------------------------------------------------*/
Richard Smithcb8eab42006-07-24 04:25:47 +0000597
Uwe Hermann1683cef2008-11-27 00:47:07 +0000598static void spd_enable_refresh(void)
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000599{
600 int i, value;
601 uint8_t reg;
602
Uwe Hermann1683cef2008-11-27 00:47:07 +0000603 reg = pci_read_config8(NB, DRAMC);
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000604
605 for (i = 0; i < DIMM_SOCKETS; i++) {
Uwe Hermannd773fd32010-11-20 20:23:08 +0000606 value = spd_read_byte(DIMM0 + i, SPD_REFRESH);
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000607 if (value < 0)
608 continue;
609 reg = (reg & 0xf8) | refresh_rate_map[(value & 0x7f)];
610
Keith Hui09f5a742010-12-23 17:12:03 +0000611 PRINT_DEBUG(" Enabling refresh (DRAMC = 0x%02x) for DIMM %02x\n", reg, i);
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000612 }
613
Uwe Hermann1683cef2008-11-27 00:47:07 +0000614 pci_write_config8(NB, DRAMC, reg);
Richard Smithcb8eab42006-07-24 04:25:47 +0000615}
616
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000617/*-----------------------------------------------------------------------------
618Public interface.
619-----------------------------------------------------------------------------*/
620
Uwe Hermann115c5b92010-10-09 17:00:18 +0000621void sdram_set_registers(void)
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000622{
623 int i, max;
Uwe Hermannbc3594732007-06-07 22:16:30 +0000624 uint8_t reg;
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000625
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000626 PRINT_DEBUG("Northbridge prior to SDRAM init:\n");
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000627 DUMPNORTH();
628
Carl-Daniel Hailfinger2ee67792008-10-01 12:52:52 +0000629 max = ARRAY_SIZE(register_values);
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000630
Uwe Hermannf5a6fd22007-05-27 23:31:31 +0000631 /* Set registers as specified in the register_values[] array. */
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000632 for (i = 0; i < max; i += 3) {
Uwe Hermann1683cef2008-11-27 00:47:07 +0000633 reg = pci_read_config8(NB, register_values[i]);
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000634 reg &= register_values[i + 1];
635 reg |= register_values[i + 2] & ~(register_values[i + 1]);
Uwe Hermann1683cef2008-11-27 00:47:07 +0000636 pci_write_config8(NB, register_values[i], reg);
Keith Hui59356ca2010-03-06 18:16:25 +0000637#if 0
Stefan Reinauerfc01e5e2010-12-27 14:31:05 +0000638 PRINT_DEBUG(" Set register 0x%02x to 0x%02x\n",
639 register_values[i], reg);
Keith Hui59356ca2010-03-06 18:16:25 +0000640#endif
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000641 }
642}
643
Keith Hui59356ca2010-03-06 18:16:25 +0000644struct dimm_size {
Keith Hui09f5a742010-12-23 17:12:03 +0000645 u32 side1;
646 u32 side2;
Keith Hui59356ca2010-03-06 18:16:25 +0000647};
648
649static struct dimm_size spd_get_dimm_size(unsigned int device)
650{
651 struct dimm_size sz;
652 int i, module_density, dimm_banks;
653 sz.side1 = 0;
654 module_density = spd_read_byte(device, SPD_DENSITY_OF_EACH_ROW_ON_MODULE);
655 dimm_banks = spd_read_byte(device, SPD_NUM_DIMM_BANKS);
656
657 /* Find the size of side1. */
658 /* Find the larger value. The larger value is always side1. */
659 for (i = 512; i >= 0; i >>= 1) {
660 if ((module_density & i) == i) {
661 sz.side1 = i;
662 break;
663 }
664 }
665
666 /* Set to 0 in case it's single sided. */
667 sz.side2 = 0;
668
669 /* Test if it's a dual-sided DIMM. */
670 if (dimm_banks > 1) {
671 /* Test if there's a second value. If so it's asymmetrical. */
672 if (module_density != i) {
673 /*
674 * Find second value, picking up where we left off.
675 * i >>= 1 done initially to make sure we don't get
676 * the same value again.
677 */
678 for (i >>= 1; i >= 0; i >>= 1) {
679 if (module_density == (sz.side1 | i)) {
680 sz.side2 = i;
681 break;
682 }
683 }
684 /* If not, it's symmetrical. */
685 } else {
686 sz.side2 = sz.side1;
687 }
688 }
689
690 /*
691 * SPD byte 31 is the memory size divided by 4 so we
692 * need to muliply by 4 to get the total size.
693 */
694 sz.side1 *= 4;
695 sz.side2 *= 4;
696
Anders Jenbo771b0e42010-04-27 08:45:30 +0000697 /* It is possible to partially use larger then supported
698 * modules by setting them to a supported size.
699 */
Elyes HAOUAS12df9502016-08-23 21:29:48 +0200700 if (sz.side1 > 128) {
Keith Hui09f5a742010-12-23 17:12:03 +0000701 PRINT_DEBUG("Side1 was %dMB but only 128MB will be used.\n",
702 sz.side1);
Anders Jenbo771b0e42010-04-27 08:45:30 +0000703 sz.side1 = 128;
704
Elyes HAOUAS12df9502016-08-23 21:29:48 +0200705 if (sz.side2 > 128) {
Keith Hui09f5a742010-12-23 17:12:03 +0000706 PRINT_DEBUG("Side2 was %dMB but only 128MB will be used.\n",
707 sz.side2);
Anders Jenbo771b0e42010-04-27 08:45:30 +0000708 sz.side2 = 128;
709 }
710 }
711
Keith Hui59356ca2010-03-06 18:16:25 +0000712 return sz;
713}
714/*
715 * Sets DRAM attributes one DIMM at a time, based on SPD data.
716 * Northbridge settings that are set: NBXCFG[31:24], DRB0-DRB7, RPS, DRAMC.
717 */
718static void set_dram_row_attributes(void)
719{
Keith Huie089a3f2011-08-02 22:28:14 -0400720 int i, dra, drb, col, width, value, rps;
Keith Hui59356ca2010-03-06 18:16:25 +0000721 u8 bpr; /* Top 8 bits of PGPOL */
Keith Huie089a3f2011-08-02 22:28:14 -0400722 u8 nbxecc = 0; /* NBXCFG[31:24] */
723 u8 edo, sd, regsd; /* EDO, SDRAM, registered SDRAM */
Keith Hui59356ca2010-03-06 18:16:25 +0000724
Keith Huie089a3f2011-08-02 22:28:14 -0400725 edo = 0;
726 sd = 0;
727 regsd = 1;
Keith Hui59356ca2010-03-06 18:16:25 +0000728 rps = 0;
729 drb = 0;
730 bpr = 0;
Keith Hui59356ca2010-03-06 18:16:25 +0000731
732 for (i = 0; i < DIMM_SOCKETS; i++) {
733 unsigned int device;
Uwe Hermannd773fd32010-11-20 20:23:08 +0000734 device = DIMM0 + i;
Keith Hui59356ca2010-03-06 18:16:25 +0000735 bpr >>= 2;
Keith Huie089a3f2011-08-02 22:28:14 -0400736 nbxecc >>= 2;
Keith Hui59356ca2010-03-06 18:16:25 +0000737
738 /* First check if a DIMM is actually present. */
739 value = spd_read_byte(device, SPD_MEMORY_TYPE);
740 /* This is 440BX! We do EDO too! */
741 if (value == SPD_MEMORY_TYPE_EDO
742 || value == SPD_MEMORY_TYPE_SDRAM) {
743
Keith Hui59356ca2010-03-06 18:16:25 +0000744 if (value == SPD_MEMORY_TYPE_EDO) {
Keith Huie089a3f2011-08-02 22:28:14 -0400745 edo = 1;
Anders Jenbo0e1e8062010-04-27 06:35:31 +0000746 } else if (value == SPD_MEMORY_TYPE_SDRAM) {
Keith Huie089a3f2011-08-02 22:28:14 -0400747 sd = 1;
Keith Hui59356ca2010-03-06 18:16:25 +0000748 }
Keith Hui09f5a742010-12-23 17:12:03 +0000749 PRINT_DEBUG("Found DIMM in slot %d\n", i);
Keith Hui59356ca2010-03-06 18:16:25 +0000750
Keith Huie089a3f2011-08-02 22:28:14 -0400751 if (edo && sd) {
Stefan Reinauer65b72ab2015-01-05 12:59:54 -0800752 printk(BIOS_ERR, "Mixing EDO/SDRAM unsupported!\n");
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000753 die("HALT\n");
Keith Hui59356ca2010-03-06 18:16:25 +0000754 }
755
756 /* "DRA" is our RPS for the two rows on this DIMM. */
757 dra = 0;
758
759 /* Columns */
760 col = spd_read_byte(device, SPD_NUM_COLUMNS);
761
762 /*
763 * Is this an ECC DIMM? Actually will be a 2 if so.
764 * TODO: Other register than NBXCFG also needs this
765 * ECC information.
766 */
Keith Huie089a3f2011-08-02 22:28:14 -0400767 value = spd_read_byte(device, SPD_DIMM_CONFIG_TYPE);
Keith Hui59356ca2010-03-06 18:16:25 +0000768
769 /* Data width */
770 width = spd_read_byte(device, SPD_MODULE_DATA_WIDTH_LSB);
Anders Jenbo0e1e8062010-04-27 06:35:31 +0000771
Keith Hui59356ca2010-03-06 18:16:25 +0000772 /* Exclude error checking data width from page size calculations */
Keith Huie089a3f2011-08-02 22:28:14 -0400773 if (value) {
Keith Hui59356ca2010-03-06 18:16:25 +0000774 value = spd_read_byte(device,
775 SPD_ERROR_CHECKING_SDRAM_WIDTH);
776 width -= value;
777 /* ### ECC */
778 /* Clear top 2 bits to help set up NBXCFG. */
Keith Huie089a3f2011-08-02 22:28:14 -0400779 nbxecc &= 0x3f;
Keith Hui59356ca2010-03-06 18:16:25 +0000780 } else {
781 /* Without ECC, top 2 bits should be 11. */
Keith Huie089a3f2011-08-02 22:28:14 -0400782 nbxecc |= 0xc0;
Keith Hui59356ca2010-03-06 18:16:25 +0000783 }
784
Keith Huie089a3f2011-08-02 22:28:14 -0400785 /* If any installed DIMM is *not* registered, this system cannot be
786 * configured for registered SDRAM.
787 * By registered, only the address and control lines need to be, which
788 * we can tell by reading SPD byte 21, bit 1.
789 */
790 value = spd_read_byte(device, SPD_MODULE_ATTRIBUTES);
791
792 PRINT_DEBUG("DIMM is ");
793 if ((value & MODULE_REGISTERED) == 0) {
794 regsd = 0;
795 PRINT_DEBUG("not ");
796 }
797 PRINT_DEBUG("registered\n");
798
Keith Hui59356ca2010-03-06 18:16:25 +0000799 /* Calculate page size in bits. */
800 value = ((1 << col) * width);
801
802 /* Convert to KB. */
803 dra = (value >> 13);
804
805 /* Number of banks of DIMM (single or double sided). */
806 value = spd_read_byte(device, SPD_NUM_DIMM_BANKS);
807
808 /* Once we have dra, col is done and can be reused.
809 * So it's reused for number of banks.
810 */
811 col = spd_read_byte(device, SPD_NUM_BANKS_PER_SDRAM);
812
813 if (value == 1) {
814 /*
815 * Second bank of 1-bank DIMMs "doesn't have
816 * ECC" - or anything.
817 */
Keith Hui59356ca2010-03-06 18:16:25 +0000818 if (dra == 2) {
819 dra = 0x0; /* 2KB */
820 } else if (dra == 4) {
821 dra = 0x1; /* 4KB */
822 } else if (dra == 8) {
823 dra = 0x2; /* 8KB */
Anders Jenbo771b0e42010-04-27 08:45:30 +0000824 } else if (dra >= 16) {
825 /* Page sizes larger than supported are
826 * set to 8KB to use module partially.
827 */
828 PRINT_DEBUG("Page size forced to 8KB.\n");
829 dra = 0x2; /* 8KB */
Keith Hui59356ca2010-03-06 18:16:25 +0000830 } else {
831 dra = -1;
832 }
833 /*
834 * Sets a flag in PGPOL[BPR] if this DIMM has
835 * 4 banks per row.
836 */
837 if (col == 4)
838 bpr |= 0x40;
839 } else if (value == 2) {
840 if (dra == 2) {
841 dra = 0x0; /* 2KB */
842 } else if (dra == 4) {
843 dra = 0x05; /* 4KB */
844 } else if (dra == 8) {
845 dra = 0x0a; /* 8KB */
Anders Jenbo771b0e42010-04-27 08:45:30 +0000846 } else if (dra >= 16) {
847 /* Ditto */
848 PRINT_DEBUG("Page size forced to 8KB.\n");
849 dra = 0x0a; /* 8KB */
Keith Hui59356ca2010-03-06 18:16:25 +0000850 } else {
851 dra = -1;
852 }
853 /* Ditto */
854 if (col == 4)
855 bpr |= 0xc0;
856 } else {
Stefan Reinauer65b72ab2015-01-05 12:59:54 -0800857 printk(BIOS_ERR, "# of banks of DIMM unsupported!\n");
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000858 die("HALT\n");
Keith Hui59356ca2010-03-06 18:16:25 +0000859 }
860 if (dra == -1) {
Stefan Reinauer65b72ab2015-01-05 12:59:54 -0800861 printk(BIOS_ERR, "Page size not supported\n");
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000862 die("HALT\n");
Keith Hui59356ca2010-03-06 18:16:25 +0000863 }
864
865 /*
866 * 440BX supports asymmetrical dual-sided DIMMs,
867 * but can't handle DIMMs smaller than 8MB per
Anders Jenbo771b0e42010-04-27 08:45:30 +0000868 * side.
Keith Hui59356ca2010-03-06 18:16:25 +0000869 */
870 struct dimm_size sz = spd_get_dimm_size(device);
871 if ((sz.side1 < 8)) {
Stefan Reinauer65b72ab2015-01-05 12:59:54 -0800872 printk(BIOS_ERR, "DIMMs smaller than 8MB per side\n"
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000873 "are not supported on this NB.\n");
874 die("HALT\n");
Keith Hui59356ca2010-03-06 18:16:25 +0000875 }
Keith Hui59356ca2010-03-06 18:16:25 +0000876
877 /* Divide size by 8 to set up the DRB registers. */
878 drb += (sz.side1 / 8);
879
880 /*
881 * Build the DRB for the next row in MSB so it gets
882 * placed in DRB[n+1] where it belongs when written
883 * as a 16-bit word.
884 */
885 drb &= 0xff;
886 drb |= (drb + (sz.side2 / 8)) << 8;
887 } else {
888#if 0
Stefan Reinauerfc01e5e2010-12-27 14:31:05 +0000889 PRINT_DEBUG("No DIMM found in slot %d\n", i);
Keith Hui59356ca2010-03-06 18:16:25 +0000890#endif
891
892 /* If there's no DIMM in the slot, set dra to 0x00. */
893 dra = 0x00;
Keith Hui59356ca2010-03-06 18:16:25 +0000894 /* Still have to propagate DRB over. */
895 drb &= 0xff;
896 drb |= (drb << 8);
897 }
898
899 pci_write_config16(NB, DRB + (2 * i), drb);
900#if 0
Stefan Reinauerfc01e5e2010-12-27 14:31:05 +0000901 PRINT_DEBUG("DRB has been set to 0x%04x\n", drb);
Keith Hui59356ca2010-03-06 18:16:25 +0000902#endif
903
904 /* Brings the upper DRB back down to be base for
905 * DRB calculations for the next two rows.
906 */
907 drb >>= 8;
908
909 rps |= (dra & 0x0f) << (i * 4);
Keith Hui59356ca2010-03-06 18:16:25 +0000910 }
911
912 /* Set paging policy register. */
913 pci_write_config8(NB, PGPOL + 1, bpr);
Keith Hui09f5a742010-12-23 17:12:03 +0000914 PRINT_DEBUG("PGPOL[BPR] has been set to 0x%02x\n", bpr);
Keith Hui59356ca2010-03-06 18:16:25 +0000915
916 /* Set DRAM row page size register. */
917 pci_write_config16(NB, RPS, rps);
Keith Hui09f5a742010-12-23 17:12:03 +0000918 PRINT_DEBUG("RPS has been set to 0x%04x\n", rps);
Keith Hui59356ca2010-03-06 18:16:25 +0000919
920 /* ### ECC */
921 pci_write_config8(NB, NBXCFG + 3, nbxecc);
Keith Hui09f5a742010-12-23 17:12:03 +0000922 PRINT_DEBUG("NBXECC[31:24] has been set to 0x%02x\n", nbxecc);
Keith Hui59356ca2010-03-06 18:16:25 +0000923
Keith Huie089a3f2011-08-02 22:28:14 -0400924 /* Set DRAMC[4:3] to proper memory type (EDO/SDRAM/Registered SDRAM). */
Keith Hui59356ca2010-03-06 18:16:25 +0000925
Keith Huie089a3f2011-08-02 22:28:14 -0400926 /* i will be used to set DRAMC[4:3]. */
927 if (regsd && sd) {
928 i = 0x10; // Registered SDRAM
929 } else if (sd) {
930 i = 0x08; // SDRAM
931 } else {
932 i = 0; // EDO
933 }
934
Keith Hui59356ca2010-03-06 18:16:25 +0000935 value = pci_read_config8(NB, DRAMC) & 0xe7;
Keith Huie089a3f2011-08-02 22:28:14 -0400936 value |= i;
Keith Hui59356ca2010-03-06 18:16:25 +0000937 pci_write_config8(NB, DRAMC, value);
Keith Hui09f5a742010-12-23 17:12:03 +0000938 PRINT_DEBUG("DRAMC has been set to 0x%02x\n", value);
Keith Hui59356ca2010-03-06 18:16:25 +0000939}
940
Uwe Hermann115c5b92010-10-09 17:00:18 +0000941void sdram_set_spd_registers(void)
Richard Smithcb8eab42006-07-24 04:25:47 +0000942{
Keith Hui59356ca2010-03-06 18:16:25 +0000943 /* Setup DRAM row boundary registers and other attributes. */
944 set_dram_row_attributes();
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000945
Keith Huidf35cdc2010-09-20 23:41:37 +0000946 /* Setup DRAM buffer strength. */
Keith Hui59356ca2010-03-06 18:16:25 +0000947 set_dram_buffer_strength();
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000948
949 /* TODO: Set PMCR? */
Uwe Hermann1683cef2008-11-27 00:47:07 +0000950 // pci_write_config8(NB, PMCR, 0x14);
951 pci_write_config8(NB, PMCR, 0x10);
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000952
Keith Huidf35cdc2010-09-20 23:41:37 +0000953 /* TODO: This is for EDO memory only. */
Uwe Hermann1683cef2008-11-27 00:47:07 +0000954 pci_write_config8(NB, DRAMT, 0x03);
Richard Smithcb8eab42006-07-24 04:25:47 +0000955}
956
Uwe Hermann115c5b92010-10-09 17:00:18 +0000957void sdram_enable(void)
Richard Smithcb8eab42006-07-24 04:25:47 +0000958{
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000959 int i;
Richard Smithcb8eab42006-07-24 04:25:47 +0000960
Uwe Hermann861f9642007-05-28 14:37:06 +0000961 /* 0. Wait until power/voltages and clocks are stable (200us). */
962 udelay(200);
Richard Smithcb8eab42006-07-24 04:25:47 +0000963
Uwe Hermann861f9642007-05-28 14:37:06 +0000964 /* 1. Apply NOP. Wait 200 clock cycles (200us should do). */
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000965 PRINT_DEBUG("RAM Enable 1: Apply NOP\n");
Uwe Hermann8b643cea2008-12-09 16:36:12 +0000966 do_ram_command(RAM_COMMAND_NOP);
Uwe Hermann861f9642007-05-28 14:37:06 +0000967 udelay(200);
Richard Smithcb8eab42006-07-24 04:25:47 +0000968
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000969 /* 2. Precharge all. Wait tRP. */
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000970 PRINT_DEBUG("RAM Enable 2: Precharge all\n");
Uwe Hermann8b643cea2008-12-09 16:36:12 +0000971 do_ram_command(RAM_COMMAND_PRECHARGE);
Uwe Hermann861f9642007-05-28 14:37:06 +0000972 udelay(1);
Richard Smithcb8eab42006-07-24 04:25:47 +0000973
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000974 /* 3. Perform 8 refresh cycles. Wait tRC each time. */
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000975 PRINT_DEBUG("RAM Enable 3: CBR\n");
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000976 for (i = 0; i < 8; i++) {
Uwe Hermann8b643cea2008-12-09 16:36:12 +0000977 do_ram_command(RAM_COMMAND_CBR);
Uwe Hermann861f9642007-05-28 14:37:06 +0000978 udelay(1);
Richard Smithcb8eab42006-07-24 04:25:47 +0000979 }
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000980
981 /* 4. Mode register set. Wait two memory cycles. */
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000982 PRINT_DEBUG("RAM Enable 4: Mode register set\n");
Uwe Hermann8b643cea2008-12-09 16:36:12 +0000983 do_ram_command(RAM_COMMAND_MRS);
Uwe Hermann861f9642007-05-28 14:37:06 +0000984 udelay(2);
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000985
986 /* 5. Normal operation. */
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000987 PRINT_DEBUG("RAM Enable 5: Normal operation\n");
Uwe Hermann8b643cea2008-12-09 16:36:12 +0000988 do_ram_command(RAM_COMMAND_NORMAL);
Uwe Hermann861f9642007-05-28 14:37:06 +0000989 udelay(1);
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000990
991 /* 6. Finally enable refresh. */
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000992 PRINT_DEBUG("RAM Enable 6: Enable refresh\n");
Uwe Hermann1683cef2008-11-27 00:47:07 +0000993 // pci_write_config8(NB, PMCR, 0x10);
994 spd_enable_refresh();
Uwe Hermann861f9642007-05-28 14:37:06 +0000995 udelay(1);
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000996
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000997 PRINT_DEBUG("Northbridge following SDRAM init:\n");
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000998 DUMPNORTH();
Richard Smithcb8eab42006-07-24 04:25:47 +0000999}