blob: 565719ded3b754d7cc97ac9ae88a05ef6ae6c51a [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 Hui9aa45e62017-07-20 21:00:56 -04005 * Copyright (C) 2010,2017 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
Keith Hui9aa45e62017-07-20 21:00:56 -040028/*
29 * Macros and definitions
30 */
Keith Huidf35cdc2010-09-20 23:41:37 +000031
Uwe Hermann1a9c8922007-04-01 17:24:03 +000032/* Debugging macros. */
Martin Roth33232602017-06-24 14:48:50 -060033#if IS_ENABLED(CONFIG_DEBUG_RAM_SETUP)
Keith Hui09f5a742010-12-23 17:12:03 +000034#define PRINT_DEBUG(x...) printk(BIOS_DEBUG, x)
Keith Huidf35cdc2010-09-20 23:41:37 +000035#define DUMPNORTH() dump_pci_device(NB)
Richard Smithcb8eab42006-07-24 04:25:47 +000036#else
Keith Hui09f5a742010-12-23 17:12:03 +000037#define PRINT_DEBUG(x...)
Uwe Hermann1a9c8922007-04-01 17:24:03 +000038#define DUMPNORTH()
Richard Smithcb8eab42006-07-24 04:25:47 +000039#endif
40
Uwe Hermann1a9c8922007-04-01 17:24:03 +000041/* SDRAMC[7:5] - SDRAM Mode Select (SMS). */
42#define RAM_COMMAND_NORMAL 0x0
43#define RAM_COMMAND_NOP 0x1
44#define RAM_COMMAND_PRECHARGE 0x2
45#define RAM_COMMAND_MRS 0x3
46#define RAM_COMMAND_CBR 0x4
Richard Smithcb8eab42006-07-24 04:25:47 +000047
Uwe Hermann1a9c8922007-04-01 17:24:03 +000048/* Map the JEDEC SPD refresh rates (array index) to 440BX refresh rates as
49 * defined in DRAMC[2:0].
50 *
51 * [0] == Normal 15.625 us -> 15.6 us
52 * [1] == Reduced(.25X) 3.9 us -> 7.8 ns
53 * [2] == Reduced(.5X) 7.8 us -> 7.8 us
54 * [3] == Extended(2x) 31.3 us -> 31.2 us
55 * [4] == Extended(4x) 62.5 us -> 62.4 us
56 * [5] == Extended(8x) 125 us -> 124.8 us
57 */
58static const uint32_t refresh_rate_map[] = {
59 1, 5, 5, 2, 3, 4
60};
Richard Smithcb8eab42006-07-24 04:25:47 +000061
Uwe Hermann1a9c8922007-04-01 17:24:03 +000062/* Table format: register, bitmask, value. */
Keith Huidf35cdc2010-09-20 23:41:37 +000063static const u8 register_values[] = {
Uwe Hermann1a9c8922007-04-01 17:24:03 +000064 /* NBXCFG - NBX Configuration Register
Uwe Hermannf5a6fd22007-05-27 23:31:31 +000065 * 0x50 - 0x53
Uwe Hermann1a9c8922007-04-01 17:24:03 +000066 *
67 * [31:24] SDRAM Row Without ECC
68 * 0 = ECC components are populated in this row
69 * 1 = ECC components are not populated in this row
70 * [23:19] Reserved
71 * [18:18] Host Bus Fast Data Ready Enable (HBFDRE)
72 * Assertion of DRAM data on host bus occurs...
73 * 0 = ...one clock after sampling snoop results (default)
74 * 1 = ...on the same clock the snoop result is being sampled
75 * (this mode is faster by one clock cycle)
76 * [17:17] ECC - EDO static Drive mode
77 * 0 = Normal mode (default)
78 * 1 = ECC signals are always driven
79 * [16:16] IDSEL_REDIRECT
80 * 0 = IDSEL1 is allocated to this bridge (default)
81 * 1 = IDSEL7 is allocated to this bridge
82 * [15:15] WSC# Handshake Disable
83 * 1 = Uni-processor mode
84 * 0 = Dual-processor mode with external IOAPIC (default)
85 * [14:14] Intel Reserved
86 * [13:12] Host/DRAM Frequency
87 * 00 = 100 MHz
88 * 01 = Reserved
89 * 10 = 66 MHz
90 * 11 = Reserved
91 * [11:11] AGP to PCI Access Enable
92 * 1 = Enable
93 * 0 = Disable
94 * [10:10] PCI Agent to Aperture Access Disable
95 * 1 = Disable
96 * 0 = Enable (default)
97 * [09:09] Aperture Access Global Enable
98 * 1 = Enable
99 * 0 = Disable
100 * [08:07] DRAM Data Integrity Mode (DDIM)
101 * 00 = Non-ECC
102 * 01 = EC-only
103 * 10 = ECC Mode
104 * 11 = ECC Mode with hardware scrubbing enabled
105 * [06:06] ECC Diagnostic Mode Enable (EDME)
106 * 1 = Enable
107 * 0 = Normal operation mode (default)
108 * [05:05] MDA Present (MDAP)
109 * Works in conjunction with the VGA_EN bit.
110 * VGA_EN MDAP
111 * 0 x All VGA cycles are sent to PCI
112 * 1 0 All VGA cycles are sent to AGP
113 * 1 1 All VGA cycles are sent to AGP, except for
114 * cycles in the MDA range.
115 * [04:04] Reserved
116 * [03:03] USWC Write Post During I/O Bridge Access Enable (UWPIO)
117 * 1 = Enable
118 * 0 = Disable
119 * [02:02] In-Order Queue Depth (IOQD)
120 * 1 = In-order queue = maximum
121 * 0 = A7# is sampled asserted (i.e., 0)
122 * [01:00] Reserved
Richard Smithcb8eab42006-07-24 04:25:47 +0000123 */
Uwe Hermannbc3594732007-06-07 22:16:30 +0000124 NBXCFG + 0, 0x00, 0x0c,
Keith Huidf35cdc2010-09-20 23:41:37 +0000125 // TODO: Bit 15 should be 0 for multiprocessor boards
Uwe Hermannbc3594732007-06-07 22:16:30 +0000126 NBXCFG + 1, 0x00, 0x80,
127 NBXCFG + 2, 0x00, 0x00,
128 NBXCFG + 3, 0x00, 0xff,
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000129
130 /* DRAMC - DRAM Control Register
131 * 0x57
132 *
133 * [7:6] Reserved
134 * [5:5] Module Mode Configuration (MMCONFIG)
Keith Huidf35cdc2010-09-20 23:41:37 +0000135 * The combination of SDRAMPWR and this bit (which is set by an
136 * external strapping option) determine how CKE works.
137 * SDRAMPWR MMCONFIG
138 * 0 0 = 3 DIMM, CKE0[5:0] driven
139 * X 1 = 3 DIMM, CKE0 only
140 * 1 0 = 4 DIMM, GCKE only
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000141 * [4:3] DRAM Type (DT)
142 * 00 = EDO
143 * 01 = SDRAM
144 * 10 = Registered SDRAM
145 * 11 = Reserved
146 * Note: EDO, SDRAM and Registered SDRAM cannot be mixed.
147 * [2:0] DRAM Refresh Rate (DRR)
148 * 000 = Refresh disabled
149 * 001 = 15.6 us
150 * 010 = 31.2 us
151 * 011 = 62.4 us
152 * 100 = 124.8 us
153 * 101 = 249.6 us
154 * 110 = Reserved
155 * 111 = Reserved
Richard Smithcb8eab42006-07-24 04:25:47 +0000156 */
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000157 /* Choose SDRAM (not registered), and disable refresh for now. */
Uwe Hermannbc3594732007-06-07 22:16:30 +0000158 DRAMC, 0x00, 0x08,
Richard Smithcb8eab42006-07-24 04:25:47 +0000159
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000160 /*
161 * PAM[6:0] - Programmable Attribute Map Registers
Uwe Hermannf5a6fd22007-05-27 23:31:31 +0000162 * 0x59 - 0x5f
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000163 *
164 * 0x59 [3:0] Reserved
165 * 0x59 [5:4] 0xF0000 - 0xFFFFF BIOS area
166 * 0x5a [1:0] 0xC0000 - 0xC3FFF ISA add-on BIOS
167 * 0x5a [5:4] 0xC4000 - 0xC7FFF ISA add-on BIOS
168 * 0x5b [1:0] 0xC8000 - 0xCBFFF ISA add-on BIOS
169 * 0x5b [5:4] 0xCC000 - 0xCFFFF ISA add-on BIOS
170 * 0x5c [1:0] 0xD0000 - 0xD3FFF ISA add-on BIOS
171 * 0x5c [5:4] 0xD4000 - 0xD7FFF ISA add-on BIOS
172 * 0x5d [1:0] 0xD8000 - 0xDBFFF ISA add-on BIOS
173 * 0x5d [5:4] 0xDC000 - 0xDFFFF ISA add-on BIOS
Martin Roth128c1042016-11-18 09:29:03 -0700174 * 0x5e [1:0] 0xE0000 - 0xE3FFF BIOS extension
175 * 0x5e [5:4] 0xE4000 - 0xE7FFF BIOS extension
176 * 0x5f [1:0] 0xE8000 - 0xEBFFF BIOS extension
177 * 0x5f [5:4] 0xEC000 - 0xEFFFF BIOS extension
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000178 *
179 * Bit assignment:
180 * 00 = DRAM Disabled (all access goes to memory mapped I/O space)
181 * 01 = Read Only (Reads to DRAM, writes to memory mapped I/O space)
182 * 10 = Write Only (Writes to DRAM, reads to memory mapped I/O space)
183 * 11 = Read/Write (all access goes to DRAM)
184 */
Keith Hui59356ca2010-03-06 18:16:25 +0000185
186 /*
187 * Map all legacy regions to RAM (read/write). This is required if
188 * you want to use the RAM area from 768 KB - 1 MB. If the PAM
189 * registers are not set here appropriately, the RAM in that region
190 * will not be accessible, thus a RAM check of it will also fail.
191 *
192 * TODO: This was set in sdram_set_spd_registers().
193 * Test if it still works when set here.
194 */
195 PAM0, 0x00, 0x30,
196 PAM1, 0x00, 0x33,
197 PAM2, 0x00, 0x33,
198 PAM3, 0x00, 0x33,
199 PAM4, 0x00, 0x33,
200 PAM5, 0x00, 0x33,
201 PAM6, 0x00, 0x33,
Richard Smithcb8eab42006-07-24 04:25:47 +0000202
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000203 /* DRB[0:7] - DRAM Row Boundary Registers
204 * 0x60 - 0x67
205 *
206 * An array of 8 byte registers, which hold the ending memory address
Anders Jenbo0e1e8062010-04-27 06:35:31 +0000207 * assigned to each pair of DIMMs, in 8MB granularity.
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000208 *
209 * 0x60 DRB0 = Total memory in row0 (in 8 MB)
210 * 0x61 DRB1 = Total memory in row0+1 (in 8 MB)
211 * 0x62 DRB2 = Total memory in row0+1+2 (in 8 MB)
212 * 0x63 DRB3 = Total memory in row0+1+2+3 (in 8 MB)
213 * 0x64 DRB4 = Total memory in row0+1+2+3+4 (in 8 MB)
214 * 0x65 DRB5 = Total memory in row0+1+2+3+4+5 (in 8 MB)
215 * 0x66 DRB6 = Total memory in row0+1+2+3+4+5+6 (in 8 MB)
216 * 0x67 DRB7 = Total memory in row0+1+2+3+4+5+6+7 (in 8 MB)
217 */
Uwe Hermannf5a6fd22007-05-27 23:31:31 +0000218 /* Set the DRBs to zero for now, this will be fixed later. */
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000219 DRB0, 0x00, 0x00,
220 DRB1, 0x00, 0x00,
221 DRB2, 0x00, 0x00,
222 DRB3, 0x00, 0x00,
223 DRB4, 0x00, 0x00,
224 DRB5, 0x00, 0x00,
225 DRB6, 0x00, 0x00,
226 DRB7, 0x00, 0x00,
227
228 /* FDHC - Fixed DRAM Hole Control Register
229 * 0x68
230 *
231 * Controls two fixed DRAM holes: 512 KB - 640 KB and 15 MB - 16 MB.
232 *
233 * [7:6] Hole Enable (HEN)
234 * 00 = None
235 * 01 = 512 KB - 640 KB (128 KB)
236 * 10 = 15 MB - 16 MB (1 MB)
237 * 11 = Reserved
238 * [5:0] Reserved
239 */
240 /* No memory holes. */
241 FDHC, 0x00, 0x00,
242
243 /* RPS - SDRAM Row Page Size Register
244 * 0x74 - 0x75
245 *
246 * Sets the row page size for SDRAM. For EDO memory, the page
247 * size is fixed at 2 KB.
248 *
Keith Huidf35cdc2010-09-20 23:41:37 +0000249 * Bits[1:0] Page Size
250 * 00 2 KB
251 * 01 4 KB
252 * 10 8 KB
253 * 11 Reserved
Keith Huie089a3f2011-08-02 22:28:14 -0400254 *
Keith Huidf35cdc2010-09-20 23:41:37 +0000255 * RPS bits Corresponding DRB register
256 * [01:00] DRB[0], row 0
257 * [03:02] DRB[1], row 1
258 * [05:04] DRB[2], row 2
259 * [07:06] DRB[3], row 3
260 * [09:08] DRB[4], row 4
261 * [11:10] DRB[5], row 5
262 * [13:12] DRB[6], row 6
263 * [15:14] DRB[7], row 7
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000264 */
Keith Huidf35cdc2010-09-20 23:41:37 +0000265 /* Power on defaults to 2KB. Will be set later. */
266 // RPS + 0, 0x00, 0x00,
267 // RPS + 1, 0x00, 0x00,
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000268
269 /* SDRAMC - SDRAM Control Register
Uwe Hermann7ea18cf2007-05-04 00:51:17 +0000270 * 0x76 - 0x77
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000271 *
272 * [15:10] Reserved
273 * [09:08] Idle/Pipeline DRAM Leadoff Timing (IPDLT)
274 * 00 = Illegal
275 * 01 = Add a clock delay to the lead-off clock count
Keith Huidf35cdc2010-09-20 23:41:37 +0000276 * 1x = Illegal
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000277 * [07:05] SDRAM Mode Select (SMS)
278 * 000 = Normal SDRAM Operation (default)
279 * 001 = NOP Command Enable
280 * 010 = All Banks Precharge Enable
281 * 011 = Mode Register Set Enable
282 * 100 = CBR Enable
283 * 101 = Reserved
284 * 110 = Reserved
285 * 111 = Reserved
286 * [04:04] SDRAMPWR
287 * 0 = 3 DIMM configuration
288 * 1 = 4 DIMM configuration
289 * [03:03] Leadoff Command Timing (LCT)
290 * 0 = 4 CS# Clock
291 * 1 = 3 CS# Clock
292 * [02:02] CAS# Latency (CL)
293 * 0 = 3 DCLK CAS# latency
294 * 1 = 2 DCLK CAS# latency
295 * [01:01] SDRAM RAS# to CAS# Delay (SRCD)
296 * 0 = 3 clocks between a row activate and a read or write cmd.
297 * 1 = 2 clocks between a row activate and a read or write cmd.
298 * [00:00] SDRAM RAS# Precharge (SRP)
299 * 0 = 3 clocks of RAS# precharge
300 * 1 = 2 clocks of RAS# precharge
301 */
Martin Roth33232602017-06-24 14:48:50 -0600302#if IS_ENABLED(CONFIG_SDRAMPWR_4DIMM)
Keith Hui9c1e1f02010-03-13 20:16:48 +0000303 SDRAMC + 0, 0x00, 0x10, /* The board has 4 DIMM slots. */
304#else
Keith Huidf35cdc2010-09-20 23:41:37 +0000305 SDRAMC + 0, 0x00, 0x00, /* The board has 3 DIMM slots. */
Keith Hui9c1e1f02010-03-13 20:16:48 +0000306#endif
Mats Erik Andersson45db3662008-09-30 04:52:29 +0000307 SDRAMC + 1, 0x00, 0x00,
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000308
309 /* PGPOL - Paging Policy Register
310 * 0x78 - 0x79
311 *
312 * [15:08] Banks per Row (BPR)
Keith Huidf35cdc2010-09-20 23:41:37 +0000313 * Each bit in this field corresponds to one row of the memory
314 * array. Bit 15 corresponds to row 7 while bit 8 corresponds
315 * to row 0. Bits for empty rows are "don't care".
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000316 * 0 = 2 banks
317 * 1 = 4 banks
318 * [07:05] Reserved
319 * [04:04] Intel Reserved
320 * [03:00] DRAM Idle Timer (DIT)
321 * 0000 = 0 clocks
322 * 0001 = 2 clocks
323 * 0010 = 4 clocks
324 * 0011 = 8 clocks
325 * 0100 = 10 clocks
326 * 0101 = 12 clocks
327 * 0110 = 16 clocks
328 * 0111 = 32 clocks
329 * 1xxx = Infinite (pages are not closed for idle condition)
330 */
Uwe Hermannbc3594732007-06-07 22:16:30 +0000331 PGPOL + 0, 0x00, 0x00,
332 PGPOL + 1, 0x00, 0xff,
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000333
334 /* PMCR - Power Management Control Register
335 * 0x7a
336 *
337 * [07:07] Power Down SDRAM Enable (PDSE)
338 * 1 = Enable
339 * 0 = Disable
340 * [06:06] ACPI Control Register Enable (SCRE)
341 * 1 = Enable
342 * 0 = Disable (default)
343 * [05:05] Suspend Refresh Type (SRT)
344 * 1 = Self refresh mode
345 * 0 = CBR fresh mode
346 * [04:04] Normal Refresh Enable (NREF_EN)
347 * 1 = Enable
348 * 0 = Disable
349 * [03:03] Quick Start Mode (QSTART)
350 * 1 = Quick start mode for the processor is enabled
351 * [02:02] Gated Clock Enable (GCLKEN)
352 * 1 = Enable
353 * 0 = Disable
354 * [01:01] AGP Disable (AGP_DIS)
355 * 1 = Disable
356 * 0 = Enable
357 * [00:00] CPU reset without PCIRST enable (CRst_En)
358 * 1 = Enable
359 * 0 = Disable
360 */
361 /* Enable normal refresh and the gated clock. */
362 // TODO: Only do this later?
363 // PMCR, 0x00, 0x14,
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000364 PMCR, 0x00, 0x00,
Keith Hui59356ca2010-03-06 18:16:25 +0000365
366 /* Enable SCRR.SRRAEN and let BX choose the SRR. */
367 SCRR + 1, 0x00, 0x10,
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000368};
369
370/*-----------------------------------------------------------------------------
371SDRAM configuration functions.
372-----------------------------------------------------------------------------*/
373
374/**
375 * Send the specified RAM command to all DIMMs.
376 *
Uwe Hermann8b643cea2008-12-09 16:36:12 +0000377 * @param command The RAM command to send to the DIMM(s).
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000378 */
Uwe Hermann8b643cea2008-12-09 16:36:12 +0000379static void do_ram_command(u32 command)
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000380{
Uwe Hermann8b643cea2008-12-09 16:36:12 +0000381 int i, caslatency;
382 u8 dimm_start, dimm_end;
383 u16 reg16;
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -0800384 void *addr;
385 u32 addr_offset;
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000386
387 /* Configure the RAM command. */
Uwe Hermann8b643cea2008-12-09 16:36:12 +0000388 reg16 = pci_read_config16(NB, SDRAMC);
389 reg16 &= 0xff1f; /* Clear bits 7-5. */
390 reg16 |= (u16) (command << 5); /* Write command into bits 7-5. */
391 pci_write_config16(NB, SDRAMC, reg16);
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000392
Uwe Hermann8b643cea2008-12-09 16:36:12 +0000393 /*
394 * RAM_COMMAND_NORMAL affects only the memory controller and
395 * doesn't need to be "sent" to the DIMMs.
396 */
397 if (command == RAM_COMMAND_NORMAL)
398 return;
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000399
Uwe Hermann8b643cea2008-12-09 16:36:12 +0000400 /* Send the RAM command to each row of memory. */
401 dimm_start = 0;
402 for (i = 0; i < (DIMM_SOCKETS * 2); i++) {
Keith Hui59356ca2010-03-06 18:16:25 +0000403 addr_offset = 0;
404 caslatency = 3; /* TODO: Dynamically get CAS latency later. */
Uwe Hermann8b643cea2008-12-09 16:36:12 +0000405 if (command == RAM_COMMAND_MRS) {
406 /*
407 * MAA[12:11,9:0] must be inverted when sent to DIMM
408 * 2 or 3 (no inversion if sent to DIMM 0 or 1).
409 */
410 if ((i >= 0 && i <= 3) && caslatency == 3)
411 addr_offset = 0x1d0;
412 if ((i >= 4 && i <= 7) && caslatency == 3)
413 addr_offset = 0x1e28;
414 if ((i >= 0 && i <= 3) && caslatency == 2)
415 addr_offset = 0x150;
416 if ((i >= 4 && i <= 7) && caslatency == 2)
417 addr_offset = 0x1ea8;
418 }
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000419
Uwe Hermann8b643cea2008-12-09 16:36:12 +0000420 dimm_end = pci_read_config8(NB, DRB + i);
421
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -0800422 addr = (void *)((dimm_start * 8 * 1024 * 1024) + addr_offset);
Uwe Hermann8b643cea2008-12-09 16:36:12 +0000423 if (dimm_end > dimm_start) {
Uwe Hermann8b643cea2008-12-09 16:36:12 +0000424 read32(addr);
425 }
426
427 /* Set the start of the next DIMM. */
428 dimm_start = dimm_end;
429 }
Richard Smithcb8eab42006-07-24 04:25:47 +0000430}
431
Keith Hui59356ca2010-03-06 18:16:25 +0000432static void set_dram_buffer_strength(void)
433{
Keith Huib48ba662010-03-17 02:15:07 +0000434 /* To give some breathing room for romcc,
Anders Jenbo0e1e8062010-04-27 06:35:31 +0000435 * mbsc0 doubles as drb
Keith Huib48ba662010-03-17 02:15:07 +0000436 * mbsc1 doubles as drb1
437 * mbfs0 doubles as i and reg
Keith Hui59356ca2010-03-06 18:16:25 +0000438 */
Keith Huib48ba662010-03-17 02:15:07 +0000439 uint8_t mbsc0,mbsc1,mbsc3,mbsc4,mbfs0,mbfs2,fsb;
Keith Hui59356ca2010-03-06 18:16:25 +0000440
Anders Jenbo0e1e8062010-04-27 06:35:31 +0000441 /* Tally how many rows between rows 0-3 and rows 4-7 are populated.
Keith Huib48ba662010-03-17 02:15:07 +0000442 * This determines how to program MBFS and MBSC.
443 */
444 uint8_t dimm03 = 0;
445 uint8_t dimm47 = 0;
446
447 mbsc0 = 0;
448 for (mbfs0 = DRB0; mbfs0 <= DRB7; mbfs0++) {
449 mbsc1 = pci_read_config8(NB, mbfs0);
450 if (mbsc0 != mbsc1) {
451 if (mbfs0 <= DRB3) {
452 dimm03++;
453 } else {
454 dimm47++;
455 }
456 mbsc0 = mbsc1;
457 }
458 }
459
Keith Huidf35cdc2010-09-20 23:41:37 +0000460 /* Algorithm bitmap for programming MBSC[39:0] and MBFS[23:0].
Keith Huib48ba662010-03-17 02:15:07 +0000461 *
Keith Huidf35cdc2010-09-20 23:41:37 +0000462 * The 440BX datasheet says buffer frequency is independent from bus
463 * frequency and mismatch both ways are possible. This is how it is
464 * programmed in the ASUS P2B-LS mainboard.
Keith Huib48ba662010-03-17 02:15:07 +0000465 *
466 * There are four main conditions to check when programming DRAM buffer
467 * frequency and strength:
468 *
469 * a: >2 rows populated across DIMM0,1
470 * b: >2 rows populated across DIMM2,3
471 * c: >4 rows populated across all DIMM slots
472 * and either one of:
473 * 1: NBXCFG[13] strapped as 100MHz, or
474 * 6: NBXCFG[13] strapped as 66MHz
475 *
476 * CKE0/FENA ----------------------------------------------------------+
477 * CKE1/GCKE -------------------[ MBFS ]------------------------+|
478 * DQMA/CASA[764320]# ----------[ 0 = 66MHz ]-----------------------+||
479 * DQMB1/CASB1# ----------------[ 1 = 100MHz ]----------------------+|||
480 * DQMB5/CASB5# ---------------------------------------------------+||||
481 * DQMA1/CASA1# --------------------------------------------------+|||||
482 * DQMA5/CASA5# -------------------------------------------------+||||||
483 * CSA0-5#,CSB0-5# ----------------------------------------++++++|||||||
484 * CSA6#/CKE2# -------------------------------------------+|||||||||||||
485 * CSB6#/CKE4# ------------------------------------------+||||||||||||||
486 * CSA7#/CKE3# -----------------------------------------+|||||||||||||||
487 * CSB7#/CKE5# ----------------------------------------+||||||||||||||||
488 * MECC[7:0] #2/#1 (100MHz) -------------------------++|||||||||||||||||
489 * MD[63:0] #2/#1 (100MHz) ------------------------++|||||||||||||||||||
490 * MAB[12:11,9:0]#,MAB[13,10],WEB#,SRASB#,SCASB# -+|||||||||||||||||||||
491 * MAA[13:0],WEA#,SRASA#,SCASA# -----------------+||||||||||||||||||||||
492 * Reserved ------------------------------------+|||||||||||||||||||||||
493 * ||||||||||||||||||||||||
494 * 3 32 21 10 0 * 2 21 10 0
495 * 9876543210987654321098765432109876543210 * 321098765432109876543210
496 * a 10------------------------1010---------- * -1---------------11----- a
497 *!a 11------------------------1111---------- * -0---------------00----- !a
498 * b --10--------------------------1010------ * --1----------------11--- b
499 *!b --11--------------------------1111------ * --0----------------00--- !b
500 * c ----------------------------------1100-- * ----------------------1- c
501 *!c ----------------------------------1011-- * ----------------------0- !c
502 * 1 ----1010101000000000000000------------00 * ---11111111111111----1-0 1
503 * 6 ----000000000000000000000010101010----00 * ---1111111111111100000-0 6
504 * | | | | | | | | | | ||||||| | | | | | |
505 * | | | | | | | | | | ||||||| | | | | | +- CKE0/FENA
506 * | | | | | | | | | | ||||||| | | | | +--- CKE1/GCKE
507 * | | | | | | | | | | ||||||| | | | +----- DQMA/CASA[764320]#
508 * | | | | | | | | | | ||||||| | | +------- DQMB1/CASB1#
509 * | | | | | | | | | | ||||||| | +--------- DQMB5/CASB5#
510 * | | | | | | | | | | ||||||| +----------- DQMA1/CASA1#
511 * | | | | | | | | | | ||||||+------------- DQMA5/CASA5#
512 * | | | | | | | | | | ++++++-------------- CSA0-5#,CSB0-5# [ 0=1x;1=2x ]
513 * | | | | | | | | | +--------------------- CSA6#/CKE2#
514 * | | | | | | | | +---[ MBSC ]------ CSB6#/CKE4#
515 * | | | | | | | +-----[ 00 = 1x ]------ CSA7#/CKE3#
516 * | | | | | | +-------[ 01 invalid ]------ CSB7#/CKE5#
517 * | | | | | +---------[ 10 = 2x ]------ MECC[7:0] #1 (2x)
518 * | | | | +-----------[ 11 = 3x ]------ MECC[7:0] #2 (2x)
519 * | | | +--------------------------------- MD[63:0] #1 (2x)
520 * | | +----------------------------------- MD[63:0] #2 (2x)
521 * | +------------------------------------- MAB[12:11,9:0]#,MAB[13,10],WEB#,SRASB#,SCASB#
522 * +--------------------------------------- MAA[13:0],WEA#,SRASA#,SCASA#
523 * MBSC[47:40] and MBFS[23] are reserved.
524 *
Keith Huidf35cdc2010-09-20 23:41:37 +0000525 * This algorithm is checked against the ASUS P2B-LS (which has
526 * 4 DIMM slots) factory BIOS.
Keith Huib48ba662010-03-17 02:15:07 +0000527 * Therefore it assumes a board with 4 slots, and will need testing
528 * on boards with 3 DIMM slots.
529 */
Anders Jenbo0e1e8062010-04-27 06:35:31 +0000530
Keith Huib48ba662010-03-17 02:15:07 +0000531 mbsc0 = 0x80;
532 mbsc1 = 0x2a;
533 mbfs2 = 0x1f;
534 if (pci_read_config8(NB, NBXCFG + 1) & 0x30) {
535 fsb = 66;
536 mbsc3 = 0x00;
537 mbsc4 = 0x00;
538 mbfs0 = 0x80;
539 } else {
540 fsb = 100;
541 mbsc3 = 0xa0;
542 mbsc4 = 0x0a;
543 mbfs0 = 0x84;
544 }
Anders Jenbo0e1e8062010-04-27 06:35:31 +0000545
546 if (dimm03 > 2) {
547 mbsc4 = mbsc4 | 0x80;
Keith Huib48ba662010-03-17 02:15:07 +0000548 mbsc1 = mbsc1 | 0x28;
549 mbfs2 = mbfs2 | 0x40;
550 mbfs0 = mbfs0 | 0x60;
Anders Jenbo0e1e8062010-04-27 06:35:31 +0000551 } else {
552 mbsc4 = mbsc4 | 0xc0;
Keith Huib48ba662010-03-17 02:15:07 +0000553 if (fsb == 100) {
554 mbsc1 = mbsc1 | 0x3c;
555 }
Anders Jenbo0e1e8062010-04-27 06:35:31 +0000556 }
557 if (dimm47 > 2) {
558 mbsc4 = mbsc4 | 0x20;
559 mbsc1 = mbsc1 | 0x02;
Keith Huib48ba662010-03-17 02:15:07 +0000560 mbsc0 = mbsc0 | 0x80;
561 mbfs2 = mbfs2 | 0x20;
562 mbfs0 = mbfs0 | 0x18;
Anders Jenbo0e1e8062010-04-27 06:35:31 +0000563 } else {
Keith Huib48ba662010-03-17 02:15:07 +0000564 mbsc4 = mbsc4 | 0x30;
565 if (fsb == 100) {
Anders Jenbo0e1e8062010-04-27 06:35:31 +0000566 mbsc1 = mbsc1 | 0x03;
Keith Huib48ba662010-03-17 02:15:07 +0000567 mbsc0 = mbsc0 | 0xc0;
568 }
569 }
Anders Jenbo0e1e8062010-04-27 06:35:31 +0000570 if ((dimm03 + dimm47) > 4) {
Keith Huib48ba662010-03-17 02:15:07 +0000571 mbsc0 = mbsc0 | 0x30;
572 mbfs0 = mbfs0 | 0x02;
Anders Jenbo0e1e8062010-04-27 06:35:31 +0000573 } else {
574 mbsc0 = mbsc0 | 0x2c;
Keith Huib48ba662010-03-17 02:15:07 +0000575 }
576
577 pci_write_config8(NB, MBSC + 0, mbsc0);
578 pci_write_config8(NB, MBSC + 1, mbsc1);
579 pci_write_config8(NB, MBSC + 2, 0x00);
580 pci_write_config8(NB, MBSC + 3, mbsc3);
581 pci_write_config8(NB, MBSC + 4, mbsc4);
582 pci_write_config8(NB, MBFS + 0, mbfs0);
583 pci_write_config8(NB, MBFS + 1, 0xff);
584 pci_write_config8(NB, MBFS + 2, mbfs2);
Keith Hui59356ca2010-03-06 18:16:25 +0000585}
586
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000587/*-----------------------------------------------------------------------------
Martin Roth128c1042016-11-18 09:29:03 -0700588DIMM-independent configuration functions.
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000589-----------------------------------------------------------------------------*/
Richard Smithcb8eab42006-07-24 04:25:47 +0000590
Uwe Hermann1683cef2008-11-27 00:47:07 +0000591static void spd_enable_refresh(void)
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000592{
593 int i, value;
594 uint8_t reg;
595
Uwe Hermann1683cef2008-11-27 00:47:07 +0000596 reg = pci_read_config8(NB, DRAMC);
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000597
598 for (i = 0; i < DIMM_SOCKETS; i++) {
Uwe Hermannd773fd32010-11-20 20:23:08 +0000599 value = spd_read_byte(DIMM0 + i, SPD_REFRESH);
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000600 if (value < 0)
601 continue;
602 reg = (reg & 0xf8) | refresh_rate_map[(value & 0x7f)];
603
Keith Hui09f5a742010-12-23 17:12:03 +0000604 PRINT_DEBUG(" Enabling refresh (DRAMC = 0x%02x) for DIMM %02x\n", reg, i);
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000605 }
606
Uwe Hermann1683cef2008-11-27 00:47:07 +0000607 pci_write_config8(NB, DRAMC, reg);
Richard Smithcb8eab42006-07-24 04:25:47 +0000608}
609
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000610/*-----------------------------------------------------------------------------
611Public interface.
612-----------------------------------------------------------------------------*/
613
Uwe Hermann115c5b92010-10-09 17:00:18 +0000614void sdram_set_registers(void)
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000615{
616 int i, max;
Uwe Hermannbc3594732007-06-07 22:16:30 +0000617 uint8_t reg;
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000618
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000619 PRINT_DEBUG("Northbridge prior to SDRAM init:\n");
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000620 DUMPNORTH();
621
Carl-Daniel Hailfinger2ee67792008-10-01 12:52:52 +0000622 max = ARRAY_SIZE(register_values);
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000623
Uwe Hermannf5a6fd22007-05-27 23:31:31 +0000624 /* Set registers as specified in the register_values[] array. */
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000625 for (i = 0; i < max; i += 3) {
Uwe Hermann1683cef2008-11-27 00:47:07 +0000626 reg = pci_read_config8(NB, register_values[i]);
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000627 reg &= register_values[i + 1];
628 reg |= register_values[i + 2] & ~(register_values[i + 1]);
Uwe Hermann1683cef2008-11-27 00:47:07 +0000629 pci_write_config8(NB, register_values[i], reg);
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000630 }
631}
632
Keith Hui59356ca2010-03-06 18:16:25 +0000633struct dimm_size {
Keith Hui09f5a742010-12-23 17:12:03 +0000634 u32 side1;
635 u32 side2;
Keith Hui59356ca2010-03-06 18:16:25 +0000636};
637
638static struct dimm_size spd_get_dimm_size(unsigned int device)
639{
640 struct dimm_size sz;
641 int i, module_density, dimm_banks;
642 sz.side1 = 0;
643 module_density = spd_read_byte(device, SPD_DENSITY_OF_EACH_ROW_ON_MODULE);
644 dimm_banks = spd_read_byte(device, SPD_NUM_DIMM_BANKS);
645
646 /* Find the size of side1. */
647 /* Find the larger value. The larger value is always side1. */
648 for (i = 512; i >= 0; i >>= 1) {
649 if ((module_density & i) == i) {
650 sz.side1 = i;
651 break;
652 }
653 }
654
655 /* Set to 0 in case it's single sided. */
656 sz.side2 = 0;
657
658 /* Test if it's a dual-sided DIMM. */
659 if (dimm_banks > 1) {
660 /* Test if there's a second value. If so it's asymmetrical. */
661 if (module_density != i) {
662 /*
663 * Find second value, picking up where we left off.
664 * i >>= 1 done initially to make sure we don't get
665 * the same value again.
666 */
667 for (i >>= 1; i >= 0; i >>= 1) {
668 if (module_density == (sz.side1 | i)) {
669 sz.side2 = i;
670 break;
671 }
672 }
673 /* If not, it's symmetrical. */
674 } else {
675 sz.side2 = sz.side1;
676 }
677 }
678
679 /*
680 * SPD byte 31 is the memory size divided by 4 so we
Martin Roth128c1042016-11-18 09:29:03 -0700681 * need to multiply by 4 to get the total size.
Keith Hui59356ca2010-03-06 18:16:25 +0000682 */
683 sz.side1 *= 4;
684 sz.side2 *= 4;
685
Anders Jenbo771b0e42010-04-27 08:45:30 +0000686 /* It is possible to partially use larger then supported
687 * modules by setting them to a supported size.
688 */
Elyes HAOUAS12df9502016-08-23 21:29:48 +0200689 if (sz.side1 > 128) {
Keith Hui09f5a742010-12-23 17:12:03 +0000690 PRINT_DEBUG("Side1 was %dMB but only 128MB will be used.\n",
691 sz.side1);
Anders Jenbo771b0e42010-04-27 08:45:30 +0000692 sz.side1 = 128;
693
Elyes HAOUAS12df9502016-08-23 21:29:48 +0200694 if (sz.side2 > 128) {
Keith Hui09f5a742010-12-23 17:12:03 +0000695 PRINT_DEBUG("Side2 was %dMB but only 128MB will be used.\n",
696 sz.side2);
Anders Jenbo771b0e42010-04-27 08:45:30 +0000697 sz.side2 = 128;
698 }
699 }
700
Keith Hui59356ca2010-03-06 18:16:25 +0000701 return sz;
702}
703/*
704 * Sets DRAM attributes one DIMM at a time, based on SPD data.
705 * Northbridge settings that are set: NBXCFG[31:24], DRB0-DRB7, RPS, DRAMC.
706 */
707static void set_dram_row_attributes(void)
708{
Keith Huie089a3f2011-08-02 22:28:14 -0400709 int i, dra, drb, col, width, value, rps;
Keith Hui59356ca2010-03-06 18:16:25 +0000710 u8 bpr; /* Top 8 bits of PGPOL */
Keith Huie089a3f2011-08-02 22:28:14 -0400711 u8 nbxecc = 0; /* NBXCFG[31:24] */
712 u8 edo, sd, regsd; /* EDO, SDRAM, registered SDRAM */
Keith Hui59356ca2010-03-06 18:16:25 +0000713
Keith Huie089a3f2011-08-02 22:28:14 -0400714 edo = 0;
715 sd = 0;
716 regsd = 1;
Keith Hui59356ca2010-03-06 18:16:25 +0000717 rps = 0;
718 drb = 0;
719 bpr = 0;
Keith Hui59356ca2010-03-06 18:16:25 +0000720
721 for (i = 0; i < DIMM_SOCKETS; i++) {
722 unsigned int device;
Uwe Hermannd773fd32010-11-20 20:23:08 +0000723 device = DIMM0 + i;
Keith Hui59356ca2010-03-06 18:16:25 +0000724 bpr >>= 2;
Keith Huie089a3f2011-08-02 22:28:14 -0400725 nbxecc >>= 2;
Keith Hui59356ca2010-03-06 18:16:25 +0000726
727 /* First check if a DIMM is actually present. */
728 value = spd_read_byte(device, SPD_MEMORY_TYPE);
729 /* This is 440BX! We do EDO too! */
730 if (value == SPD_MEMORY_TYPE_EDO
731 || value == SPD_MEMORY_TYPE_SDRAM) {
732
Keith Hui59356ca2010-03-06 18:16:25 +0000733 if (value == SPD_MEMORY_TYPE_EDO) {
Keith Huie089a3f2011-08-02 22:28:14 -0400734 edo = 1;
Anders Jenbo0e1e8062010-04-27 06:35:31 +0000735 } else if (value == SPD_MEMORY_TYPE_SDRAM) {
Keith Huie089a3f2011-08-02 22:28:14 -0400736 sd = 1;
Keith Hui59356ca2010-03-06 18:16:25 +0000737 }
Keith Hui09f5a742010-12-23 17:12:03 +0000738 PRINT_DEBUG("Found DIMM in slot %d\n", i);
Keith Hui59356ca2010-03-06 18:16:25 +0000739
Keith Huie089a3f2011-08-02 22:28:14 -0400740 if (edo && sd) {
Stefan Reinauer65b72ab2015-01-05 12:59:54 -0800741 printk(BIOS_ERR, "Mixing EDO/SDRAM unsupported!\n");
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000742 die("HALT\n");
Keith Hui59356ca2010-03-06 18:16:25 +0000743 }
744
745 /* "DRA" is our RPS for the two rows on this DIMM. */
746 dra = 0;
747
748 /* Columns */
749 col = spd_read_byte(device, SPD_NUM_COLUMNS);
750
751 /*
752 * Is this an ECC DIMM? Actually will be a 2 if so.
753 * TODO: Other register than NBXCFG also needs this
754 * ECC information.
755 */
Keith Huie089a3f2011-08-02 22:28:14 -0400756 value = spd_read_byte(device, SPD_DIMM_CONFIG_TYPE);
Keith Hui59356ca2010-03-06 18:16:25 +0000757
758 /* Data width */
759 width = spd_read_byte(device, SPD_MODULE_DATA_WIDTH_LSB);
Anders Jenbo0e1e8062010-04-27 06:35:31 +0000760
Keith Hui59356ca2010-03-06 18:16:25 +0000761 /* Exclude error checking data width from page size calculations */
Keith Huie089a3f2011-08-02 22:28:14 -0400762 if (value) {
Keith Hui59356ca2010-03-06 18:16:25 +0000763 value = spd_read_byte(device,
764 SPD_ERROR_CHECKING_SDRAM_WIDTH);
765 width -= value;
766 /* ### ECC */
767 /* Clear top 2 bits to help set up NBXCFG. */
Keith Huie089a3f2011-08-02 22:28:14 -0400768 nbxecc &= 0x3f;
Keith Hui59356ca2010-03-06 18:16:25 +0000769 } else {
770 /* Without ECC, top 2 bits should be 11. */
Keith Huie089a3f2011-08-02 22:28:14 -0400771 nbxecc |= 0xc0;
Keith Hui59356ca2010-03-06 18:16:25 +0000772 }
773
Keith Huie089a3f2011-08-02 22:28:14 -0400774 /* If any installed DIMM is *not* registered, this system cannot be
775 * configured for registered SDRAM.
776 * By registered, only the address and control lines need to be, which
777 * we can tell by reading SPD byte 21, bit 1.
778 */
779 value = spd_read_byte(device, SPD_MODULE_ATTRIBUTES);
780
781 PRINT_DEBUG("DIMM is ");
782 if ((value & MODULE_REGISTERED) == 0) {
783 regsd = 0;
784 PRINT_DEBUG("not ");
785 }
786 PRINT_DEBUG("registered\n");
787
Keith Hui59356ca2010-03-06 18:16:25 +0000788 /* Calculate page size in bits. */
789 value = ((1 << col) * width);
790
791 /* Convert to KB. */
792 dra = (value >> 13);
793
794 /* Number of banks of DIMM (single or double sided). */
795 value = spd_read_byte(device, SPD_NUM_DIMM_BANKS);
796
797 /* Once we have dra, col is done and can be reused.
798 * So it's reused for number of banks.
799 */
800 col = spd_read_byte(device, SPD_NUM_BANKS_PER_SDRAM);
801
802 if (value == 1) {
803 /*
804 * Second bank of 1-bank DIMMs "doesn't have
805 * ECC" - or anything.
806 */
Keith Hui59356ca2010-03-06 18:16:25 +0000807 if (dra == 2) {
808 dra = 0x0; /* 2KB */
809 } else if (dra == 4) {
810 dra = 0x1; /* 4KB */
811 } else if (dra == 8) {
812 dra = 0x2; /* 8KB */
Anders Jenbo771b0e42010-04-27 08:45:30 +0000813 } else if (dra >= 16) {
814 /* Page sizes larger than supported are
815 * set to 8KB to use module partially.
816 */
817 PRINT_DEBUG("Page size forced to 8KB.\n");
818 dra = 0x2; /* 8KB */
Keith Hui59356ca2010-03-06 18:16:25 +0000819 } else {
820 dra = -1;
821 }
822 /*
823 * Sets a flag in PGPOL[BPR] if this DIMM has
824 * 4 banks per row.
825 */
826 if (col == 4)
827 bpr |= 0x40;
828 } else if (value == 2) {
829 if (dra == 2) {
830 dra = 0x0; /* 2KB */
831 } else if (dra == 4) {
832 dra = 0x05; /* 4KB */
833 } else if (dra == 8) {
834 dra = 0x0a; /* 8KB */
Anders Jenbo771b0e42010-04-27 08:45:30 +0000835 } else if (dra >= 16) {
836 /* Ditto */
837 PRINT_DEBUG("Page size forced to 8KB.\n");
838 dra = 0x0a; /* 8KB */
Keith Hui59356ca2010-03-06 18:16:25 +0000839 } else {
840 dra = -1;
841 }
842 /* Ditto */
843 if (col == 4)
844 bpr |= 0xc0;
845 } else {
Stefan Reinauer65b72ab2015-01-05 12:59:54 -0800846 printk(BIOS_ERR, "# of banks of DIMM unsupported!\n");
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000847 die("HALT\n");
Keith Hui59356ca2010-03-06 18:16:25 +0000848 }
849 if (dra == -1) {
Stefan Reinauer65b72ab2015-01-05 12:59:54 -0800850 printk(BIOS_ERR, "Page size not supported\n");
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000851 die("HALT\n");
Keith Hui59356ca2010-03-06 18:16:25 +0000852 }
853
854 /*
855 * 440BX supports asymmetrical dual-sided DIMMs,
856 * but can't handle DIMMs smaller than 8MB per
Anders Jenbo771b0e42010-04-27 08:45:30 +0000857 * side.
Keith Hui59356ca2010-03-06 18:16:25 +0000858 */
859 struct dimm_size sz = spd_get_dimm_size(device);
860 if ((sz.side1 < 8)) {
Stefan Reinauer65b72ab2015-01-05 12:59:54 -0800861 printk(BIOS_ERR, "DIMMs smaller than 8MB per side\n"
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000862 "are not supported on this NB.\n");
863 die("HALT\n");
Keith Hui59356ca2010-03-06 18:16:25 +0000864 }
Keith Hui59356ca2010-03-06 18:16:25 +0000865
866 /* Divide size by 8 to set up the DRB registers. */
867 drb += (sz.side1 / 8);
868
869 /*
870 * Build the DRB for the next row in MSB so it gets
871 * placed in DRB[n+1] where it belongs when written
872 * as a 16-bit word.
873 */
874 drb &= 0xff;
875 drb |= (drb + (sz.side2 / 8)) << 8;
876 } else {
Keith Hui59356ca2010-03-06 18:16:25 +0000877 /* If there's no DIMM in the slot, set dra to 0x00. */
878 dra = 0x00;
Keith Hui59356ca2010-03-06 18:16:25 +0000879 /* Still have to propagate DRB over. */
880 drb &= 0xff;
881 drb |= (drb << 8);
882 }
883
884 pci_write_config16(NB, DRB + (2 * i), drb);
Keith Hui59356ca2010-03-06 18:16:25 +0000885
886 /* Brings the upper DRB back down to be base for
887 * DRB calculations for the next two rows.
888 */
889 drb >>= 8;
890
891 rps |= (dra & 0x0f) << (i * 4);
Keith Hui59356ca2010-03-06 18:16:25 +0000892 }
893
894 /* Set paging policy register. */
895 pci_write_config8(NB, PGPOL + 1, bpr);
Keith Hui09f5a742010-12-23 17:12:03 +0000896 PRINT_DEBUG("PGPOL[BPR] has been set to 0x%02x\n", bpr);
Keith Hui59356ca2010-03-06 18:16:25 +0000897
898 /* Set DRAM row page size register. */
899 pci_write_config16(NB, RPS, rps);
Keith Hui09f5a742010-12-23 17:12:03 +0000900 PRINT_DEBUG("RPS has been set to 0x%04x\n", rps);
Keith Hui59356ca2010-03-06 18:16:25 +0000901
902 /* ### ECC */
903 pci_write_config8(NB, NBXCFG + 3, nbxecc);
Keith Hui09f5a742010-12-23 17:12:03 +0000904 PRINT_DEBUG("NBXECC[31:24] has been set to 0x%02x\n", nbxecc);
Keith Hui59356ca2010-03-06 18:16:25 +0000905
Keith Huie089a3f2011-08-02 22:28:14 -0400906 /* Set DRAMC[4:3] to proper memory type (EDO/SDRAM/Registered SDRAM). */
Keith Hui59356ca2010-03-06 18:16:25 +0000907
Keith Huie089a3f2011-08-02 22:28:14 -0400908 /* i will be used to set DRAMC[4:3]. */
909 if (regsd && sd) {
910 i = 0x10; // Registered SDRAM
911 } else if (sd) {
912 i = 0x08; // SDRAM
913 } else {
914 i = 0; // EDO
915 }
916
Keith Hui59356ca2010-03-06 18:16:25 +0000917 value = pci_read_config8(NB, DRAMC) & 0xe7;
Keith Huie089a3f2011-08-02 22:28:14 -0400918 value |= i;
Keith Hui59356ca2010-03-06 18:16:25 +0000919 pci_write_config8(NB, DRAMC, value);
Keith Hui09f5a742010-12-23 17:12:03 +0000920 PRINT_DEBUG("DRAMC has been set to 0x%02x\n", value);
Keith Hui59356ca2010-03-06 18:16:25 +0000921}
922
Uwe Hermann115c5b92010-10-09 17:00:18 +0000923void sdram_set_spd_registers(void)
Richard Smithcb8eab42006-07-24 04:25:47 +0000924{
Keith Hui59356ca2010-03-06 18:16:25 +0000925 /* Setup DRAM row boundary registers and other attributes. */
926 set_dram_row_attributes();
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000927
Keith Huidf35cdc2010-09-20 23:41:37 +0000928 /* Setup DRAM buffer strength. */
Keith Hui59356ca2010-03-06 18:16:25 +0000929 set_dram_buffer_strength();
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000930
931 /* TODO: Set PMCR? */
Uwe Hermann1683cef2008-11-27 00:47:07 +0000932 // pci_write_config8(NB, PMCR, 0x14);
933 pci_write_config8(NB, PMCR, 0x10);
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000934
Keith Huidf35cdc2010-09-20 23:41:37 +0000935 /* TODO: This is for EDO memory only. */
Uwe Hermann1683cef2008-11-27 00:47:07 +0000936 pci_write_config8(NB, DRAMT, 0x03);
Richard Smithcb8eab42006-07-24 04:25:47 +0000937}
938
Uwe Hermann115c5b92010-10-09 17:00:18 +0000939void sdram_enable(void)
Richard Smithcb8eab42006-07-24 04:25:47 +0000940{
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000941 int i;
Richard Smithcb8eab42006-07-24 04:25:47 +0000942
Uwe Hermann861f9642007-05-28 14:37:06 +0000943 /* 0. Wait until power/voltages and clocks are stable (200us). */
944 udelay(200);
Richard Smithcb8eab42006-07-24 04:25:47 +0000945
Uwe Hermann861f9642007-05-28 14:37:06 +0000946 /* 1. Apply NOP. Wait 200 clock cycles (200us should do). */
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000947 PRINT_DEBUG("RAM Enable 1: Apply NOP\n");
Uwe Hermann8b643cea2008-12-09 16:36:12 +0000948 do_ram_command(RAM_COMMAND_NOP);
Uwe Hermann861f9642007-05-28 14:37:06 +0000949 udelay(200);
Richard Smithcb8eab42006-07-24 04:25:47 +0000950
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000951 /* 2. Precharge all. Wait tRP. */
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000952 PRINT_DEBUG("RAM Enable 2: Precharge all\n");
Uwe Hermann8b643cea2008-12-09 16:36:12 +0000953 do_ram_command(RAM_COMMAND_PRECHARGE);
Uwe Hermann861f9642007-05-28 14:37:06 +0000954 udelay(1);
Richard Smithcb8eab42006-07-24 04:25:47 +0000955
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000956 /* 3. Perform 8 refresh cycles. Wait tRC each time. */
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000957 PRINT_DEBUG("RAM Enable 3: CBR\n");
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000958 for (i = 0; i < 8; i++) {
Uwe Hermann8b643cea2008-12-09 16:36:12 +0000959 do_ram_command(RAM_COMMAND_CBR);
Uwe Hermann861f9642007-05-28 14:37:06 +0000960 udelay(1);
Richard Smithcb8eab42006-07-24 04:25:47 +0000961 }
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000962
963 /* 4. Mode register set. Wait two memory cycles. */
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000964 PRINT_DEBUG("RAM Enable 4: Mode register set\n");
Uwe Hermann8b643cea2008-12-09 16:36:12 +0000965 do_ram_command(RAM_COMMAND_MRS);
Uwe Hermann861f9642007-05-28 14:37:06 +0000966 udelay(2);
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000967
968 /* 5. Normal operation. */
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000969 PRINT_DEBUG("RAM Enable 5: Normal operation\n");
Uwe Hermann8b643cea2008-12-09 16:36:12 +0000970 do_ram_command(RAM_COMMAND_NORMAL);
Uwe Hermann861f9642007-05-28 14:37:06 +0000971 udelay(1);
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000972
973 /* 6. Finally enable refresh. */
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000974 PRINT_DEBUG("RAM Enable 6: Enable refresh\n");
Uwe Hermann1683cef2008-11-27 00:47:07 +0000975 // pci_write_config8(NB, PMCR, 0x10);
976 spd_enable_refresh();
Uwe Hermann861f9642007-05-28 14:37:06 +0000977 udelay(1);
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000978
Stefan Reinauer64ed2b72010-03-31 14:47:43 +0000979 PRINT_DEBUG("Northbridge following SDRAM init:\n");
Uwe Hermann1a9c8922007-04-01 17:24:03 +0000980 DUMPNORTH();
Richard Smithcb8eab42006-07-24 04:25:47 +0000981}
Keith Hui078e3242017-07-20 21:14:21 -0400982
983void sdram_initialize(void)
984{
985 dump_spd_registers();
986 sdram_set_registers();
987 sdram_set_spd_registers();
988 sdram_enable();
989}