blob: 66c7c170f2f44f48238e7c2de9cbaf70d096793d [file] [log] [blame]
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2007-2009 coresystems GmbH
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
Patrick Georgib890a122015-03-26 15:17:45 +010017 * Foundation, Inc.
Stefan Reinaueraeba92a2009-04-17 08:37:18 +000018 */
19
20#include <types.h>
21#include <spd.h>
22#include <spd_ddr2.h>
Stefan Reinaueraeba92a2009-04-17 08:37:18 +000023#include <delay.h>
stepan8301d832010-12-08 07:07:33 +000024#include "registers.h"
Stefan Reinaueraeba92a2009-04-17 08:37:18 +000025
Stefan Reinaueraeba92a2009-04-17 08:37:18 +000026/* Debugging macros. */
Uwe Hermann01ce6012010-03-05 10:03:50 +000027#if CONFIG_DEBUG_RAM_SETUP
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +000028#define PRINTK_DEBUG(x...) printk(BIOS_DEBUG, x)
Stefan Reinaueraeba92a2009-04-17 08:37:18 +000029#else
30#define PRINTK_DEBUG(x...)
31#endif
32
33#define RAM_COMMAND_NORMAL 0x0
34#define RAM_COMMAND_NOP 0x1
35#define RAM_COMMAND_PRECHARGE 0x2
36#define RAM_COMMAND_MRS 0x3
37#define RAM_COMMAND_CBR 0x4
38
39#define HOSTCTRL PCI_DEV(0, 0, 2)
40#define MEMCTRL PCI_DEV(0, 0, 3)
41
Stefan Reinaueraeba92a2009-04-17 08:37:18 +000042#define OHM_150 1
43
44#ifdef MEM_WIDTH_32BIT_MODE
45#define SDRAM1X_RA_14 30
46#define SDRAM1X_RA_13 29
47#define SDRAM1X_RA_12 28
48#define SDRAM1X_RA_12_8bk 26
49#define SDRAM1X_CA_12 15
50#define SDRAM1X_CA_11 14
51#define SDRAM1X_CA_09 11
52#define SDRAM1X_CA_09_8bk 11
53#define SDRAM1X_BA1 13
54#define SDRAM1X_BA2_8bk 14
55#define SDRAM1X_BA1_8bk 13
56#else
57#define SDRAM1X_RA_14 31
58#define SDRAM1X_RA_13 30
59#define SDRAM1X_RA_12 29
60#define SDRAM1X_RA_12_8bk 27
61#define SDRAM1X_CA_12 16
62#define SDRAM1X_CA_11 15
63#define SDRAM1X_CA_09 12
64#define SDRAM1X_CA_09_8bk 12
65#define SDRAM1X_BA1 14
66#define SDRAM1X_BA2_8bk 15
67#define SDRAM1X_BA1_8bk 14
68#endif
69
70#define MA_Column 0x06
71#define MA_Bank 0x08
72#define MA_Row 0x30
73#define MA_4_Bank 0x00
74#define MA_8_Bank 0x08
75#define MA_12_Row 0x00
76#define MA_13_Row 0x10
77#define MA_14_Row 0x20
78#define MA_15_Row 0x30
79#define MA_9_Column 0x00
80#define MA_10_Column 0x02
81#define MA_11_Column 0x04
82#define MA_12_Column 0x06
83
84#define GET_SPD(i, val, tmp, reg) \
85 do{ \
86 val = 0; \
87 tmp = 0; \
88 for(i = 0; i < 2; i++) { \
89 if(pci_read_config8(PCI_DEV(0, 0, 4), (SCRATCH_REG_BASE + (i << 1)))) { \
90 tmp = get_spd_data(ctrl, i, reg); \
91 if(tmp > val) \
92 val = tmp; \
93 } \
94 } \
95 } while ( 0 )
96
97#define REGISTERPRESET(bus,dev,fun,bdfspec) \
Stefan Reinauerc65666f2010-04-03 12:41:41 +000098 { u8 j, reg; \
99 for (j=0; j<(sizeof((bdfspec))/sizeof(struct regmask)); j++) { \
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000100 printk(BIOS_DEBUG, "Writing bus " #bus " dev " #dev " fun " #fun " register "); \
Stefan Reinauerc65666f2010-04-03 12:41:41 +0000101 printk(BIOS_DEBUG, "%02x", (bdfspec)[j].reg); \
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000102 printk(BIOS_DEBUG, "\n"); \
Stefan Reinauerc65666f2010-04-03 12:41:41 +0000103 reg = pci_read_config8(PCI_DEV((bus), (dev), (fun)), (bdfspec)[j].reg); \
104 reg &= (bdfspec)[j].mask; \
105 reg |= (bdfspec)[j].val; \
106 pci_write_config8(PCI_DEV((bus), (dev), (fun)), (bdfspec)[j].reg, reg); \
Stefan Reinaueraeba92a2009-04-17 08:37:18 +0000107 } \
108 }
109
Stefan Reinauerd2759ff2010-04-25 21:44:33 +0000110static const u8 Reg_Val[] = {
111/* REG, VALUE */
112 0x70, 0x33,
113 0x71, 0x11,
114 0x72, 0x33,
115 0x73, 0x11,
116 0x74, 0x20,
117 0x75, 0x2e,
118 0x76, 0x64,
119 0x77, 0x00,
120 0x78, 0x44,
121 0x79, 0xaa,
122 0x7a, 0x33,
123 0x7b, 0xaa,
124 0x7c, 0x00,
125 0x7e, 0x33,
126 0x7f, 0x33,
127 0x80, 0x44,
128 0x81, 0x44,
129 0x82, 0x44,
130 0x83, 0x02,
131 0x50, 0x88,
132 0x51, 0x7b,
133 0x52, 0x6f,
134 0x53, 0x88,
135 0x54, 0x0e,
136 0x55, 0x00,
137 0x56, 0x00,
138 0x59, 0x00,
139 0x5d, 0x72,
140 0x5e, 0x88,
141 0x5f, 0xc7,
142 0x68, 0x01,
143};
144
145/* Host registers initial value */
146static const u8 Host_Reg_Val[] = {
147/* REG, VALUE */
148 0x60, 0xff,
149 0x61, 0xff,
150 0x62, 0x0f,
151 0x63, 0xff,
152 0x64, 0xff,
153 0x65, 0x0f,
154 0x66, 0xff,
155 0x67, 0x30,
156};
157
158static const u8 Mem_Reg_Init[] = {
159/* REG, AND, OR */
160 0x50, 0x11, 0x66,
161 0x51, 0x11, 0x66,
162 0x52, 0x00, 0x11,
163 0x53, 0x00, 0x0f,
164 0x54, 0x00, 0x00,
165 0x55, 0x00, 0x00,
166 0x56, 0x00, 0x00,
167 0x57, 0x00, 0x00,
168 0x60, 0x00, 0x00,
169 0x62, 0xf7, 0x08,
170 0x65, 0x00, 0xd9,
171 0x66, 0x00, 0x80,
172 0x67, 0x00, 0x50, /* OR 0x00 ?? */
173 0x69, 0xf0, 0x00,
174 0x6a, 0x00, 0x00,
175 0x6d, 0xcf, 0xc0,
176 0x6e, 0xff, 0x80,
177 0x75, 0x0f, 0x40,
178 0x77, 0x00, 0x00,
179 0x80, 0x00, 0x00,
180 0x81, 0x00, 0x00,
181 0x82, 0x00, 0x00,
182 0x83, 0x00, 0x00,
183 0x84, 0x00, 0x00,
184 0x85, 0x00, 0x00,
185 0x86, 0xff, 0x2c, /* OR 0x28 if we don't want enable top 1M SM memory */
186 0x40, 0x00, 0x00,
187 0x7c, 0x00, 0x00,
188 0x7e, 0x00, 0x00,
189 0xa4, 0xfe, 0x00,
190 0xb0, 0x7f, 0x80,
191 0xb1, 0x00, 0xaa,
192 0xb4, 0xfd, 0x02,
193 0xb8, 0xfe, 0x00,
194};
195
196static const u8 Dram_Driving_ODT_CTRL[] = {
197/* REG, VALUE */
198 0xd6, 0xa8,
199 0xd4, 0x80,
200 0xd0, 0x88,
201 0xd3, 0x01,
202 0xd8, 0x00,
203 0xda, 0x80,
204};
205
206#define Rank0_ODT 0x00
207#define Rank1_ODT 0x01
208#define Rank2_ODT 0x02
209#define Rank3_ODT 0x03
210#define NA_ODT 0x00
211#define NB_ODT_75ohm 0x00
212#define NB_ODT_150ohm 0x01
213#define DDR2_ODT_75ohm 0x20
214#define DDR2_ODT_150ohm 0x40
215
216static const u8 ODT_TBL[] = {
217/* RankMap, ODT Control Bits, DRAM & NB ODT setting */
218 0x01, ((NA_ODT << 6) | (NA_ODT << 4) | (NA_ODT << 2) | Rank0_ODT), (DDR2_ODT_150ohm | NB_ODT_75ohm),
219 0x03, ((NA_ODT << 6) | (NA_ODT << 4) | (Rank0_ODT << 2) | Rank1_ODT), (DDR2_ODT_150ohm | NB_ODT_75ohm),
220 0x04, ((NA_ODT << 6) | (Rank2_ODT << 4) | (NA_ODT << 2) | NA_ODT), (DDR2_ODT_150ohm | NB_ODT_75ohm),
221 0x05, ((NA_ODT << 6) | (Rank0_ODT << 4) | (NA_ODT << 2) | Rank2_ODT), (DDR2_ODT_75ohm | NB_ODT_150ohm),
222 0x07, ((NA_ODT << 6) | (Rank0_ODT << 4) | (Rank2_ODT << 2) | Rank2_ODT), (DDR2_ODT_75ohm | NB_ODT_150ohm),
223 0x0c, ((Rank2_ODT << 6) | (Rank3_ODT << 4) | (NA_ODT << 2) | NA_ODT), (DDR2_ODT_150ohm | NB_ODT_75ohm),
224 0x0d, ((Rank0_ODT << 6) | (Rank0_ODT << 4) | (NA_ODT << 2) | Rank2_ODT), (DDR2_ODT_75ohm | NB_ODT_150ohm),
225 0x0f, ((Rank0_ODT << 6) | (Rank0_ODT << 4) | (Rank2_ODT << 2) | Rank2_ODT), (DDR2_ODT_75ohm | NB_ODT_150ohm),
226};
227
228static const u8 DQS_DQ_TBL[] = {
229/* RxE0: DRAM Timing DQS */
230/* RxE2: DRAM Timing DQ */
231/* RxE0, RxE2 */
232 0xee, 0xba,
233 0xee, 0xba,
234 0xcc, 0xba,
235 0xcc, 0xba,
236};
237
238static const u8 Duty_Control_DDR2[] = {
239/* RxEC, RxED, RxEE, RXEF */
240 /* DDRII533 1~2 rank, DDRII400 */
241 0x84, 0x10, 0x00, 0x10,
242 /* DDRII533 3~4 rank */
243 0x44, 0x10, 0x00, 0x10,
244};
245
246static const u8 ChA_Clk_Phase_DDR2_Table[] = {
247/* Rx91, Rx92, Rx93 */
248 /* DDRII533 1 rank */
249 0x04, 0x05, 0x06,
250 /* DDRII533 2~4 rank */
251 0x04, 0x05, 0x05,
252 /* DDRII400 */
253 0x02, 0x04, 0x04,
254};
255
256static const u8 DQ_DQS_Table[] = {
257/* REG, VALUE */
258/* DRAM DQ/DQS Output Delay Control */
259 0xdc, 0x65,
260 0xdd, 0x01,
261 0xde, 0xc0,
262/* DRAM DQ/DQS input Capture Control */
263 0x78, 0x83,
264 0x79, 0x83,
265 0x7a, 0x00,
266};
267
268static const u8 DQSOChA_DDR2_Driving_Table[] = {
269/* Rx70, Rx71 */
270 /* DDRII533 1~2 rank */
271 0x00, 0x01,
272 /* DDRII533 3~4 rank */
273 0x03, 0x00,
274 /* DDRII400 1~2 rank */
275 0x00, 0x04,
276 /* DDRII400 3~4 rank */
277 0x00, 0x01,
278};
279
280/************************************************************************/
281/* Chipset Performance UP and other setting after DRAM Sizing Registers */
282/************************************************************************/
283static const u8 Dram_Table[] = {
284/* REG, AND, OR */
285 0x60, 0xff, 0x03,
286 0x66, 0xcf, 0x80,
287 0x68, 0x00, 0x00,
288 0x69, 0xfd, 0x03,
289 0x6e, 0xff, 0x01,
290 0x95, 0xff, 0x40,
291};
292
293static const u8 Host_Table[] = {
294/* REG, AND, OR */
295 0x51, 0x81, 0x7a,
296 0x55, 0xff, 0x06,
297 0x5e, 0x00, 0x88,
298 0x5d, 0xff, 0xb2,
299};
300
301static const u8 Init_Rank_Reg_Table[] = {
302 /* Rank Ending Address Registers */
303 0x40, 0x41, 0x42, 0x43,
304 /* Rank Beginning Address Registers */
305 0x48, 0x49, 0x4a, 0x4b,
306 /* Physical-to-Virtual Rank Mapping Registers */
307 0x54, 0x55,
308};
309
310static const u16 DDR2_MRS_table[] = {
311/* CL: 2, 3, 4, 5 */
312 0x150, 0x1d0, 0x250, 0x2d0, /* BL=4 ;Use 1X-bandwidth MA table to init DRAM */
313 0x158, 0x1d8, 0x258, 0x2d8, /* BL=8 ;Use 1X-bandwidth MA table to init DRAM */
314};
315
316#define MRS_DDR2_TWR2 ((0 << 15) | (0 << 20) | (1 << 12))
317#define MRS_DDR2_TWR3 ((0 << 15) | (1 << 20) | (0 << 12))
318#define MRS_DDR2_TWR4 ((0 << 15) | (1 << 20) | (1 << 12))
319#define MRS_DDR2_TWR5 ((1 << 15) | (0 << 20) | (0 << 12))
320static const u32 DDR2_Twr_table[] = {
321 MRS_DDR2_TWR2,
322 MRS_DDR2_TWR3,
323 MRS_DDR2_TWR4,
324 MRS_DDR2_TWR5,
325};
326
327static const u8 DQSI_Rate_Table[] = {
328 8, /* DDRII 200 */
329 8, /* DDRII 266 */
330 8, /* DDRII 333 */
331 7, /* DDRII 400 */
332 8, /* DDRII 533 */
333 8, /* DDRII 666 */
334};
335
336static const u8 REFC_Table[] = {
337 0x65, 0x32, /* DDRII 100 */
338 0x86, 0x43, /* DDRII 266 */
339 0xa8, 0x54, /* DDRII 333 */
340 0xca, 0x65, /* DDRII 400 */
341 0xca, 0x86, /* DDRII 533 */
342 0xca, 0xa8, /* DDRII 666 */
343};
Stefan Reinaueraeba92a2009-04-17 08:37:18 +0000344
345static void do_ram_command(const struct mem_controller *ctrl, u8 command)
346{
347 u8 reg;
348
349 reg = pci_read_config8(MEMCTRL, 0x6b);
350 reg &= 0xf8; /* Clear bits 2-0. */
351 reg |= command;
352 pci_write_config8(MEMCTRL, 0x6b, reg);
353
354 PRINTK_DEBUG(" Sending RAM command 0x%02x\n", reg);
355}
356
357// TODO factor out to another file
358static void c7_cpu_setup(const struct mem_controller *ctrl)
359{
360 u8 size, i;
361 size = sizeof(Reg_Val) / sizeof(Reg_Val[0]);
362 for (i = 0; i < size; i += 2)
363 pci_write_config8(HOSTCTRL, Reg_Val[i], Reg_Val[i + 1]);
364}
365
366static void ddr_detect(const struct mem_controller *ctrl)
367{
368 /* FIXME: Only supports 2 ranks per DIMM */
369 u8 val, rsize, dimm;
370 u8 nrank = 0;
371 u8 ndimm = 0;
372 u8 rmap = 0;
373 for (dimm = 0; dimm < DIMM_SOCKETS; dimm++) {
374 val = get_spd_data(ctrl, dimm, 0);
375 if ((val == 0x80) || (val == 0xff)) {
376 ndimm++;
377 rsize = get_spd_data(ctrl, dimm, SPD_RANK_SIZE);
378 /* unit is 128M */
379 rsize = (rsize << 3) | (rsize >> 5);
380 val =
381 get_spd_data(ctrl, dimm,
382 SPD_MOD_ATTRIB_RANK) & SPD_MOD_ATTRIB_RANK_NUM_MASK;
383 switch (val) {
384 case 1:
385 pci_write_config8(PCI_DEV(0, 0, 4), (SCRATCH_RANK_1 + (dimm << 1)),
386 rsize);
387 rmap |= (1 << ((dimm << 1) + 1));
388 nrank++;
389 case 0:
390 pci_write_config8(PCI_DEV(0, 0, 4), (SCRATCH_RANK_0 + (dimm << 1)),
391 rsize);
392 rmap |= (1 << (dimm << 1));
393 nrank++;
394 }
395 }
396 }
397 pci_write_config8(PCI_DEV(0, 0, 4), SCRATCH_DIMM_NUM, ndimm);
398 pci_write_config8(PCI_DEV(0, 0, 4), SCRATCH_RANK_NUM, nrank);
399 pci_write_config8(PCI_DEV(0, 0, 4), SCRATCH_RANK_MAP, rmap);
400}
401
402static void sdram_set_safe_values(const struct mem_controller *ctrl)
403{
404 /* The purpose of this function is to set initial values for the dram
405 * size and timings. It will be replaced with the SPD based function
406 * once the RAM commands are working with these values.
407 */
408 u8 regs, val, t, dimm;
409 u32 spds, tmp;
410
411 regs = pci_read_config8(MEMCTRL, 0x6c);
412 if (regs & (1 << 6))
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000413 printk(BIOS_DEBUG, "DDR2 Detected.\n");
Stefan Reinaueraeba92a2009-04-17 08:37:18 +0000414 else
415 die("ERROR: DDR1 memory detected but not supported by coreboot.\n");
416
417 /* Enable DDR2 */
418 regs |= (1 << 7);
419 pci_write_config8(MEMCTRL, 0x6c, regs);
420
421 /* SPD 5 # of ranks */
422 pci_write_config8(MEMCTRL, 0x6d, 0xc0);
423
424 /**********************************************/
425 /* Set DRAM Freq (DDR2 533) */
426 /**********************************************/
427 /* SPD 9 SDRAM Cycle Time */
428 GET_SPD(dimm, spds, regs, 9);
429
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000430 printk(BIOS_DEBUG, "\nDDRII ");
Stefan Reinaueraeba92a2009-04-17 08:37:18 +0000431 if (spds <= 0x3d) {
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000432 printk(BIOS_DEBUG, "533");
Stefan Reinaueraeba92a2009-04-17 08:37:18 +0000433 val = DDRII_533;
434 t = 38;
435 } else if (spds <= 0x50) {
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000436 printk(BIOS_DEBUG, "400");
Stefan Reinaueraeba92a2009-04-17 08:37:18 +0000437 val = DDRII_400;
438 t = 50;
439 } else if (spds <= 0x60) {
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000440 printk(BIOS_DEBUG, "333");
Stefan Reinaueraeba92a2009-04-17 08:37:18 +0000441 val = DDRII_333;
442 t = 60;
443 } else if (spds <= 0x75) {
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000444 printk(BIOS_DEBUG, "266");
Stefan Reinaueraeba92a2009-04-17 08:37:18 +0000445 val = DDRII_266;
446 t = 75;
447 } else {
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000448 printk(BIOS_DEBUG, "200");
Stefan Reinaueraeba92a2009-04-17 08:37:18 +0000449 val = DDRII_200;
450 t = 100;
451 }
452 /* To store DDRII frequence */
453 pci_write_config8(PCI_DEV(0, 0, 4), SCRATCH_DRAM_FREQ, val);
454
Stefan Reinauer14e22772010-04-27 06:56:47 +0000455 /* Manual reset and adjust DLL when DRAM change frequency
Stefan Reinaueraeba92a2009-04-17 08:37:18 +0000456 * This is a necessary sequence.
457 */
458 udelay(2000);
459 regs = pci_read_config8(MEMCTRL, 0x90);
460 regs |= 0x7;
461 pci_write_config8(MEMCTRL, 0x90, regs);
462 udelay(2000);
463 regs = pci_read_config8(MEMCTRL, 0x90);
464 regs &= ~0x7;
465 regs |= val;
466 pci_write_config8(MEMCTRL, 0x90, regs);
467 udelay(2000);
468 regs = pci_read_config8(MEMCTRL, 0x6b);
469 regs |= 0xc0;
470 regs &= ~0x10;
471 pci_write_config8(MEMCTRL, 0x6b, regs);
472 udelay(1);
473 regs |= 0x10;
474 pci_write_config8(MEMCTRL, 0x6b, regs);
475 udelay(1);
476 regs &= ~0xc0;
477 pci_write_config8(MEMCTRL, 0x6b, regs);
478 regs = pci_read_config8(MEMCTRL, 0x6f);
479 regs |= 0x1;
480 pci_write_config8(MEMCTRL, 0x6f, regs);
481
482 /**********************************************/
483 /* Set DRAM Timing Setting (DDR2 533) */
484 /**********************************************/
485 /* SPD 9 18 23 25 CAS Latency NB3DRAM_REG62[2:0] */
486 /* Read SPD byte 18 CAS Latency */
487 GET_SPD(dimm, spds, regs, SPD_CAS_LAT);
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000488 printk(BIOS_DEBUG, "\nCAS Supported ");
Stefan Reinaueraeba92a2009-04-17 08:37:18 +0000489 if (spds & SPD_CAS_LAT_2)
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000490 printk(BIOS_DEBUG, "2 ");
Stefan Reinaueraeba92a2009-04-17 08:37:18 +0000491 if (spds & SPD_CAS_LAT_3)
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000492 printk(BIOS_DEBUG, "3 ");
Stefan Reinaueraeba92a2009-04-17 08:37:18 +0000493 if (spds & SPD_CAS_LAT_4)
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000494 printk(BIOS_DEBUG, "4 ");
Stefan Reinaueraeba92a2009-04-17 08:37:18 +0000495 if (spds & SPD_CAS_LAT_5)
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000496 printk(BIOS_DEBUG, "5 ");
Stefan Reinaueraeba92a2009-04-17 08:37:18 +0000497 if (spds & SPD_CAS_LAT_6)
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000498 printk(BIOS_DEBUG, "6");
Stefan Reinaueraeba92a2009-04-17 08:37:18 +0000499
500 /* We don't consider CAS = 6, because CX700 doesn't support it */
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000501 printk(BIOS_DEBUG, "\n CAS:");
Stefan Reinaueraeba92a2009-04-17 08:37:18 +0000502 if (spds & SPD_CAS_LAT_5) {
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000503 printk(BIOS_DEBUG, "Starting at CL5");
Stefan Reinaueraeba92a2009-04-17 08:37:18 +0000504 val = 0x3;
505 /* See whether we can improve it */
506 GET_SPD(dimm, tmp, regs, SPD_CAS_LAT_MIN_X_1);
507 if ((spds & SPD_CAS_LAT_4) && (tmp < 0x50)) {
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000508 printk(BIOS_DEBUG, "\n... going to CL4");
Stefan Reinaueraeba92a2009-04-17 08:37:18 +0000509 val = 0x2;
510 }
511 GET_SPD(dimm, tmp, regs, SPD_CAS_LAT_MIN_X_2);
512 if ((spds & SPD_CAS_LAT_3) && (tmp < 0x50)) {
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000513 printk(BIOS_DEBUG, "\n... going to CL3");
Stefan Reinaueraeba92a2009-04-17 08:37:18 +0000514 val = 0x1;
515 }
516 } else {
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000517 printk(BIOS_DEBUG, "Starting at CL4");
Stefan Reinaueraeba92a2009-04-17 08:37:18 +0000518 val = 0x2;
519 GET_SPD(dimm, tmp, regs, SPD_CAS_LAT_MIN_X_1);
520 if ((spds & SPD_CAS_LAT_3) && (tmp < 0x50)) {
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000521 printk(BIOS_DEBUG, "\n... going to CL3");
Stefan Reinaueraeba92a2009-04-17 08:37:18 +0000522 val = 0x1;
523 }
524 GET_SPD(dimm, tmp, regs, SPD_CAS_LAT_MIN_X_2);
525 if ((spds & SPD_CAS_LAT_2) && (tmp < 0x50)) {
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000526 printk(BIOS_DEBUG, "\n... going to CL2");
Stefan Reinaueraeba92a2009-04-17 08:37:18 +0000527 val = 0x0;
528 }
529 }
530 regs = pci_read_config8(MEMCTRL, 0x62);
531 regs &= ~0x7;
532 regs |= val;
533 pci_write_config8(MEMCTRL, 0x62, regs);
534
535 /* SPD 27 Trp NB3DRAM_REG64[3:2] */
536 GET_SPD(dimm, spds, regs, SPD_TRP);
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000537 printk(BIOS_DEBUG, "\nTrp %d", spds);
Stefan Reinaueraeba92a2009-04-17 08:37:18 +0000538 spds >>= 2;
539 for (val = 2; val <= 5; val++) {
540 if (spds <= (val * t / 10)) {
541 val = val - 2;
542 break;
543 }
544 }
545 val <<= 2;
546 regs = pci_read_config8(MEMCTRL, 0x64);
547 regs &= ~0xc;
548 regs |= val;
549 pci_write_config8(MEMCTRL, 0x64, regs);
550
551 /* SPD 29 Trcd NB3DRAM_REG64[7:6] */
552 GET_SPD(dimm, spds, regs, SPD_TRCD);
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000553 printk(BIOS_DEBUG, "\nTrcd %d", spds);
Stefan Reinaueraeba92a2009-04-17 08:37:18 +0000554 spds >>= 2;
555 for (val = 2; val <= 5; val++) {
556 if (spds <= (val * t / 10)) {
557 val = val - 2;
558 break;
559 }
560 }
561 val <<= 6;
562 regs = pci_read_config8(MEMCTRL, 0x64);
563 regs &= ~0xc0;
564 regs |= val;
565 pci_write_config8(MEMCTRL, 0x64, regs);
566
567 /* SPD 30 Tras NB3DRAM_REG62[7:4] */
568 GET_SPD(dimm, spds, regs, SPD_TRAS);
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000569 printk(BIOS_DEBUG, "\nTras %d", spds);
Stefan Reinaueraeba92a2009-04-17 08:37:18 +0000570 for (val = 5; val <= 20; val++) {
571 if (spds <= (val * t / 10)) {
572 val = val - 5;
573 break;
574 }
575 }
576 val <<= 4;
577 regs = pci_read_config8(MEMCTRL, 0x62);
578 regs &= ~0xf0;
579 regs |= val;
580 pci_write_config8(MEMCTRL, 0x62, regs);
581
582 /* SPD 42 SPD 40 Trfc NB3DRAM_REG61[5:0] */
583 GET_SPD(dimm, spds, regs, SPD_TRFC);
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000584 printk(BIOS_DEBUG, "\nTrfc %d", spds);
Stefan Reinaueraeba92a2009-04-17 08:37:18 +0000585 tmp = spds;
586 GET_SPD(dimm, spds, regs, SPD_EX_TRC_TRFC);
587 if (spds & 0x1)
588 tmp += 256;
589 if (spds & 0xe)
590 tmp++;
591 for (val = 8; val <= 71; val++) {
592 if (tmp <= (val * t / 10)) {
593 val = val - 8;
594 break;
595 }
596 }
597 regs = pci_read_config8(MEMCTRL, 0x61);
598 regs &= ~0x3f;
599 regs |= val;
600 pci_write_config8(MEMCTRL, 0x61, regs);
601
602 /* SPD 28 Trrd NB3DRAM_REG63[7:6] */
603 GET_SPD(dimm, spds, regs, SPD_TRRD);
604 for (val = 2; val <= 5; val++) {
605 if (spds <= (val * t / 10)) {
606 val = val - 2;
607 break;
608 }
609 }
610 val <<= 6;
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000611 printk(BIOS_DEBUG, "\nTrrd val = 0x%x", val);
Stefan Reinaueraeba92a2009-04-17 08:37:18 +0000612 regs = pci_read_config8(MEMCTRL, 0x63);
613 regs &= ~0xc0;
614 regs |= val;
615 pci_write_config8(MEMCTRL, 0x63, regs);
616
617 /* SPD 36 Twr NB3DRAM_REG61[7:6] */
618 GET_SPD(dimm, spds, regs, SPD_TWR);
619 for (val = 2; val <= 5; val++) {
620 if (spds <= (val * t / 10)) {
621 val = val - 2;
622 break;
623 }
624 }
625 val <<= 6;
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000626 printk(BIOS_DEBUG, "\nTwr val = 0x%x", val);
Stefan Reinaueraeba92a2009-04-17 08:37:18 +0000627
628 regs = pci_read_config8(MEMCTRL, 0x61);
629 regs &= ~0xc0;
630 regs |= val;
631 pci_write_config8(MEMCTRL, 0x61, regs);
632
633 /* SPD 37 Twtr NB3DRAM_REG63[1] */
634 GET_SPD(dimm, spds, regs, SPD_TWTR);
635 spds >>= 2;
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000636 printk(BIOS_DEBUG, "\nTwtr 0x%x", spds);
Stefan Reinaueraeba92a2009-04-17 08:37:18 +0000637 if (spds <= (t * 2 / 10))
638 val = 0;
639 else
640 val = 1;
641 val <<= 1;
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000642 printk(BIOS_DEBUG, "\nTwtr val = 0x%x", val);
Stefan Reinaueraeba92a2009-04-17 08:37:18 +0000643
644 regs = pci_read_config8(MEMCTRL, 0x63);
645 regs &= ~0x2;
646 regs |= val;
647 pci_write_config8(MEMCTRL, 0x63, regs);
648
649 /* SPD 38 Trtp NB3DRAM_REG63[3] */
650 GET_SPD(dimm, spds, regs, SPD_TRTP);
651 spds >>= 2;
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000652 printk(BIOS_DEBUG, "\nTrtp 0x%x", spds);
Stefan Reinaueraeba92a2009-04-17 08:37:18 +0000653 if (spds <= (t * 2 / 10))
654 val = 0;
655 else
656 val = 1;
657 val <<= 3;
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000658 printk(BIOS_DEBUG, "\nTrtp val = 0x%x", val);
Stefan Reinaueraeba92a2009-04-17 08:37:18 +0000659
660 regs = pci_read_config8(MEMCTRL, 0x63);
661 regs &= ~0x8;
662 regs |= val;
663 pci_write_config8(MEMCTRL, 0x63, regs);
664
665 /**********************************************/
666 /* Set DRAM DRDY Setting */
667 /**********************************************/
668 /* Write slowest value to register */
669 tmp = sizeof(Host_Reg_Val) / sizeof(Host_Reg_Val[0]);
670 for (val = 0; val < tmp; val += 2)
671 pci_write_config8(HOSTCTRL, Host_Reg_Val[val], Host_Reg_Val[val + 1]);
672
673 /* F2_RX51[7]=0, disable DRDY timing */
674 regs = pci_read_config8(HOSTCTRL, 0x51);
675 regs &= ~0x80;
676 pci_write_config8(HOSTCTRL, 0x51, regs);
677
678 /**********************************************/
679 /* Set DRAM BurstLength */
680 /**********************************************/
681 regs = pci_read_config8(MEMCTRL, 0x6c);
682 for (dimm = 0; dimm < DIMM_SOCKETS; dimm++) {
683 if (pci_read_config8(PCI_DEV(0, 0, 4), (SCRATCH_REG_BASE + (dimm << 1)))) {
684 spds = get_spd_data(ctrl, dimm, 16);
685 if (!(spds & 0x8))
686 break;
687 }
688 }
689 if (dimm == 2)
690 regs |= 0x8;
691 pci_write_config8(MEMCTRL, 0x6c, regs);
692 val = pci_read_config8(HOSTCTRL, 0x54);
693 val &= ~0x10;
694 if (dimm == 2)
695 val |= 0x10;
696 pci_write_config8(HOSTCTRL, 0x54, val);
697
698 /**********************************************/
699 /* Set DRAM Driving Setting */
700 /**********************************************/
701 /* DRAM Timing ODT */
702 tmp = sizeof(Dram_Driving_ODT_CTRL) / sizeof(Dram_Driving_ODT_CTRL[0]);
703 for (val = 0; val < tmp; val += 2)
704 pci_write_config8(MEMCTRL, Dram_Driving_ODT_CTRL[val],
705 Dram_Driving_ODT_CTRL[val + 1]);
706
707 regs = pci_read_config8(PCI_DEV(0, 0, 4), SCRATCH_RANK_NUM);
708 val = pci_read_config8(MEMCTRL, 0xd5);
709 val &= ~0xaa;
710 switch (regs) {
711 case 3:
712 case 2:
713 val |= 0xa0;
714 break;
715 default:
716 val |= 0x80;
717 }
718 regs = pci_read_config8(PCI_DEV(0, 0, 4), SCRATCH_DIMM_NUM);
719 if (regs == 1)
720 val |= 0xa;
721 pci_write_config8(MEMCTRL, 0xd5, val);
722
723 regs = pci_read_config8(PCI_DEV(0, 0, 4), SCRATCH_DIMM_NUM);
724 val = pci_read_config8(MEMCTRL, 0xd6);
725 val &= ~0x2;
726 if (regs == 1)
727 val |= 0x2;
728 pci_write_config8(MEMCTRL, 0xd6, val);
729
730 regs = pci_read_config8(PCI_DEV(0, 0, 4), SCRATCH_RANK_MAP);
731 tmp = sizeof(ODT_TBL) / sizeof(ODT_TBL[0]);
732 for (val = 0; val < tmp; val += 3) {
733 if (regs == ODT_TBL[val]) {
734 pci_write_config8(MEMCTRL, 0xd8, ODT_TBL[val + 1]);
735 /* Store DRAM & NB ODT setting in d0f4_Rxd8 */
736 pci_write_config8(PCI_DEV(0, 0, 4), SCRATCH_DRAM_NB_ODT, ODT_TBL[val + 2]);
737 break;
738 }
739 }
740
741 pci_write_config8(MEMCTRL, 0xd9, 0x0a);
742 regs = pci_read_config8(PCI_DEV(0, 0, 4), SCRATCH_RANK_NUM);
743 regs--;
744 regs = regs << 1;
745 pci_write_config8(MEMCTRL, 0xe0, DQS_DQ_TBL[regs++]);
746 pci_write_config8(MEMCTRL, 0xe2, DQS_DQ_TBL[regs]);
747
748 /* DRAM Timing CS */
749 pci_write_config8(MEMCTRL, 0xe4, 0x66);
750
751 /* DRAM Timing MAA */
752 val = 0;
753 for (dimm = 0; dimm < DIMM_SOCKETS; dimm++) {
754 if (pci_read_config8(PCI_DEV(0, 0, 4), (SCRATCH_REG_BASE + (dimm << 1)))) {
755 spds = get_spd_data(ctrl, dimm, SPD_PRI_WIDTH);
756 spds = 64 / spds;
757 if (pci_read_config8
758 (PCI_DEV(0, 0, 4), (SCRATCH_REG_BASE + (dimm << 1) + 1)))
759 spds = spds << 1;
760 val += spds;
761 }
762 }
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000763 printk(BIOS_DEBUG, "\nchip #%d", val);
Stefan Reinaueraeba92a2009-04-17 08:37:18 +0000764 if (val > 18)
765 regs = 0xdb;
766 else
767 regs = 0x86;
768 pci_write_config8(MEMCTRL, 0xe8, regs);
769
770 /* DRAM Timing MAB */
771 pci_write_config8(MEMCTRL, 0xe9, 0x0);
772
773 /* DRAM Timing DCLK VT8454C always 0x66 */
774 pci_write_config8(MEMCTRL, 0xe6, 0xaa);
775
776 /**********************************************/
777 /* Set DRAM Duty Control */
778 /**********************************************/
779 regs = pci_read_config8(PCI_DEV(0, 0, 4), SCRATCH_RANK_NUM);
780 switch (regs) {
781 case 1:
782 case 2: /* 1~2 rank */
783 val = 0;
784 break;
785 case 3:
786 case 4: /* 3~4 rank */
787 regs = pci_read_config8(PCI_DEV(0, 0, 4), SCRATCH_DRAM_FREQ);
788 if (regs == DDRII_533)
789 val = 4;
790 else /* DDRII-400 */
791 val = 0;
792 break;
793 }
794 regs = 0xec;
795 for (t = 0; t < 4; t++) {
796 pci_write_config8(MEMCTRL, regs, Duty_Control_DDR2[val]);
797 regs++;
798 val++;
799 }
800
801 /**********************************************/
802 /* Set DRAM Clock Control */
803 /**********************************************/
804 /* Write Data Phase */
805 val = pci_read_config8(PCI_DEV(0, 0, 4), SCRATCH_DRAM_FREQ);
806 regs = pci_read_config8(MEMCTRL, 0x75);
807 regs &= 0xf0;
808 switch (val) {
809 case DDRII_533:
810 pci_write_config8(MEMCTRL, 0x74, 0x07);
811 regs |= 0x7;
812 break;
813 case DDRII_400:
814 default:
815 pci_write_config8(MEMCTRL, 0x74, 0x05);
816 regs |= 0x5;
817 break;
818 }
819 pci_write_config8(MEMCTRL, 0x75, regs);
820 pci_write_config8(MEMCTRL, 0x76, 0x80);
821
822 /* Clock Phase Control for FeedBack Mode */
823 regs = pci_read_config8(MEMCTRL, 0x90);
824// regs |= 0x80;
825 pci_write_config8(MEMCTRL, 0x90, regs);
826
827 regs = pci_read_config8(PCI_DEV(0, 0, 4), SCRATCH_DRAM_FREQ);
828 switch (regs) {
829 case DDRII_533:
830 regs = pci_read_config8(PCI_DEV(0, 0, 4), SCRATCH_RANK_NUM);
831 if (regs == 1)
832 val = 0;
833 else
834 val = 3;
835 break;
836 case DDRII_400:
837 default:
838 val = 6;
839 break;
840 }
841 regs = pci_read_config8(MEMCTRL, 0x91);
842 regs &= ~0xc0;
843 regs |= 0x80;
844 pci_write_config8(MEMCTRL, 0x91, regs);
845 regs = 0x91;
846 for (t = 0; t < 3; t++) {
847 dimm = pci_read_config8(MEMCTRL, regs);
848 dimm &= ~0x7;
849 dimm |= ChA_Clk_Phase_DDR2_Table[val];
850 pci_write_config8(MEMCTRL, regs, dimm);
851 regs++;
852 val++;
853 }
854
855 pci_write_config8(MEMCTRL, 0x97, 0x12);
856 pci_write_config8(MEMCTRL, 0x98, 0x33);
857
858 regs = pci_read_config8(PCI_DEV(0, 0, 4), SCRATCH_RANK_0);
859 val = pci_read_config8(PCI_DEV(0, 0, 4), SCRATCH_RANK_2);
860 if (regs && val)
861 pci_write_config8(MEMCTRL, 0x9d, 0x00);
862 else
863 pci_write_config8(MEMCTRL, 0x9d, 0x0f);
864
865 tmp = sizeof(DQ_DQS_Table) / sizeof(DQ_DQS_Table[0]);
866 for (val = 0; val < tmp; val += 2)
867 pci_write_config8(MEMCTRL, DQ_DQS_Table[val], DQ_DQS_Table[val + 1]);
868 regs = pci_read_config8(PCI_DEV(0, 0, 4), SCRATCH_DRAM_FREQ);
869 if (regs == DDRII_533)
870 pci_write_config8(MEMCTRL, 0x7b, 0xa0);
871 else
872 pci_write_config8(MEMCTRL, 0x7b, 0x10);
873
874 /***************************************************/
875 /* Set necessary register before DRAM initialize */
876 /***************************************************/
877 tmp = sizeof(Mem_Reg_Init) / sizeof(Mem_Reg_Init[0]);
878 for (val = 0; val < tmp; val += 3) {
879 regs = pci_read_config8(MEMCTRL, Mem_Reg_Init[val]);
880 regs &= Mem_Reg_Init[val + 1];
881 regs |= Mem_Reg_Init[val + 2];
882 pci_write_config8(MEMCTRL, Mem_Reg_Init[val], regs);
883 }
884 regs = pci_read_config8(HOSTCTRL, 0x51);
885 regs &= 0xbf; // Clear bit 6 Disable Read Around Write
886 pci_write_config8(HOSTCTRL, 0x51, regs);
887
888 regs = pci_read_config8(HOSTCTRL, 0x54);
889 t = regs >> 5;
890 val = pci_read_config8(HOSTCTRL, 0x57);
891 dimm = val >> 5;
892 if (t == dimm)
893 t = 0x0;
894 else
895 t = 0x1;
896 regs &= ~0x1;
897 regs |= t;
898 val &= ~0x1;
899 val |= t;
900 pci_write_config8(HOSTCTRL, 0x57, val);
901
902 regs = pci_read_config8(HOSTCTRL, 0x51);
903 regs |= t;
904 pci_write_config8(HOSTCTRL, 0x51, regs);
905
906 regs = pci_read_config8(MEMCTRL, 0x90);
907 regs &= 0x7;
908 val = 0;
909 if (regs < 0x2)
910 val = 0x80;
911 regs = pci_read_config8(MEMCTRL, 0x76);
912 regs &= 0x80;
913 regs |= val;
914 pci_write_config8(MEMCTRL, 0x76, regs);
915
916 regs = pci_read_config8(MEMCTRL, 0x6f);
917 regs |= 0x10;
918 pci_write_config8(MEMCTRL, 0x6f, regs);
919
920 /***************************************************/
921 /* Find suitable DQS value for ChA and ChB */
922 /***************************************************/
923 // Set DQS output delay for Channel A
924 regs = pci_read_config8(PCI_DEV(0, 0, 4), SCRATCH_DRAM_FREQ);
925 val = pci_read_config8(PCI_DEV(0, 0, 4), SCRATCH_RANK_NUM);
926 switch (regs) {
927 case DDRII_533:
928 if (val < 2)
929 val = 0;
930 else
931 val = 2;
932 break;
933 case DDRII_400:
934 default:
935 if (val < 2)
936 val = 4;
937 else
938 val = 6;
939 break;
940 }
941 for (t = 0; t < 2; t++)
942 pci_write_config8(MEMCTRL, (0x70 + t), DQSOChA_DDR2_Driving_Table[val + t]);
943 // Set DQS output delay for Channel B
944 pci_write_config8(MEMCTRL, 0x72, 0x0);
945
946 regs = pci_read_config8(PCI_DEV(0, 0, 4), SCRATCH_RANK_0);
947 val = pci_read_config8(PCI_DEV(0, 0, 4), SCRATCH_RANK_2);
948 if (regs && val)
949 pci_write_config8(MEMCTRL, 0x73, 0xfd);
950 else
951 pci_write_config8(MEMCTRL, 0x73, 0x01);
952}
953
954static void sdram_set_registers(const struct mem_controller *ctrl)
955{
956 c7_cpu_setup(ctrl);
957 ddr_detect(ctrl);
958 sdram_set_safe_values(ctrl);
959}
960
961static void step_20_21(const struct mem_controller *ctrl)
962{
963 u8 val;
964
965 // Step 20
966 udelay(200);
967
968 val = pci_read_config8(PCI_DEV(0, 0, 4), SCRATCH_DRAM_NB_ODT);
969 if (val & DDR2_ODT_150ohm)
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -0800970 read32((void *)0x102200);
Stefan Reinaueraeba92a2009-04-17 08:37:18 +0000971 else
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -0800972 read32((void *)0x102020);
Stefan Reinaueraeba92a2009-04-17 08:37:18 +0000973
974 /* Step 21. Normal operation */
Stefan Reinauer65b72ab2015-01-05 12:59:54 -0800975 printk(BIOS_SPEW, "RAM Enable 5: Normal operation\n");
Stefan Reinaueraeba92a2009-04-17 08:37:18 +0000976 do_ram_command(ctrl, RAM_COMMAND_NORMAL);
977 udelay(3);
978}
979
980static void step_2_19(const struct mem_controller *ctrl)
981{
982 u32 i;
983 u8 val;
984
985 // Step 2
986 val = pci_read_config8(MEMCTRL, 0x69);
987 val &= ~0x03;
988 pci_write_config8(MEMCTRL, 0x69, val);
989
990 /* Step 3 Apply NOP. */
Stefan Reinauer65b72ab2015-01-05 12:59:54 -0800991 printk(BIOS_SPEW, "RAM Enable 1: Apply NOP\n");
Stefan Reinaueraeba92a2009-04-17 08:37:18 +0000992 do_ram_command(ctrl, RAM_COMMAND_NOP);
993
994 udelay(15);
995
996 // Step 4
Stefan Reinauer65b72ab2015-01-05 12:59:54 -0800997 printk(BIOS_SPEW, "SEND: ");
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -0800998 read32((void *)0);
Stefan Reinauer65b72ab2015-01-05 12:59:54 -0800999 printk(BIOS_SPEW, "OK\n");
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001000
1001 // Step 5
1002 udelay(400);
1003
1004 /* 6. Precharge all. Wait tRP. */
Stefan Reinauer65b72ab2015-01-05 12:59:54 -08001005 printk(BIOS_SPEW, "RAM Enable 2: Precharge all\n");
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001006 do_ram_command(ctrl, RAM_COMMAND_PRECHARGE);
1007
1008 // Step 7
Stefan Reinauer65b72ab2015-01-05 12:59:54 -08001009 printk(BIOS_SPEW, "SEND: ");
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -08001010 read32((void *)0);
Stefan Reinauer65b72ab2015-01-05 12:59:54 -08001011 printk(BIOS_SPEW, "OK\n");
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001012
1013 /* Step 8. Mode register set. */
Stefan Reinauer65b72ab2015-01-05 12:59:54 -08001014 printk(BIOS_SPEW, "RAM Enable 4: Mode register set\n");
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001015 do_ram_command(ctrl, RAM_COMMAND_MRS); //enable dll
1016
1017 // Step 9
Stefan Reinauer65b72ab2015-01-05 12:59:54 -08001018 printk(BIOS_SPEW, "SEND: ");
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001019
1020 val = pci_read_config8(PCI_DEV(0, 0, 4), SCRATCH_DRAM_NB_ODT);
1021 if (val & DDR2_ODT_150ohm)
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -08001022 read32((void *)0x102200); //DDR2_ODT_150ohm
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001023 else
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -08001024 read32((void *)0x102020);
Stefan Reinauer65b72ab2015-01-05 12:59:54 -08001025 printk(BIOS_SPEW, "OK\n");
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001026
1027 // Step 10
Stefan Reinauer65b72ab2015-01-05 12:59:54 -08001028 printk(BIOS_SPEW, "SEND: ");
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -08001029 read32((void *)0x800);
Stefan Reinauer65b72ab2015-01-05 12:59:54 -08001030 printk(BIOS_SPEW, "OK\n");
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001031
1032 /* Step 11. Precharge all. Wait tRP. */
Stefan Reinauer65b72ab2015-01-05 12:59:54 -08001033 printk(BIOS_SPEW, "RAM Enable 2: Precharge all\n");
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001034 do_ram_command(ctrl, RAM_COMMAND_PRECHARGE);
1035
1036 // Step 12
Stefan Reinauer65b72ab2015-01-05 12:59:54 -08001037 printk(BIOS_SPEW, "SEND: ");
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -08001038 read32((u32 *)0x0);
Stefan Reinauer65b72ab2015-01-05 12:59:54 -08001039 printk(BIOS_SPEW, "OK\n");
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001040
1041 /* Step 13. Perform 8 refresh cycles. Wait tRC each time. */
Stefan Reinauer65b72ab2015-01-05 12:59:54 -08001042 printk(BIOS_SPEW, "RAM Enable 3: CBR\n");
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001043 do_ram_command(ctrl, RAM_COMMAND_CBR);
1044
1045 /* JEDEC says only twice, do 8 times for posterity */
1046 // Step 16: Repeat Step 14 and 15 another 7 times
1047 for (i = 0; i < 8; i++) {
1048 // Step 14
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -08001049 read32((u32 *)0);
Stefan Reinauer65b72ab2015-01-05 12:59:54 -08001050 printk(BIOS_SPEW, ".");
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001051
1052 // Step 15
1053 udelay(100);
1054 }
1055
1056 /* Step 17. Mode register set. Wait 200us. */
Stefan Reinauer65b72ab2015-01-05 12:59:54 -08001057 printk(BIOS_SPEW, "\nRAM Enable 4: Mode register set\n");
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001058
1059 //safe value for now, BL=8, WR=4, CAS=4
1060 do_ram_command(ctrl, RAM_COMMAND_MRS);
1061 udelay(200);
1062
1063 /* Use Single Chanel temporarily */
1064 val = pci_read_config8(MEMCTRL, 0x6c);
1065 if (val & 0x8) { /* Burst Length = 8 */
1066 val = pci_read_config8(MEMCTRL, 0x62);
1067 val &= 0x7;
1068 i = DDR2_MRS_table[4 + val];
1069 } else {
1070 val = pci_read_config8(MEMCTRL, 0x62);
1071 val &= 0x7;
1072 i = DDR2_MRS_table[val];
1073 }
1074
1075 // Step 18
1076 val = pci_read_config8(MEMCTRL, 0x61);
1077 val = val >> 6;
1078 i |= DDR2_Twr_table[val];
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -08001079 read32((void *)i);
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001080
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +00001081 printk(BIOS_DEBUG, "MRS = %08x\n", i);
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001082
1083 udelay(15);
1084
1085 // Step 19
1086 val = pci_read_config8(PCI_DEV(0, 0, 4), SCRATCH_DRAM_NB_ODT);
1087 if (val & DDR2_ODT_150ohm)
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -08001088 read32((void *)0x103e00); //EMRS OCD Default
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001089 else
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -08001090 read32((void *)0x103c20);
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001091}
1092
1093static void sdram_set_vr(const struct mem_controller *ctrl, u8 num)
1094{
1095 u8 reg, val;
1096 val = 0x54 + (num >> 1);
1097 reg = pci_read_config8(MEMCTRL, val);
1098 reg &= (0xf << (4 * (num & 0x1)));
1099 reg |= (((0x8 | num) << 4) >> (4 * (num & 0x1)));
1100 pci_write_config8(MEMCTRL, val, reg);
1101}
1102static void sdram_ending_addr(const struct mem_controller *ctrl, u8 num)
1103{
1104 u8 reg, val;
1105 /* Set Ending Address */
1106 val = 0x40 + num;
1107 reg = pci_read_config8(MEMCTRL, val);
1108 reg += 0x10;
1109 pci_write_config8(MEMCTRL, val, reg);
1110 /* Set Beginning Address */
1111 val = 0x48 + num;
1112 pci_write_config8(MEMCTRL, val, 0x0);
1113}
1114
1115static void sdram_clear_vr_addr(const struct mem_controller *ctrl, u8 num)
1116{
1117 u8 reg, val;
1118 val = 0x54 + (num >> 1);
1119 reg = pci_read_config8(MEMCTRL, val);
1120 reg = ~(0x80 >> (4 * (num & 0x1)));
1121 pci_write_config8(MEMCTRL, val, reg);
1122 val = 0x40 + num;
1123 reg = pci_read_config8(MEMCTRL, val);
1124 reg -= 0x10;
1125 pci_write_config8(MEMCTRL, val, reg);
1126 val = 0x48 + num;
1127 pci_write_config8(MEMCTRL, val, 0x0);
1128}
1129
1130/* Perform sizing DRAM by dynamic method */
1131static void sdram_calc_size(const struct mem_controller *ctrl, u8 num)
1132{
1133 u8 ca, ra, ba, reg;
1134 ba = pci_read_config8(PCI_DEV(0, 0, 4), SCRATCH_FLAGS);
1135 if (ba == 8) {
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -08001136 write8((void *)0, 0x0d);
1137 ra = read8((void *)0);
1138 write8((void *)(1 << SDRAM1X_RA_12_8bk), 0x0c);
1139 ra = read8((void *)0);
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001140
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -08001141 write8((void *)0, 0x0a);
1142 ca = read8((void *)0);
1143 write8((void *)(1 << SDRAM1X_CA_09_8bk), 0x0c);
1144 ca = read8((void *)0);
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001145
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -08001146 write8((void *)0, 0x03);
1147 ba = read8((void *)0);
1148 write8((void *)(1 << SDRAM1X_BA2_8bk), 0x02);
1149 ba = read8((void *)0);
1150 write8((void *)(1 << SDRAM1X_BA1_8bk), 0x01);
1151 ba = read8((void *)0);
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001152 } else {
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -08001153 write8((void *)0, 0x0f);
1154 ra = read8((void *)0);
1155 write8((void *)(1 << SDRAM1X_RA_14), 0x0e);
1156 ra = read8((void *)0);
1157 write8((void *)(1 << SDRAM1X_RA_13), 0x0d);
1158 ra = read8((void *)0);
1159 write8((void *)(1 << SDRAM1X_RA_12), 0x0c);
1160 ra = read8((void *)0);
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001161
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -08001162 write8((void *)0, 0x0c);
1163 ca = read8((void *)0);
1164 write8((void *)(1 << SDRAM1X_CA_12), 0x0b);
1165 ca = read8((void *)0);
1166 write8((void *)(1 << SDRAM1X_CA_11), 0x0a);
1167 ca = read8((void *)0);
1168 write8((void *)(1 << SDRAM1X_CA_09), 0x09);
1169 ca = read8((void *)0);
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001170
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -08001171 write8((void *)0, 0x02);
1172 ba = read8((void *)0);
1173 write8((void *)(1 << SDRAM1X_BA1), 0x01);
1174 ba = read8((void *)0);
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001175 }
1176
1177 if (ra < 10 || ra > 15)
1178 die("bad RA");
1179 if (ca < 8 || ca > 12)
1180 die("bad CA");
1181 if (ba < 1 || ba > 3)
1182 die("bad BA");
1183
1184 /* Calculate MA type save to scratch register */
1185 reg = 0;
1186
1187 switch (ra) {
1188 case 12:
1189 reg |= MA_12_Row;
1190 break;
1191 case 13:
1192 reg |= MA_13_Row;
1193 break;
1194 case 14:
1195 reg |= MA_14_Row;
1196 break;
1197 default:
1198 reg |= MA_15_Row;
1199 }
1200
1201 switch (ca) {
1202 case 9:
1203 reg |= MA_9_Column;
1204 break;
1205 case 10:
1206 reg |= MA_10_Column;
1207 break;
1208 case 11:
1209 reg |= MA_11_Column;
1210 break;
1211 default:
1212 reg |= MA_12_Column;
1213 }
1214
1215 switch (ba) {
1216 case 3:
1217 reg |= MA_8_Bank;
1218 break;
1219 default:
1220 reg |= MA_4_Bank;
1221 }
1222
1223 pci_write_config8(PCI_DEV(0, 0, 4), (SCRATCH_RANK0_MA_REG + num), reg);
1224
1225 if (ra >= 13)
1226 pci_write_config8(PCI_DEV(0, 0, 4), SCRATCH_DRAM_256M_BIT, 1);
1227
1228 /* Calculate rank size save to scratch register */
1229 ra = ra + ca + ba + 3 - 26; /* 1 unit = 64M */
1230 ra = 1 << ra;
1231 pci_write_config8(PCI_DEV(0, 0, 4), (SCRATCH_RANK0_SIZE_REG + num), ra);
1232}
1233
1234static void sdram_enable(const struct mem_controller *ctrl)
1235{
1236 u8 reg8;
1237 u8 val, i;
1238 device_t dev;
1239 u8 dl, dh;
1240 u32 quot;
1241
1242 /* Init Present Bank */
1243 val = sizeof(Init_Rank_Reg_Table) / sizeof(Init_Rank_Reg_Table[0]);
1244 for (i = 0; i < val; i++)
1245 pci_write_config8(MEMCTRL, Init_Rank_Reg_Table[i], 0x0);
1246
1247 /* Init other banks */
1248 for (i = 0; i < 4; i++) {
1249 reg8 = pci_read_config8(PCI_DEV(0, 0, 4), (SCRATCH_RANK_0 + i));
1250 if (reg8) {
1251 sdram_set_vr(ctrl, i);
1252 sdram_ending_addr(ctrl, i);
1253 step_2_19(ctrl);
1254 step_20_21(ctrl);
1255 sdram_clear_vr_addr(ctrl, i);
1256 }
1257 }
1258
1259#ifdef MEM_WIDTH_32BIT_MODE
1260 /****************************************************************/
1261 /* Set Dram 32bit Mode */
1262 /****************************************************************/
1263 reg8 = pci_read_config8(MEMCTRL, 0x6c);
1264 reg8 |= 0x20;
1265 pci_write_config(MEMCTRL, 0x6c, reg8);
1266#endif
1267
1268 /****************************************************************/
1269 /* Find the DQSI Low/High bound and save it to Scratch register */
1270 /****************************************************************/
1271 for (dl = 0; dl < 0x3f; dl += 2) {
1272 reg8 = dl & 0x3f;
1273 reg8 |= 0x80; /* Set Manual Mode */
1274 pci_write_config8(MEMCTRL, 0x77, reg8);
1275 for (i = 0; i < 4; i++) {
1276 reg8 = pci_read_config8(PCI_DEV(0, 0, 4), (SCRATCH_RANK_0 + i));
1277 if (reg8) {
1278 sdram_set_vr(ctrl, i);
1279 sdram_ending_addr(ctrl, i);
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -08001280 write32((void *)0, 0x55555555);
1281 write32((void *)4, 0x55555555);
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001282 udelay(15);
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -08001283 if (read32((void *)0) != 0x55555555)
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001284 break;
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -08001285 if (read32((void *)4) != 0x55555555)
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001286 break;
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -08001287 write32((void *)0, 0xaaaaaaaa);
1288 write32((void *)4, 0xaaaaaaaa);
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001289 udelay(15);
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -08001290 if (read32((void *)0) != 0xaaaaaaaa)
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001291 break;
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -08001292 if (read32((void *)4) != 0xaaaaaaaa)
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001293 break;
1294 sdram_clear_vr_addr(ctrl, i);
1295 }
1296 }
1297 if (i == 4)
1298 break;
1299 else
1300 sdram_clear_vr_addr(ctrl, i);
1301 }
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +00001302 printk(BIOS_DEBUG, "\nDQSI Low %08x", dl);
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001303 for (dh = dl; dh < 0x3f; dh += 2) {
1304 reg8 = dh & 0x3f;
1305 reg8 |= 0x80; /* Set Manual Mode */
1306 pci_write_config8(MEMCTRL, 0x77, reg8);
1307 for (i = 0; i < 4; i++) {
1308 reg8 = pci_read_config8(PCI_DEV(0, 0, 4), (SCRATCH_RANK_0 + i));
1309 if (reg8) {
1310 sdram_set_vr(ctrl, i);
1311 sdram_ending_addr(ctrl, i);
1312
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -08001313 write32((void *)0, 0x55555555);
1314 write32((void *)4, 0x55555555);
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001315 udelay(15);
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -08001316 if (read32((void *)0) != 0x55555555)
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001317 break;
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -08001318 if (read32((void *)4) != 0x55555555)
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001319 break;
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -08001320 write32((void *)0, 0xaaaaaaaa);
1321 write32((void *)4, 0xaaaaaaaa);
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001322 udelay(15);
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -08001323 if (read32((void *)0) != 0xaaaaaaaa)
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001324 break;
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -08001325 if (read32((void *)4) != 0xaaaaaaaa)
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001326 break;
1327 sdram_clear_vr_addr(ctrl, i);
1328 }
1329 }
1330 if (i != 4) {
1331 sdram_clear_vr_addr(ctrl, i);
1332 break;
1333 }
1334 }
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +00001335 printk(BIOS_DEBUG, "\nDQSI High %02x", dh);
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001336 pci_write_config8(PCI_DEV(0, 0, 4), SCRATCH_CHA_DQSI_LOW_REG, dl);
1337 pci_write_config8(PCI_DEV(0, 0, 4), SCRATCH_CHA_DQSI_HIGH_REG, dh);
1338 reg8 = pci_read_config8(MEMCTRL, 0X90) & 0X7;
1339 val = DQSI_Rate_Table[reg8];
1340 quot = dh - dl;
1341 quot = quot * val;
1342 quot >>= 4;
1343 val = quot + dl;
1344 pci_write_config8(PCI_DEV(0, 0, 4), SCRATCH_ChA_DQSI_REG, val);
1345 reg8 = val & 0x3f;
1346 reg8 |= 0x80;
1347 pci_write_config8(MEMCTRL, 0x77, reg8);
1348
1349 /****************************************************************/
1350 /* Find out the lowest Bank Interleave and Set Register */
1351 /****************************************************************/
1352#if 0
1353 //TODO
1354 reg8 = pci_read_config8(MEMCTRL, 0x69);
1355 reg8 &= ~0xc0;
1356 reg8 |= 0x80; //8 banks
1357 pci_write_config8(MEMCTRL, 0x69, reg8);
1358#endif
1359 dl = 2;
1360 for (i = 0; i < 4; i++) {
1361 reg8 = pci_read_config8(PCI_DEV(0, 0, 4), (SCRATCH_RANK_0 + i));
1362 if (reg8) {
1363 reg8 = get_spd_data(ctrl, (i >> 1), 17);
1364 sdram_set_vr(ctrl, i);
1365 sdram_ending_addr(ctrl, i);
1366 if (reg8 == 4) {
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -08001367 write8((void *)0, 0x02);
1368 val = read8((void *)0);
1369 write8((void *)(1 << SDRAM1X_BA1), 0x01);
1370 val = read8((void *)0);
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001371 } else {
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -08001372 write8((void *)0, 0x03);
1373 val = read8((void *)0);
1374 write8((void *)(1 << SDRAM1X_BA2_8bk), 0x02);
1375 val = read8((void *)0);
1376 write8((void *)(1 << SDRAM1X_BA1_8bk), 0x01);
1377 val = read8((void *)0);
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001378 }
1379 if (val < dl)
1380 dl = val;
1381 sdram_clear_vr_addr(ctrl, i);
1382 }
1383 }
1384 dl <<= 6;
1385 reg8 = pci_read_config8(MEMCTRL, 0x69);
1386 reg8 &= ~0xc0;
1387 reg8 |= dl;
1388 pci_write_config8(MEMCTRL, 0x69, reg8);
1389
1390 /****************************************************************/
1391 /* DRAM Sizing and Fill MA type */
1392 /****************************************************************/
1393 for (i = 0; i < 4; i++) {
1394 val = pci_read_config8(PCI_DEV(0, 0, 4), (SCRATCH_RANK_0 + i));
1395 if (val) {
1396 reg8 = get_spd_data(ctrl, (i >> 1), 17);
1397 pci_write_config8(PCI_DEV(0, 0, 4), SCRATCH_FLAGS, reg8);
1398 if (reg8 == 4) {
1399 /* Use MA Type 3 for DRAM sizing */
1400 reg8 = pci_read_config8(MEMCTRL, 0x50);
1401 reg8 &= 0x11;
1402 reg8 |= 0x66;
1403 pci_write_config8(MEMCTRL, 0x50, reg8);
1404 pci_write_config8(MEMCTRL, 0x51, reg8);
1405 } else {
1406 /* Use MA Type 5 for DRAM sizing */
1407 reg8 = pci_read_config8(MEMCTRL, 0x50);
1408 reg8 &= 0x11;
1409 reg8 |= 0xaa;
1410 pci_write_config8(MEMCTRL, 0x50, reg8);
1411 pci_write_config8(MEMCTRL, 0x51, reg8);
1412 reg8 = pci_read_config8(MEMCTRL, 0x53);
1413 reg8 &= 0x0f;
1414 reg8 |= 0x90;
1415 pci_write_config8(MEMCTRL, 0x53, reg8);
1416 }
1417 sdram_set_vr(ctrl, i);
1418 val = 0x40 + i;
1419 reg8 = pci_read_config8(MEMCTRL, val);
1420 /* max size 3G for new MA table */
1421 reg8 += 0x30;
1422 pci_write_config8(MEMCTRL, val, reg8);
1423 /* Set Beginning Address */
1424 val = 0x48 + i;
1425 pci_write_config8(MEMCTRL, val, 0x0);
1426
1427 sdram_calc_size(ctrl, i);
1428
1429 /* Clear */
1430 val = 0x54 + (i >> 1);
1431 reg8 = pci_read_config8(MEMCTRL, val);
1432 reg8 = ~(0x80 >> (4 * (i & 0x1)));
1433 pci_write_config8(MEMCTRL, val, reg8);
1434 val = 0x40 + i;
1435 reg8 = pci_read_config8(MEMCTRL, val);
1436 reg8 -= 0x30;
1437 pci_write_config8(MEMCTRL, val, reg8);
1438 val = 0x48 + i;
1439 pci_write_config8(MEMCTRL, val, 0x0);
1440
1441 }
1442 }
1443 /* Clear MA Type */
1444 reg8 = pci_read_config8(MEMCTRL, 0x50);
1445 reg8 &= 0x11;
1446 pci_write_config8(MEMCTRL, 0x50, reg8);
1447 pci_write_config8(MEMCTRL, 0x51, reg8);
1448 reg8 = pci_read_config8(MEMCTRL, 0x6b);
1449 reg8 &= ~0x08;
1450 pci_write_config8(MEMCTRL, 0x6b, reg8);
1451
1452 /****************************************************************/
1453 /* DRAM re-initialize for burst length */
1454 /****************************************************************/
1455 for (i = 0; i < 4; i++) {
1456 reg8 = pci_read_config8(PCI_DEV(0, 0, 4), (SCRATCH_RANK_0 + i));
1457 if (reg8) {
1458 sdram_set_vr(ctrl, i);
1459 sdram_ending_addr(ctrl, i);
1460 step_2_19(ctrl);
1461 step_20_21(ctrl);
1462 sdram_clear_vr_addr(ctrl, i);
1463 }
1464 }
1465
1466 /****************************************************************/
1467 /* Set the MA Type */
1468 /****************************************************************/
1469 reg8 = pci_read_config8(MEMCTRL, 0x50);
1470 reg8 &= 0x11;
1471 pci_write_config8(MEMCTRL, 0x50, reg8);
1472
1473 reg8 = pci_read_config8(MEMCTRL, 0x51);
1474 reg8 &= 0x11;
1475 pci_write_config8(MEMCTRL, 0x51, reg8);
1476
1477 reg8 = pci_read_config8(MEMCTRL, 0x6b);
1478 reg8 &= ~0x08;
1479 pci_write_config8(MEMCTRL, 0x6b, reg8);
1480
1481 for (i = 0; i < 4; i += 2) {
1482 reg8 = pci_read_config8(PCI_DEV(0, 0, 4), (SCRATCH_RANK_0 + i));
1483 if (reg8) {
1484 reg8 = pci_read_config8(PCI_DEV(0, 0, 4), (SCRATCH_RANK0_MA_REG + i));
1485 reg8 &= (MA_Bank + MA_Column);
1486 val = pci_read_config8(MEMCTRL, 0x50);
1487 if (i == 0) {
1488 reg8 <<= 4;
1489 val &= 0x1f;
1490 } else
1491 val &= 0xf1;
1492 val |= reg8;
1493 pci_write_config8(MEMCTRL, 0x50, val);
1494 }
1495 }
1496
1497 /****************************************************************/
1498 /* Set Start and Ending Address */
1499 /****************************************************************/
1500 dl = 0; /* Begin Address */
1501 dh = 0; /* Ending Address */
1502 for (i = 0; i < 4; i++) {
1503 reg8 = pci_read_config8(PCI_DEV(0, 0, 4), (SCRATCH_RANK_0 + i));
1504 if (reg8) {
1505 reg8 = pci_read_config8(PCI_DEV(0, 0, 4), (SCRATCH_RANK0_SIZE_REG + i));
1506 if (reg8 == 0)
1507 continue;
1508 dh += reg8;
1509 pci_write_config8(MEMCTRL, (0x40 + i), dh);
1510 pci_write_config8(MEMCTRL, (0x48 + i), dl);
1511 dl = dh;
1512 }
1513 }
1514 dh <<= 2;
1515 // F7_Rx57 Ending address mirror register
1516 pci_write_config8(PCI_DEV(0, 0, 7), 0x57, dh);
1517 dev = pci_locate_device(PCI_ID(0x1106, 0x324e), 0);
1518 pci_write_config8(dev, 0x57, dh);
1519 // LOW TOP Address
1520 pci_write_config8(MEMCTRL, 0x88, dh);
1521 pci_write_config8(MEMCTRL, 0x85, dh);
1522 // also program vlink mirror
1523 pci_write_config8(PCI_DEV(0, 0, 7), 0xe5, dh);
1524
1525 /****************************************************************/
1526 /* Set Physical to Virtual Rank mapping */
1527 /****************************************************************/
1528 pci_write_config32(MEMCTRL, 0x54, 0x0);
1529 for (i = 0; i < 4; i++) {
1530 reg8 = pci_read_config8(PCI_DEV(0, 0, 4), (SCRATCH_RANK_0 + i));
1531 if (reg8) {
1532 reg8 = pci_read_config8(MEMCTRL, (0x54 + (i >> 1)));
1533 if (i & 0x1) { /* Odd Rank */
1534 reg8 &= 0xf0;
1535 reg8 |= (0x8 | i);
1536 } else { /* Even Rank */
1537
1538 reg8 &= 0x0f;
1539 reg8 |= ((0x8 | i) << 4);
1540 }
1541 pci_write_config8(MEMCTRL, (0x54 + (i >> 1)), reg8);
1542 }
1543 }
1544
1545 /****************************************************************/
1546 /* Set DRAM Refresh Counter */
1547 /****************************************************************/
1548 val = pci_read_config8(MEMCTRL, 0X90) & 0X7;
1549 val <<= 1;
1550 reg8 = pci_read_config8(PCI_DEV(0, 0, 4), SCRATCH_DRAM_256M_BIT);
1551 if (reg8)
1552 val++;
1553 pci_write_config8(MEMCTRL, 0x6a, REFC_Table[val]);
1554
1555 /****************************************************************/
1556 /* Chipset Performance UP and other setting after DRAM Sizing */
1557 /****************************************************************/
1558 /* Dram Registers */
1559 val = sizeof(Dram_Table) / sizeof(Dram_Table[0]);
1560 for (i = 0; i < val; i += 3) {
1561 reg8 = pci_read_config8(MEMCTRL, Dram_Table[i]);
1562 reg8 &= Dram_Table[i + 1];
1563 reg8 |= Dram_Table[i + 2];
1564 pci_write_config8(MEMCTRL, Dram_Table[i], reg8);
1565 }
1566
1567 /* Host Registers */
1568 val = sizeof(Host_Table) / sizeof(Host_Table[0]);
1569 for (i = 0; i < val; i += 3) {
1570 reg8 = pci_read_config8(HOSTCTRL, Host_Table[i]);
1571 reg8 &= Host_Table[i + 1];
1572 reg8 |= Host_Table[i + 2];
1573 pci_write_config8(HOSTCTRL, Host_Table[i], reg8);
1574 }
1575
1576 /* PM Registers */
1577#ifdef SETUP_PM_REGISTERS
1578 val = sizeof(PM_Table) / sizeof(PM_Table[0]);
1579 for (i = 0; i < val; i += 3) {
1580 reg8 = pci_read_config8(PCI_DEV(0, 0, 4), PM_Table[i]);
1581 reg8 &= PM_Table[i + 1];
1582 reg8 |= PM_Table[i + 2];
1583 pci_write_config8(PCI_DEV(0, 0, 4), PM_Table[i], reg8);
1584 }
1585#endif
1586 pci_write_config8(HOSTCTRL, 0x5d, 0xb2);
1587
1588 /****************************************************************/
1589 /* UMA registers for N-series projects */
1590 /****************************************************************/
1591
1592 /* Manual setting frame buffer bank */
1593 for (i = 0; i < 4; i++) {
1594 reg8 = pci_read_config8(PCI_DEV(0, 0, 4), (SCRATCH_RANK_0 + i));
1595 if (reg8)
1596 val = i;
1597 }
1598 pci_write_config8(MEMCTRL, 0xb0, val);
1599 reg8 = 0x40; // Frame buffer size 64M
1600 reg8 |= 0x80; // VGA Enable
1601 reg8 |= 0x0a; // A[31:28] = 1010b
1602 pci_write_config8(MEMCTRL, 0xa1, reg8);
1603
1604#ifdef ECC
1605 // Clear Ecc
1606 outl(0x80000180, 0xcf8);
1607 outb(0xff, 0xcfc);
1608 // Enable Ecc
1609 outl(0x80000188, 0xcf8);
1610 outb(0xcf, 0xcfc);
1611
1612 reg8 = pci_read_config8(PCI_DEV(0, 0, 0), 0xa5);
1613 reg8 |= 0x10;
1614 pci_write_config8(PCI_DEV(0, 0, 0), 0xa5, reg8);
1615
1616 reg8 = pci_read_config8(PCI_DEV(0, 0, 0), 0x91);
1617 reg8 |= 0x20;
1618 pci_write_config8(PCI_DEV(0, 0, 0), 0x91, reg8);
1619#endif
1620
1621 static const struct regmask {
1622 u8 reg;
1623 u8 mask;
1624 u8 val;
1625 } b0d1f0[] = {
Stefan Reinauer14e22772010-04-27 06:56:47 +00001626 { 0x40, 0x00, 0x8b},
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001627 { 0x41, 0x80, 0x43},
1628 { 0x42, 0x00, 0x62},
1629 { 0x43, 0x00, 0x44},
1630 { 0x44, 0x00, 0x34},
1631 { 0x45, 0x00, 0x72}
1632 }, b0d0f3[] = {
1633 { 0x53, 0xf0, 0x0f},
1634 { 0x60, 0x00, 0x03},
1635 { 0x65, 0x00, 0xd9},
1636 { 0x66, 0x00, 0x80},
1637 { 0x67, 0x00, 0x00},
1638 { 0x68, 0x00, 0x01},
1639 { 0x69, 0xe0, 0x03},
1640 { 0x6b, 0x00, 0x10},
1641 { 0x6c, 0xc1, 0x08},
1642 { 0x6e, 0x00, 0x89},
1643 { 0x6f, 0x00, 0x51},
1644 { 0x75, ~0x40, 0x40},
1645 { 0x76, 0x8f, 0x00},
1646 { 0x7b, 0x00, 0xa0},
1647 { 0x86, 0x01, 0x24},
1648 { 0x86, 0x04, 0x29},
1649 { 0x8c, 0x00, 0x00},
1650 { 0x8d, 0x00, 0x00},
1651 { 0x95, ~0x40, 0x00},
1652 { 0xa2, 0x00, 0x44},
1653 { 0xb1, 0x00, 0xaa}
1654 }, b0d0f0[] = {
1655 { 0x4d, 0x00, 0x24},
1656 { 0x4f, 0x00, 0x01},
1657 { 0xbc, 0x00, 0x21},
1658 { 0xbe, 0x00, 0x00},
1659 { 0xbf, 0x7f, 0x80}
1660 }, b0d17f0[] = {
1661 { 0x40, ~0x01, 0x01}, // enable timer/counter shadow registers
1662 { 0x67, ~0x03, 0x01},
1663 { 0x5b, ~0x01, 0x00},
1664 { 0x8d, ~0x02, 0x02},
Stefan Reinauerc65666f2010-04-03 12:41:41 +00001665 { 0x97, 0x7f, 0x00},
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001666 { 0xd2, ~0x18, 0x00},
1667 { 0xe2, ~0x36, 0x06},
Stefan Reinauerc65666f2010-04-03 12:41:41 +00001668 { 0xe4, 0x7f, 0x00},
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001669 { 0xe5, 0x00, 0x40},
1670 { 0xe6, 0x00, 0x20},
Stefan Reinauerc65666f2010-04-03 12:41:41 +00001671 { 0xe7, 0x2f, 0xc0},
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001672 { 0xec, ~0x08, 0x00}
1673 }, b0d17f7[] = {
Stefan Reinauerc65666f2010-04-03 12:41:41 +00001674 { 0x4e, 0x7f, 0x80},
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001675 { 0x4f, ~(1 << 6), 1 << 6 }, /* PG_CX700: 14.1.1 enable P2P Bridge Header for External PCI Bus */
1676 { 0x74, ~0x00, 0x04}, /* PG_CX700: 14.1.2 APIC FSB directly up to snmic, not on pci */
1677 { 0x7c, ~0x00, 0x02}, /* PG_CX700: 14.1.1 APIC FSB directly up to snmic, not on pci */
1678 { 0xe6, 0x0, 0x04} // MSI post
1679 }, b0d19f0[] = { /* P2PE */
1680 { 0x42, ~0x08, 0x08}, // Disable HD Audio,
Stefan Reinauerc65666f2010-04-03 12:41:41 +00001681 { 0x40, 0x3f, 0x80} // 14.1.3.1.1 of the PG: extended cfg mode for pcie. enable capability, but don't activate
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001682 }, b0d0f2[] = {
1683 { 0x50, ~0x40, 0x88},
1684 { 0x51, 0x80, 0x7b},
1685 { 0x52, 0x90, 0x6f},
1686 { 0x53, 0x00, 0x88},
1687 { 0x54, 0xe4, 0x16},
1688 { 0x55, 0xf2, 0x04},
1689 { 0x56, 0x0f, 0x00},
1690 { 0x57, ~0x04, 0x00},
1691 { 0x5d, 0x00, 0xb2},
1692 { 0x5e, 0x00, 0x88},
1693 { 0x5f, 0x00, 0xc7},
1694 { 0x5c, 0x00, 0x01}
1695 };
1696
1697 REGISTERPRESET(0, 0, 0, b0d0f0);
1698 REGISTERPRESET(0, 0, 2, b0d0f2);
1699 REGISTERPRESET(0, 0, 3, b0d0f3);
1700 REGISTERPRESET(0, 1, 0, b0d1f0);
1701 REGISTERPRESET(0, 17, 0, b0d17f0);
1702 REGISTERPRESET(0, 17, 7, b0d17f7);
1703 REGISTERPRESET(0, 19, 0, b0d19f0);
1704}