blob: 249f265376df35fcf882d63b502e2ceef52cbb8f [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.
Stefan Reinaueraeba92a2009-04-17 08:37:18 +000014 */
15
16#include <types.h>
17#include <spd.h>
18#include <spd_ddr2.h>
Stefan Reinaueraeba92a2009-04-17 08:37:18 +000019#include <delay.h>
stepan8301d832010-12-08 07:07:33 +000020#include "registers.h"
Stefan Reinaueraeba92a2009-04-17 08:37:18 +000021
Stefan Reinaueraeba92a2009-04-17 08:37:18 +000022/* Debugging macros. */
Uwe Hermann01ce6012010-03-05 10:03:50 +000023#if CONFIG_DEBUG_RAM_SETUP
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +000024#define PRINTK_DEBUG(x...) printk(BIOS_DEBUG, x)
Stefan Reinaueraeba92a2009-04-17 08:37:18 +000025#else
26#define PRINTK_DEBUG(x...)
27#endif
28
29#define RAM_COMMAND_NORMAL 0x0
30#define RAM_COMMAND_NOP 0x1
31#define RAM_COMMAND_PRECHARGE 0x2
32#define RAM_COMMAND_MRS 0x3
33#define RAM_COMMAND_CBR 0x4
34
35#define HOSTCTRL PCI_DEV(0, 0, 2)
36#define MEMCTRL PCI_DEV(0, 0, 3)
37
Stefan Reinaueraeba92a2009-04-17 08:37:18 +000038#ifdef MEM_WIDTH_32BIT_MODE
39#define SDRAM1X_RA_14 30
40#define SDRAM1X_RA_13 29
41#define SDRAM1X_RA_12 28
42#define SDRAM1X_RA_12_8bk 26
43#define SDRAM1X_CA_12 15
44#define SDRAM1X_CA_11 14
45#define SDRAM1X_CA_09 11
46#define SDRAM1X_CA_09_8bk 11
47#define SDRAM1X_BA1 13
48#define SDRAM1X_BA2_8bk 14
49#define SDRAM1X_BA1_8bk 13
50#else
51#define SDRAM1X_RA_14 31
52#define SDRAM1X_RA_13 30
53#define SDRAM1X_RA_12 29
54#define SDRAM1X_RA_12_8bk 27
55#define SDRAM1X_CA_12 16
56#define SDRAM1X_CA_11 15
57#define SDRAM1X_CA_09 12
58#define SDRAM1X_CA_09_8bk 12
59#define SDRAM1X_BA1 14
60#define SDRAM1X_BA2_8bk 15
61#define SDRAM1X_BA1_8bk 14
62#endif
63
64#define MA_Column 0x06
65#define MA_Bank 0x08
66#define MA_Row 0x30
67#define MA_4_Bank 0x00
68#define MA_8_Bank 0x08
69#define MA_12_Row 0x00
70#define MA_13_Row 0x10
71#define MA_14_Row 0x20
72#define MA_15_Row 0x30
73#define MA_9_Column 0x00
74#define MA_10_Column 0x02
75#define MA_11_Column 0x04
76#define MA_12_Column 0x06
77
78#define GET_SPD(i, val, tmp, reg) \
79 do{ \
80 val = 0; \
81 tmp = 0; \
82 for(i = 0; i < 2; i++) { \
83 if(pci_read_config8(PCI_DEV(0, 0, 4), (SCRATCH_REG_BASE + (i << 1)))) { \
84 tmp = get_spd_data(ctrl, i, reg); \
85 if(tmp > val) \
86 val = tmp; \
87 } \
88 } \
89 } while ( 0 )
90
91#define REGISTERPRESET(bus,dev,fun,bdfspec) \
Stefan Reinauerc65666f2010-04-03 12:41:41 +000092 { u8 j, reg; \
93 for (j=0; j<(sizeof((bdfspec))/sizeof(struct regmask)); j++) { \
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +000094 printk(BIOS_DEBUG, "Writing bus " #bus " dev " #dev " fun " #fun " register "); \
Stefan Reinauerc65666f2010-04-03 12:41:41 +000095 printk(BIOS_DEBUG, "%02x", (bdfspec)[j].reg); \
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +000096 printk(BIOS_DEBUG, "\n"); \
Stefan Reinauerc65666f2010-04-03 12:41:41 +000097 reg = pci_read_config8(PCI_DEV((bus), (dev), (fun)), (bdfspec)[j].reg); \
98 reg &= (bdfspec)[j].mask; \
99 reg |= (bdfspec)[j].val; \
100 pci_write_config8(PCI_DEV((bus), (dev), (fun)), (bdfspec)[j].reg, reg); \
Stefan Reinaueraeba92a2009-04-17 08:37:18 +0000101 } \
102 }
103
Stefan Reinauerd2759ff2010-04-25 21:44:33 +0000104static const u8 Reg_Val[] = {
105/* REG, VALUE */
106 0x70, 0x33,
107 0x71, 0x11,
108 0x72, 0x33,
109 0x73, 0x11,
110 0x74, 0x20,
111 0x75, 0x2e,
112 0x76, 0x64,
113 0x77, 0x00,
114 0x78, 0x44,
115 0x79, 0xaa,
116 0x7a, 0x33,
117 0x7b, 0xaa,
118 0x7c, 0x00,
119 0x7e, 0x33,
120 0x7f, 0x33,
121 0x80, 0x44,
122 0x81, 0x44,
123 0x82, 0x44,
124 0x83, 0x02,
125 0x50, 0x88,
126 0x51, 0x7b,
127 0x52, 0x6f,
128 0x53, 0x88,
129 0x54, 0x0e,
130 0x55, 0x00,
131 0x56, 0x00,
132 0x59, 0x00,
133 0x5d, 0x72,
134 0x5e, 0x88,
135 0x5f, 0xc7,
136 0x68, 0x01,
137};
138
139/* Host registers initial value */
140static const u8 Host_Reg_Val[] = {
141/* REG, VALUE */
142 0x60, 0xff,
143 0x61, 0xff,
144 0x62, 0x0f,
145 0x63, 0xff,
146 0x64, 0xff,
147 0x65, 0x0f,
148 0x66, 0xff,
149 0x67, 0x30,
150};
151
152static const u8 Mem_Reg_Init[] = {
153/* REG, AND, OR */
154 0x50, 0x11, 0x66,
155 0x51, 0x11, 0x66,
156 0x52, 0x00, 0x11,
157 0x53, 0x00, 0x0f,
158 0x54, 0x00, 0x00,
159 0x55, 0x00, 0x00,
160 0x56, 0x00, 0x00,
161 0x57, 0x00, 0x00,
162 0x60, 0x00, 0x00,
163 0x62, 0xf7, 0x08,
164 0x65, 0x00, 0xd9,
165 0x66, 0x00, 0x80,
166 0x67, 0x00, 0x50, /* OR 0x00 ?? */
167 0x69, 0xf0, 0x00,
168 0x6a, 0x00, 0x00,
169 0x6d, 0xcf, 0xc0,
170 0x6e, 0xff, 0x80,
171 0x75, 0x0f, 0x40,
172 0x77, 0x00, 0x00,
173 0x80, 0x00, 0x00,
174 0x81, 0x00, 0x00,
175 0x82, 0x00, 0x00,
176 0x83, 0x00, 0x00,
177 0x84, 0x00, 0x00,
178 0x85, 0x00, 0x00,
179 0x86, 0xff, 0x2c, /* OR 0x28 if we don't want enable top 1M SM memory */
180 0x40, 0x00, 0x00,
181 0x7c, 0x00, 0x00,
182 0x7e, 0x00, 0x00,
183 0xa4, 0xfe, 0x00,
184 0xb0, 0x7f, 0x80,
185 0xb1, 0x00, 0xaa,
186 0xb4, 0xfd, 0x02,
187 0xb8, 0xfe, 0x00,
188};
189
190static const u8 Dram_Driving_ODT_CTRL[] = {
191/* REG, VALUE */
192 0xd6, 0xa8,
193 0xd4, 0x80,
194 0xd0, 0x88,
195 0xd3, 0x01,
196 0xd8, 0x00,
197 0xda, 0x80,
198};
199
200#define Rank0_ODT 0x00
201#define Rank1_ODT 0x01
202#define Rank2_ODT 0x02
203#define Rank3_ODT 0x03
204#define NA_ODT 0x00
205#define NB_ODT_75ohm 0x00
206#define NB_ODT_150ohm 0x01
207#define DDR2_ODT_75ohm 0x20
208#define DDR2_ODT_150ohm 0x40
209
210static const u8 ODT_TBL[] = {
211/* RankMap, ODT Control Bits, DRAM & NB ODT setting */
212 0x01, ((NA_ODT << 6) | (NA_ODT << 4) | (NA_ODT << 2) | Rank0_ODT), (DDR2_ODT_150ohm | NB_ODT_75ohm),
213 0x03, ((NA_ODT << 6) | (NA_ODT << 4) | (Rank0_ODT << 2) | Rank1_ODT), (DDR2_ODT_150ohm | NB_ODT_75ohm),
214 0x04, ((NA_ODT << 6) | (Rank2_ODT << 4) | (NA_ODT << 2) | NA_ODT), (DDR2_ODT_150ohm | NB_ODT_75ohm),
215 0x05, ((NA_ODT << 6) | (Rank0_ODT << 4) | (NA_ODT << 2) | Rank2_ODT), (DDR2_ODT_75ohm | NB_ODT_150ohm),
216 0x07, ((NA_ODT << 6) | (Rank0_ODT << 4) | (Rank2_ODT << 2) | Rank2_ODT), (DDR2_ODT_75ohm | NB_ODT_150ohm),
217 0x0c, ((Rank2_ODT << 6) | (Rank3_ODT << 4) | (NA_ODT << 2) | NA_ODT), (DDR2_ODT_150ohm | NB_ODT_75ohm),
218 0x0d, ((Rank0_ODT << 6) | (Rank0_ODT << 4) | (NA_ODT << 2) | Rank2_ODT), (DDR2_ODT_75ohm | NB_ODT_150ohm),
219 0x0f, ((Rank0_ODT << 6) | (Rank0_ODT << 4) | (Rank2_ODT << 2) | Rank2_ODT), (DDR2_ODT_75ohm | NB_ODT_150ohm),
220};
221
222static const u8 DQS_DQ_TBL[] = {
223/* RxE0: DRAM Timing DQS */
224/* RxE2: DRAM Timing DQ */
225/* RxE0, RxE2 */
226 0xee, 0xba,
227 0xee, 0xba,
228 0xcc, 0xba,
229 0xcc, 0xba,
230};
231
232static const u8 Duty_Control_DDR2[] = {
233/* RxEC, RxED, RxEE, RXEF */
234 /* DDRII533 1~2 rank, DDRII400 */
235 0x84, 0x10, 0x00, 0x10,
236 /* DDRII533 3~4 rank */
237 0x44, 0x10, 0x00, 0x10,
238};
239
240static const u8 ChA_Clk_Phase_DDR2_Table[] = {
241/* Rx91, Rx92, Rx93 */
242 /* DDRII533 1 rank */
243 0x04, 0x05, 0x06,
244 /* DDRII533 2~4 rank */
245 0x04, 0x05, 0x05,
246 /* DDRII400 */
247 0x02, 0x04, 0x04,
248};
249
250static const u8 DQ_DQS_Table[] = {
251/* REG, VALUE */
252/* DRAM DQ/DQS Output Delay Control */
253 0xdc, 0x65,
254 0xdd, 0x01,
255 0xde, 0xc0,
256/* DRAM DQ/DQS input Capture Control */
257 0x78, 0x83,
258 0x79, 0x83,
259 0x7a, 0x00,
260};
261
262static const u8 DQSOChA_DDR2_Driving_Table[] = {
263/* Rx70, Rx71 */
264 /* DDRII533 1~2 rank */
265 0x00, 0x01,
266 /* DDRII533 3~4 rank */
267 0x03, 0x00,
268 /* DDRII400 1~2 rank */
269 0x00, 0x04,
270 /* DDRII400 3~4 rank */
271 0x00, 0x01,
272};
273
274/************************************************************************/
275/* Chipset Performance UP and other setting after DRAM Sizing Registers */
276/************************************************************************/
277static const u8 Dram_Table[] = {
278/* REG, AND, OR */
279 0x60, 0xff, 0x03,
280 0x66, 0xcf, 0x80,
281 0x68, 0x00, 0x00,
282 0x69, 0xfd, 0x03,
283 0x6e, 0xff, 0x01,
284 0x95, 0xff, 0x40,
285};
286
287static const u8 Host_Table[] = {
288/* REG, AND, OR */
289 0x51, 0x81, 0x7a,
290 0x55, 0xff, 0x06,
291 0x5e, 0x00, 0x88,
292 0x5d, 0xff, 0xb2,
293};
294
295static const u8 Init_Rank_Reg_Table[] = {
296 /* Rank Ending Address Registers */
297 0x40, 0x41, 0x42, 0x43,
298 /* Rank Beginning Address Registers */
299 0x48, 0x49, 0x4a, 0x4b,
300 /* Physical-to-Virtual Rank Mapping Registers */
301 0x54, 0x55,
302};
303
304static const u16 DDR2_MRS_table[] = {
305/* CL: 2, 3, 4, 5 */
306 0x150, 0x1d0, 0x250, 0x2d0, /* BL=4 ;Use 1X-bandwidth MA table to init DRAM */
307 0x158, 0x1d8, 0x258, 0x2d8, /* BL=8 ;Use 1X-bandwidth MA table to init DRAM */
308};
309
310#define MRS_DDR2_TWR2 ((0 << 15) | (0 << 20) | (1 << 12))
311#define MRS_DDR2_TWR3 ((0 << 15) | (1 << 20) | (0 << 12))
312#define MRS_DDR2_TWR4 ((0 << 15) | (1 << 20) | (1 << 12))
313#define MRS_DDR2_TWR5 ((1 << 15) | (0 << 20) | (0 << 12))
314static const u32 DDR2_Twr_table[] = {
315 MRS_DDR2_TWR2,
316 MRS_DDR2_TWR3,
317 MRS_DDR2_TWR4,
318 MRS_DDR2_TWR5,
319};
320
321static const u8 DQSI_Rate_Table[] = {
322 8, /* DDRII 200 */
323 8, /* DDRII 266 */
324 8, /* DDRII 333 */
325 7, /* DDRII 400 */
326 8, /* DDRII 533 */
327 8, /* DDRII 666 */
328};
329
330static const u8 REFC_Table[] = {
331 0x65, 0x32, /* DDRII 100 */
332 0x86, 0x43, /* DDRII 266 */
333 0xa8, 0x54, /* DDRII 333 */
334 0xca, 0x65, /* DDRII 400 */
335 0xca, 0x86, /* DDRII 533 */
336 0xca, 0xa8, /* DDRII 666 */
337};
Stefan Reinaueraeba92a2009-04-17 08:37:18 +0000338
339static void do_ram_command(const struct mem_controller *ctrl, u8 command)
340{
341 u8 reg;
342
343 reg = pci_read_config8(MEMCTRL, 0x6b);
344 reg &= 0xf8; /* Clear bits 2-0. */
345 reg |= command;
346 pci_write_config8(MEMCTRL, 0x6b, reg);
347
348 PRINTK_DEBUG(" Sending RAM command 0x%02x\n", reg);
349}
350
351// TODO factor out to another file
352static void c7_cpu_setup(const struct mem_controller *ctrl)
353{
354 u8 size, i;
355 size = sizeof(Reg_Val) / sizeof(Reg_Val[0]);
356 for (i = 0; i < size; i += 2)
357 pci_write_config8(HOSTCTRL, Reg_Val[i], Reg_Val[i + 1]);
358}
359
360static void ddr_detect(const struct mem_controller *ctrl)
361{
362 /* FIXME: Only supports 2 ranks per DIMM */
363 u8 val, rsize, dimm;
364 u8 nrank = 0;
365 u8 ndimm = 0;
366 u8 rmap = 0;
367 for (dimm = 0; dimm < DIMM_SOCKETS; dimm++) {
368 val = get_spd_data(ctrl, dimm, 0);
369 if ((val == 0x80) || (val == 0xff)) {
370 ndimm++;
371 rsize = get_spd_data(ctrl, dimm, SPD_RANK_SIZE);
372 /* unit is 128M */
373 rsize = (rsize << 3) | (rsize >> 5);
374 val =
375 get_spd_data(ctrl, dimm,
376 SPD_MOD_ATTRIB_RANK) & SPD_MOD_ATTRIB_RANK_NUM_MASK;
377 switch (val) {
378 case 1:
379 pci_write_config8(PCI_DEV(0, 0, 4), (SCRATCH_RANK_1 + (dimm << 1)),
380 rsize);
381 rmap |= (1 << ((dimm << 1) + 1));
382 nrank++;
383 case 0:
384 pci_write_config8(PCI_DEV(0, 0, 4), (SCRATCH_RANK_0 + (dimm << 1)),
385 rsize);
386 rmap |= (1 << (dimm << 1));
387 nrank++;
388 }
389 }
390 }
391 pci_write_config8(PCI_DEV(0, 0, 4), SCRATCH_DIMM_NUM, ndimm);
392 pci_write_config8(PCI_DEV(0, 0, 4), SCRATCH_RANK_NUM, nrank);
393 pci_write_config8(PCI_DEV(0, 0, 4), SCRATCH_RANK_MAP, rmap);
394}
395
396static void sdram_set_safe_values(const struct mem_controller *ctrl)
397{
398 /* The purpose of this function is to set initial values for the dram
399 * size and timings. It will be replaced with the SPD based function
400 * once the RAM commands are working with these values.
401 */
402 u8 regs, val, t, dimm;
403 u32 spds, tmp;
404
405 regs = pci_read_config8(MEMCTRL, 0x6c);
406 if (regs & (1 << 6))
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000407 printk(BIOS_DEBUG, "DDR2 Detected.\n");
Stefan Reinaueraeba92a2009-04-17 08:37:18 +0000408 else
409 die("ERROR: DDR1 memory detected but not supported by coreboot.\n");
410
411 /* Enable DDR2 */
412 regs |= (1 << 7);
413 pci_write_config8(MEMCTRL, 0x6c, regs);
414
415 /* SPD 5 # of ranks */
416 pci_write_config8(MEMCTRL, 0x6d, 0xc0);
417
418 /**********************************************/
419 /* Set DRAM Freq (DDR2 533) */
420 /**********************************************/
421 /* SPD 9 SDRAM Cycle Time */
422 GET_SPD(dimm, spds, regs, 9);
423
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000424 printk(BIOS_DEBUG, "\nDDRII ");
Stefan Reinaueraeba92a2009-04-17 08:37:18 +0000425 if (spds <= 0x3d) {
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000426 printk(BIOS_DEBUG, "533");
Stefan Reinaueraeba92a2009-04-17 08:37:18 +0000427 val = DDRII_533;
428 t = 38;
429 } else if (spds <= 0x50) {
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000430 printk(BIOS_DEBUG, "400");
Stefan Reinaueraeba92a2009-04-17 08:37:18 +0000431 val = DDRII_400;
432 t = 50;
433 } else if (spds <= 0x60) {
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000434 printk(BIOS_DEBUG, "333");
Stefan Reinaueraeba92a2009-04-17 08:37:18 +0000435 val = DDRII_333;
436 t = 60;
437 } else if (spds <= 0x75) {
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000438 printk(BIOS_DEBUG, "266");
Stefan Reinaueraeba92a2009-04-17 08:37:18 +0000439 val = DDRII_266;
440 t = 75;
441 } else {
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000442 printk(BIOS_DEBUG, "200");
Stefan Reinaueraeba92a2009-04-17 08:37:18 +0000443 val = DDRII_200;
444 t = 100;
445 }
446 /* To store DDRII frequence */
447 pci_write_config8(PCI_DEV(0, 0, 4), SCRATCH_DRAM_FREQ, val);
448
Stefan Reinauer14e22772010-04-27 06:56:47 +0000449 /* Manual reset and adjust DLL when DRAM change frequency
Stefan Reinaueraeba92a2009-04-17 08:37:18 +0000450 * This is a necessary sequence.
451 */
452 udelay(2000);
453 regs = pci_read_config8(MEMCTRL, 0x90);
454 regs |= 0x7;
455 pci_write_config8(MEMCTRL, 0x90, regs);
456 udelay(2000);
457 regs = pci_read_config8(MEMCTRL, 0x90);
458 regs &= ~0x7;
459 regs |= val;
460 pci_write_config8(MEMCTRL, 0x90, regs);
461 udelay(2000);
462 regs = pci_read_config8(MEMCTRL, 0x6b);
463 regs |= 0xc0;
464 regs &= ~0x10;
465 pci_write_config8(MEMCTRL, 0x6b, regs);
466 udelay(1);
467 regs |= 0x10;
468 pci_write_config8(MEMCTRL, 0x6b, regs);
469 udelay(1);
470 regs &= ~0xc0;
471 pci_write_config8(MEMCTRL, 0x6b, regs);
472 regs = pci_read_config8(MEMCTRL, 0x6f);
473 regs |= 0x1;
474 pci_write_config8(MEMCTRL, 0x6f, regs);
475
476 /**********************************************/
477 /* Set DRAM Timing Setting (DDR2 533) */
478 /**********************************************/
479 /* SPD 9 18 23 25 CAS Latency NB3DRAM_REG62[2:0] */
480 /* Read SPD byte 18 CAS Latency */
481 GET_SPD(dimm, spds, regs, SPD_CAS_LAT);
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000482 printk(BIOS_DEBUG, "\nCAS Supported ");
Stefan Reinaueraeba92a2009-04-17 08:37:18 +0000483 if (spds & SPD_CAS_LAT_2)
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000484 printk(BIOS_DEBUG, "2 ");
Stefan Reinaueraeba92a2009-04-17 08:37:18 +0000485 if (spds & SPD_CAS_LAT_3)
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000486 printk(BIOS_DEBUG, "3 ");
Stefan Reinaueraeba92a2009-04-17 08:37:18 +0000487 if (spds & SPD_CAS_LAT_4)
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000488 printk(BIOS_DEBUG, "4 ");
Stefan Reinaueraeba92a2009-04-17 08:37:18 +0000489 if (spds & SPD_CAS_LAT_5)
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000490 printk(BIOS_DEBUG, "5 ");
Stefan Reinaueraeba92a2009-04-17 08:37:18 +0000491 if (spds & SPD_CAS_LAT_6)
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000492 printk(BIOS_DEBUG, "6");
Stefan Reinaueraeba92a2009-04-17 08:37:18 +0000493
494 /* We don't consider CAS = 6, because CX700 doesn't support it */
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000495 printk(BIOS_DEBUG, "\n CAS:");
Stefan Reinaueraeba92a2009-04-17 08:37:18 +0000496 if (spds & SPD_CAS_LAT_5) {
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000497 printk(BIOS_DEBUG, "Starting at CL5");
Stefan Reinaueraeba92a2009-04-17 08:37:18 +0000498 val = 0x3;
499 /* See whether we can improve it */
500 GET_SPD(dimm, tmp, regs, SPD_CAS_LAT_MIN_X_1);
501 if ((spds & SPD_CAS_LAT_4) && (tmp < 0x50)) {
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000502 printk(BIOS_DEBUG, "\n... going to CL4");
Stefan Reinaueraeba92a2009-04-17 08:37:18 +0000503 val = 0x2;
504 }
505 GET_SPD(dimm, tmp, regs, SPD_CAS_LAT_MIN_X_2);
506 if ((spds & SPD_CAS_LAT_3) && (tmp < 0x50)) {
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000507 printk(BIOS_DEBUG, "\n... going to CL3");
Stefan Reinaueraeba92a2009-04-17 08:37:18 +0000508 val = 0x1;
509 }
510 } else {
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000511 printk(BIOS_DEBUG, "Starting at CL4");
Stefan Reinaueraeba92a2009-04-17 08:37:18 +0000512 val = 0x2;
513 GET_SPD(dimm, tmp, regs, SPD_CAS_LAT_MIN_X_1);
514 if ((spds & SPD_CAS_LAT_3) && (tmp < 0x50)) {
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000515 printk(BIOS_DEBUG, "\n... going to CL3");
Stefan Reinaueraeba92a2009-04-17 08:37:18 +0000516 val = 0x1;
517 }
518 GET_SPD(dimm, tmp, regs, SPD_CAS_LAT_MIN_X_2);
519 if ((spds & SPD_CAS_LAT_2) && (tmp < 0x50)) {
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000520 printk(BIOS_DEBUG, "\n... going to CL2");
Stefan Reinaueraeba92a2009-04-17 08:37:18 +0000521 val = 0x0;
522 }
523 }
524 regs = pci_read_config8(MEMCTRL, 0x62);
525 regs &= ~0x7;
526 regs |= val;
527 pci_write_config8(MEMCTRL, 0x62, regs);
528
529 /* SPD 27 Trp NB3DRAM_REG64[3:2] */
530 GET_SPD(dimm, spds, regs, SPD_TRP);
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000531 printk(BIOS_DEBUG, "\nTrp %d", spds);
Stefan Reinaueraeba92a2009-04-17 08:37:18 +0000532 spds >>= 2;
533 for (val = 2; val <= 5; val++) {
534 if (spds <= (val * t / 10)) {
535 val = val - 2;
536 break;
537 }
538 }
539 val <<= 2;
540 regs = pci_read_config8(MEMCTRL, 0x64);
541 regs &= ~0xc;
542 regs |= val;
543 pci_write_config8(MEMCTRL, 0x64, regs);
544
545 /* SPD 29 Trcd NB3DRAM_REG64[7:6] */
546 GET_SPD(dimm, spds, regs, SPD_TRCD);
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000547 printk(BIOS_DEBUG, "\nTrcd %d", spds);
Stefan Reinaueraeba92a2009-04-17 08:37:18 +0000548 spds >>= 2;
549 for (val = 2; val <= 5; val++) {
550 if (spds <= (val * t / 10)) {
551 val = val - 2;
552 break;
553 }
554 }
555 val <<= 6;
556 regs = pci_read_config8(MEMCTRL, 0x64);
557 regs &= ~0xc0;
558 regs |= val;
559 pci_write_config8(MEMCTRL, 0x64, regs);
560
561 /* SPD 30 Tras NB3DRAM_REG62[7:4] */
562 GET_SPD(dimm, spds, regs, SPD_TRAS);
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000563 printk(BIOS_DEBUG, "\nTras %d", spds);
Stefan Reinaueraeba92a2009-04-17 08:37:18 +0000564 for (val = 5; val <= 20; val++) {
565 if (spds <= (val * t / 10)) {
566 val = val - 5;
567 break;
568 }
569 }
570 val <<= 4;
571 regs = pci_read_config8(MEMCTRL, 0x62);
572 regs &= ~0xf0;
573 regs |= val;
574 pci_write_config8(MEMCTRL, 0x62, regs);
575
576 /* SPD 42 SPD 40 Trfc NB3DRAM_REG61[5:0] */
577 GET_SPD(dimm, spds, regs, SPD_TRFC);
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000578 printk(BIOS_DEBUG, "\nTrfc %d", spds);
Stefan Reinaueraeba92a2009-04-17 08:37:18 +0000579 tmp = spds;
580 GET_SPD(dimm, spds, regs, SPD_EX_TRC_TRFC);
581 if (spds & 0x1)
582 tmp += 256;
583 if (spds & 0xe)
584 tmp++;
585 for (val = 8; val <= 71; val++) {
586 if (tmp <= (val * t / 10)) {
587 val = val - 8;
588 break;
589 }
590 }
591 regs = pci_read_config8(MEMCTRL, 0x61);
592 regs &= ~0x3f;
593 regs |= val;
594 pci_write_config8(MEMCTRL, 0x61, regs);
595
596 /* SPD 28 Trrd NB3DRAM_REG63[7:6] */
597 GET_SPD(dimm, spds, regs, SPD_TRRD);
598 for (val = 2; val <= 5; val++) {
599 if (spds <= (val * t / 10)) {
600 val = val - 2;
601 break;
602 }
603 }
604 val <<= 6;
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000605 printk(BIOS_DEBUG, "\nTrrd val = 0x%x", val);
Stefan Reinaueraeba92a2009-04-17 08:37:18 +0000606 regs = pci_read_config8(MEMCTRL, 0x63);
607 regs &= ~0xc0;
608 regs |= val;
609 pci_write_config8(MEMCTRL, 0x63, regs);
610
611 /* SPD 36 Twr NB3DRAM_REG61[7:6] */
612 GET_SPD(dimm, spds, regs, SPD_TWR);
613 for (val = 2; val <= 5; val++) {
614 if (spds <= (val * t / 10)) {
615 val = val - 2;
616 break;
617 }
618 }
619 val <<= 6;
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000620 printk(BIOS_DEBUG, "\nTwr val = 0x%x", val);
Stefan Reinaueraeba92a2009-04-17 08:37:18 +0000621
622 regs = pci_read_config8(MEMCTRL, 0x61);
623 regs &= ~0xc0;
624 regs |= val;
625 pci_write_config8(MEMCTRL, 0x61, regs);
626
627 /* SPD 37 Twtr NB3DRAM_REG63[1] */
628 GET_SPD(dimm, spds, regs, SPD_TWTR);
629 spds >>= 2;
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000630 printk(BIOS_DEBUG, "\nTwtr 0x%x", spds);
Stefan Reinaueraeba92a2009-04-17 08:37:18 +0000631 if (spds <= (t * 2 / 10))
632 val = 0;
633 else
634 val = 1;
635 val <<= 1;
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000636 printk(BIOS_DEBUG, "\nTwtr val = 0x%x", val);
Stefan Reinaueraeba92a2009-04-17 08:37:18 +0000637
638 regs = pci_read_config8(MEMCTRL, 0x63);
639 regs &= ~0x2;
640 regs |= val;
641 pci_write_config8(MEMCTRL, 0x63, regs);
642
643 /* SPD 38 Trtp NB3DRAM_REG63[3] */
644 GET_SPD(dimm, spds, regs, SPD_TRTP);
645 spds >>= 2;
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000646 printk(BIOS_DEBUG, "\nTrtp 0x%x", spds);
Stefan Reinaueraeba92a2009-04-17 08:37:18 +0000647 if (spds <= (t * 2 / 10))
648 val = 0;
649 else
650 val = 1;
651 val <<= 3;
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000652 printk(BIOS_DEBUG, "\nTrtp val = 0x%x", val);
Stefan Reinaueraeba92a2009-04-17 08:37:18 +0000653
654 regs = pci_read_config8(MEMCTRL, 0x63);
655 regs &= ~0x8;
656 regs |= val;
657 pci_write_config8(MEMCTRL, 0x63, regs);
658
659 /**********************************************/
660 /* Set DRAM DRDY Setting */
661 /**********************************************/
662 /* Write slowest value to register */
663 tmp = sizeof(Host_Reg_Val) / sizeof(Host_Reg_Val[0]);
664 for (val = 0; val < tmp; val += 2)
665 pci_write_config8(HOSTCTRL, Host_Reg_Val[val], Host_Reg_Val[val + 1]);
666
667 /* F2_RX51[7]=0, disable DRDY timing */
668 regs = pci_read_config8(HOSTCTRL, 0x51);
669 regs &= ~0x80;
670 pci_write_config8(HOSTCTRL, 0x51, regs);
671
672 /**********************************************/
673 /* Set DRAM BurstLength */
674 /**********************************************/
675 regs = pci_read_config8(MEMCTRL, 0x6c);
676 for (dimm = 0; dimm < DIMM_SOCKETS; dimm++) {
677 if (pci_read_config8(PCI_DEV(0, 0, 4), (SCRATCH_REG_BASE + (dimm << 1)))) {
678 spds = get_spd_data(ctrl, dimm, 16);
679 if (!(spds & 0x8))
680 break;
681 }
682 }
683 if (dimm == 2)
684 regs |= 0x8;
685 pci_write_config8(MEMCTRL, 0x6c, regs);
686 val = pci_read_config8(HOSTCTRL, 0x54);
687 val &= ~0x10;
688 if (dimm == 2)
689 val |= 0x10;
690 pci_write_config8(HOSTCTRL, 0x54, val);
691
692 /**********************************************/
693 /* Set DRAM Driving Setting */
694 /**********************************************/
695 /* DRAM Timing ODT */
696 tmp = sizeof(Dram_Driving_ODT_CTRL) / sizeof(Dram_Driving_ODT_CTRL[0]);
697 for (val = 0; val < tmp; val += 2)
698 pci_write_config8(MEMCTRL, Dram_Driving_ODT_CTRL[val],
699 Dram_Driving_ODT_CTRL[val + 1]);
700
701 regs = pci_read_config8(PCI_DEV(0, 0, 4), SCRATCH_RANK_NUM);
702 val = pci_read_config8(MEMCTRL, 0xd5);
703 val &= ~0xaa;
704 switch (regs) {
705 case 3:
706 case 2:
707 val |= 0xa0;
708 break;
709 default:
710 val |= 0x80;
711 }
712 regs = pci_read_config8(PCI_DEV(0, 0, 4), SCRATCH_DIMM_NUM);
713 if (regs == 1)
714 val |= 0xa;
715 pci_write_config8(MEMCTRL, 0xd5, val);
716
717 regs = pci_read_config8(PCI_DEV(0, 0, 4), SCRATCH_DIMM_NUM);
718 val = pci_read_config8(MEMCTRL, 0xd6);
719 val &= ~0x2;
720 if (regs == 1)
721 val |= 0x2;
722 pci_write_config8(MEMCTRL, 0xd6, val);
723
724 regs = pci_read_config8(PCI_DEV(0, 0, 4), SCRATCH_RANK_MAP);
725 tmp = sizeof(ODT_TBL) / sizeof(ODT_TBL[0]);
726 for (val = 0; val < tmp; val += 3) {
727 if (regs == ODT_TBL[val]) {
728 pci_write_config8(MEMCTRL, 0xd8, ODT_TBL[val + 1]);
729 /* Store DRAM & NB ODT setting in d0f4_Rxd8 */
730 pci_write_config8(PCI_DEV(0, 0, 4), SCRATCH_DRAM_NB_ODT, ODT_TBL[val + 2]);
731 break;
732 }
733 }
734
735 pci_write_config8(MEMCTRL, 0xd9, 0x0a);
736 regs = pci_read_config8(PCI_DEV(0, 0, 4), SCRATCH_RANK_NUM);
737 regs--;
738 regs = regs << 1;
739 pci_write_config8(MEMCTRL, 0xe0, DQS_DQ_TBL[regs++]);
740 pci_write_config8(MEMCTRL, 0xe2, DQS_DQ_TBL[regs]);
741
742 /* DRAM Timing CS */
743 pci_write_config8(MEMCTRL, 0xe4, 0x66);
744
745 /* DRAM Timing MAA */
746 val = 0;
747 for (dimm = 0; dimm < DIMM_SOCKETS; dimm++) {
748 if (pci_read_config8(PCI_DEV(0, 0, 4), (SCRATCH_REG_BASE + (dimm << 1)))) {
749 spds = get_spd_data(ctrl, dimm, SPD_PRI_WIDTH);
750 spds = 64 / spds;
751 if (pci_read_config8
752 (PCI_DEV(0, 0, 4), (SCRATCH_REG_BASE + (dimm << 1) + 1)))
753 spds = spds << 1;
754 val += spds;
755 }
756 }
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000757 printk(BIOS_DEBUG, "\nchip #%d", val);
Stefan Reinaueraeba92a2009-04-17 08:37:18 +0000758 if (val > 18)
759 regs = 0xdb;
760 else
761 regs = 0x86;
762 pci_write_config8(MEMCTRL, 0xe8, regs);
763
764 /* DRAM Timing MAB */
765 pci_write_config8(MEMCTRL, 0xe9, 0x0);
766
767 /* DRAM Timing DCLK VT8454C always 0x66 */
768 pci_write_config8(MEMCTRL, 0xe6, 0xaa);
769
770 /**********************************************/
771 /* Set DRAM Duty Control */
772 /**********************************************/
773 regs = pci_read_config8(PCI_DEV(0, 0, 4), SCRATCH_RANK_NUM);
774 switch (regs) {
775 case 1:
776 case 2: /* 1~2 rank */
777 val = 0;
778 break;
779 case 3:
780 case 4: /* 3~4 rank */
781 regs = pci_read_config8(PCI_DEV(0, 0, 4), SCRATCH_DRAM_FREQ);
782 if (regs == DDRII_533)
783 val = 4;
784 else /* DDRII-400 */
785 val = 0;
786 break;
787 }
788 regs = 0xec;
789 for (t = 0; t < 4; t++) {
790 pci_write_config8(MEMCTRL, regs, Duty_Control_DDR2[val]);
791 regs++;
792 val++;
793 }
794
795 /**********************************************/
796 /* Set DRAM Clock Control */
797 /**********************************************/
798 /* Write Data Phase */
799 val = pci_read_config8(PCI_DEV(0, 0, 4), SCRATCH_DRAM_FREQ);
800 regs = pci_read_config8(MEMCTRL, 0x75);
801 regs &= 0xf0;
802 switch (val) {
803 case DDRII_533:
804 pci_write_config8(MEMCTRL, 0x74, 0x07);
805 regs |= 0x7;
806 break;
807 case DDRII_400:
808 default:
809 pci_write_config8(MEMCTRL, 0x74, 0x05);
810 regs |= 0x5;
811 break;
812 }
813 pci_write_config8(MEMCTRL, 0x75, regs);
814 pci_write_config8(MEMCTRL, 0x76, 0x80);
815
816 /* Clock Phase Control for FeedBack Mode */
817 regs = pci_read_config8(MEMCTRL, 0x90);
818// regs |= 0x80;
819 pci_write_config8(MEMCTRL, 0x90, regs);
820
821 regs = pci_read_config8(PCI_DEV(0, 0, 4), SCRATCH_DRAM_FREQ);
822 switch (regs) {
823 case DDRII_533:
824 regs = pci_read_config8(PCI_DEV(0, 0, 4), SCRATCH_RANK_NUM);
825 if (regs == 1)
826 val = 0;
827 else
828 val = 3;
829 break;
830 case DDRII_400:
831 default:
832 val = 6;
833 break;
834 }
835 regs = pci_read_config8(MEMCTRL, 0x91);
836 regs &= ~0xc0;
837 regs |= 0x80;
838 pci_write_config8(MEMCTRL, 0x91, regs);
839 regs = 0x91;
840 for (t = 0; t < 3; t++) {
841 dimm = pci_read_config8(MEMCTRL, regs);
842 dimm &= ~0x7;
843 dimm |= ChA_Clk_Phase_DDR2_Table[val];
844 pci_write_config8(MEMCTRL, regs, dimm);
845 regs++;
846 val++;
847 }
848
849 pci_write_config8(MEMCTRL, 0x97, 0x12);
850 pci_write_config8(MEMCTRL, 0x98, 0x33);
851
852 regs = pci_read_config8(PCI_DEV(0, 0, 4), SCRATCH_RANK_0);
853 val = pci_read_config8(PCI_DEV(0, 0, 4), SCRATCH_RANK_2);
854 if (regs && val)
855 pci_write_config8(MEMCTRL, 0x9d, 0x00);
856 else
857 pci_write_config8(MEMCTRL, 0x9d, 0x0f);
858
859 tmp = sizeof(DQ_DQS_Table) / sizeof(DQ_DQS_Table[0]);
860 for (val = 0; val < tmp; val += 2)
861 pci_write_config8(MEMCTRL, DQ_DQS_Table[val], DQ_DQS_Table[val + 1]);
862 regs = pci_read_config8(PCI_DEV(0, 0, 4), SCRATCH_DRAM_FREQ);
863 if (regs == DDRII_533)
864 pci_write_config8(MEMCTRL, 0x7b, 0xa0);
865 else
866 pci_write_config8(MEMCTRL, 0x7b, 0x10);
867
868 /***************************************************/
869 /* Set necessary register before DRAM initialize */
870 /***************************************************/
871 tmp = sizeof(Mem_Reg_Init) / sizeof(Mem_Reg_Init[0]);
872 for (val = 0; val < tmp; val += 3) {
873 regs = pci_read_config8(MEMCTRL, Mem_Reg_Init[val]);
874 regs &= Mem_Reg_Init[val + 1];
875 regs |= Mem_Reg_Init[val + 2];
876 pci_write_config8(MEMCTRL, Mem_Reg_Init[val], regs);
877 }
878 regs = pci_read_config8(HOSTCTRL, 0x51);
879 regs &= 0xbf; // Clear bit 6 Disable Read Around Write
880 pci_write_config8(HOSTCTRL, 0x51, regs);
881
882 regs = pci_read_config8(HOSTCTRL, 0x54);
883 t = regs >> 5;
884 val = pci_read_config8(HOSTCTRL, 0x57);
885 dimm = val >> 5;
886 if (t == dimm)
887 t = 0x0;
888 else
889 t = 0x1;
890 regs &= ~0x1;
891 regs |= t;
892 val &= ~0x1;
893 val |= t;
894 pci_write_config8(HOSTCTRL, 0x57, val);
895
896 regs = pci_read_config8(HOSTCTRL, 0x51);
897 regs |= t;
898 pci_write_config8(HOSTCTRL, 0x51, regs);
899
900 regs = pci_read_config8(MEMCTRL, 0x90);
901 regs &= 0x7;
902 val = 0;
903 if (regs < 0x2)
904 val = 0x80;
905 regs = pci_read_config8(MEMCTRL, 0x76);
906 regs &= 0x80;
907 regs |= val;
908 pci_write_config8(MEMCTRL, 0x76, regs);
909
910 regs = pci_read_config8(MEMCTRL, 0x6f);
911 regs |= 0x10;
912 pci_write_config8(MEMCTRL, 0x6f, regs);
913
914 /***************************************************/
915 /* Find suitable DQS value for ChA and ChB */
916 /***************************************************/
917 // Set DQS output delay for Channel A
918 regs = pci_read_config8(PCI_DEV(0, 0, 4), SCRATCH_DRAM_FREQ);
919 val = pci_read_config8(PCI_DEV(0, 0, 4), SCRATCH_RANK_NUM);
920 switch (regs) {
921 case DDRII_533:
922 if (val < 2)
923 val = 0;
924 else
925 val = 2;
926 break;
927 case DDRII_400:
928 default:
929 if (val < 2)
930 val = 4;
931 else
932 val = 6;
933 break;
934 }
935 for (t = 0; t < 2; t++)
936 pci_write_config8(MEMCTRL, (0x70 + t), DQSOChA_DDR2_Driving_Table[val + t]);
937 // Set DQS output delay for Channel B
938 pci_write_config8(MEMCTRL, 0x72, 0x0);
939
940 regs = pci_read_config8(PCI_DEV(0, 0, 4), SCRATCH_RANK_0);
941 val = pci_read_config8(PCI_DEV(0, 0, 4), SCRATCH_RANK_2);
942 if (regs && val)
943 pci_write_config8(MEMCTRL, 0x73, 0xfd);
944 else
945 pci_write_config8(MEMCTRL, 0x73, 0x01);
946}
947
948static void sdram_set_registers(const struct mem_controller *ctrl)
949{
950 c7_cpu_setup(ctrl);
951 ddr_detect(ctrl);
952 sdram_set_safe_values(ctrl);
953}
954
955static void step_20_21(const struct mem_controller *ctrl)
956{
957 u8 val;
958
959 // Step 20
960 udelay(200);
961
962 val = pci_read_config8(PCI_DEV(0, 0, 4), SCRATCH_DRAM_NB_ODT);
963 if (val & DDR2_ODT_150ohm)
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -0800964 read32((void *)0x102200);
Stefan Reinaueraeba92a2009-04-17 08:37:18 +0000965 else
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -0800966 read32((void *)0x102020);
Stefan Reinaueraeba92a2009-04-17 08:37:18 +0000967
968 /* Step 21. Normal operation */
Stefan Reinauer65b72ab2015-01-05 12:59:54 -0800969 printk(BIOS_SPEW, "RAM Enable 5: Normal operation\n");
Stefan Reinaueraeba92a2009-04-17 08:37:18 +0000970 do_ram_command(ctrl, RAM_COMMAND_NORMAL);
971 udelay(3);
972}
973
974static void step_2_19(const struct mem_controller *ctrl)
975{
976 u32 i;
977 u8 val;
978
979 // Step 2
980 val = pci_read_config8(MEMCTRL, 0x69);
981 val &= ~0x03;
982 pci_write_config8(MEMCTRL, 0x69, val);
983
984 /* Step 3 Apply NOP. */
Stefan Reinauer65b72ab2015-01-05 12:59:54 -0800985 printk(BIOS_SPEW, "RAM Enable 1: Apply NOP\n");
Stefan Reinaueraeba92a2009-04-17 08:37:18 +0000986 do_ram_command(ctrl, RAM_COMMAND_NOP);
987
988 udelay(15);
989
990 // Step 4
Stefan Reinauer65b72ab2015-01-05 12:59:54 -0800991 printk(BIOS_SPEW, "SEND: ");
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -0800992 read32((void *)0);
Stefan Reinauer65b72ab2015-01-05 12:59:54 -0800993 printk(BIOS_SPEW, "OK\n");
Stefan Reinaueraeba92a2009-04-17 08:37:18 +0000994
995 // Step 5
996 udelay(400);
997
998 /* 6. Precharge all. Wait tRP. */
Stefan Reinauer65b72ab2015-01-05 12:59:54 -0800999 printk(BIOS_SPEW, "RAM Enable 2: Precharge all\n");
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001000 do_ram_command(ctrl, RAM_COMMAND_PRECHARGE);
1001
1002 // Step 7
Stefan Reinauer65b72ab2015-01-05 12:59:54 -08001003 printk(BIOS_SPEW, "SEND: ");
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -08001004 read32((void *)0);
Stefan Reinauer65b72ab2015-01-05 12:59:54 -08001005 printk(BIOS_SPEW, "OK\n");
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001006
1007 /* Step 8. Mode register set. */
Stefan Reinauer65b72ab2015-01-05 12:59:54 -08001008 printk(BIOS_SPEW, "RAM Enable 4: Mode register set\n");
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001009 do_ram_command(ctrl, RAM_COMMAND_MRS); //enable dll
1010
1011 // Step 9
Stefan Reinauer65b72ab2015-01-05 12:59:54 -08001012 printk(BIOS_SPEW, "SEND: ");
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001013
1014 val = pci_read_config8(PCI_DEV(0, 0, 4), SCRATCH_DRAM_NB_ODT);
1015 if (val & DDR2_ODT_150ohm)
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -08001016 read32((void *)0x102200); //DDR2_ODT_150ohm
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001017 else
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -08001018 read32((void *)0x102020);
Stefan Reinauer65b72ab2015-01-05 12:59:54 -08001019 printk(BIOS_SPEW, "OK\n");
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001020
1021 // Step 10
Stefan Reinauer65b72ab2015-01-05 12:59:54 -08001022 printk(BIOS_SPEW, "SEND: ");
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -08001023 read32((void *)0x800);
Stefan Reinauer65b72ab2015-01-05 12:59:54 -08001024 printk(BIOS_SPEW, "OK\n");
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001025
1026 /* Step 11. Precharge all. Wait tRP. */
Stefan Reinauer65b72ab2015-01-05 12:59:54 -08001027 printk(BIOS_SPEW, "RAM Enable 2: Precharge all\n");
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001028 do_ram_command(ctrl, RAM_COMMAND_PRECHARGE);
1029
1030 // Step 12
Stefan Reinauer65b72ab2015-01-05 12:59:54 -08001031 printk(BIOS_SPEW, "SEND: ");
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -08001032 read32((u32 *)0x0);
Stefan Reinauer65b72ab2015-01-05 12:59:54 -08001033 printk(BIOS_SPEW, "OK\n");
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001034
1035 /* Step 13. Perform 8 refresh cycles. Wait tRC each time. */
Stefan Reinauer65b72ab2015-01-05 12:59:54 -08001036 printk(BIOS_SPEW, "RAM Enable 3: CBR\n");
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001037 do_ram_command(ctrl, RAM_COMMAND_CBR);
1038
1039 /* JEDEC says only twice, do 8 times for posterity */
1040 // Step 16: Repeat Step 14 and 15 another 7 times
1041 for (i = 0; i < 8; i++) {
1042 // Step 14
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -08001043 read32((u32 *)0);
Stefan Reinauer65b72ab2015-01-05 12:59:54 -08001044 printk(BIOS_SPEW, ".");
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001045
1046 // Step 15
1047 udelay(100);
1048 }
1049
1050 /* Step 17. Mode register set. Wait 200us. */
Stefan Reinauer65b72ab2015-01-05 12:59:54 -08001051 printk(BIOS_SPEW, "\nRAM Enable 4: Mode register set\n");
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001052
1053 //safe value for now, BL=8, WR=4, CAS=4
1054 do_ram_command(ctrl, RAM_COMMAND_MRS);
1055 udelay(200);
1056
1057 /* Use Single Chanel temporarily */
1058 val = pci_read_config8(MEMCTRL, 0x6c);
1059 if (val & 0x8) { /* Burst Length = 8 */
1060 val = pci_read_config8(MEMCTRL, 0x62);
1061 val &= 0x7;
1062 i = DDR2_MRS_table[4 + val];
1063 } else {
1064 val = pci_read_config8(MEMCTRL, 0x62);
1065 val &= 0x7;
1066 i = DDR2_MRS_table[val];
1067 }
1068
1069 // Step 18
1070 val = pci_read_config8(MEMCTRL, 0x61);
1071 val = val >> 6;
1072 i |= DDR2_Twr_table[val];
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -08001073 read32((void *)i);
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001074
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +00001075 printk(BIOS_DEBUG, "MRS = %08x\n", i);
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001076
1077 udelay(15);
1078
1079 // Step 19
1080 val = pci_read_config8(PCI_DEV(0, 0, 4), SCRATCH_DRAM_NB_ODT);
1081 if (val & DDR2_ODT_150ohm)
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -08001082 read32((void *)0x103e00); //EMRS OCD Default
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001083 else
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -08001084 read32((void *)0x103c20);
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001085}
1086
1087static void sdram_set_vr(const struct mem_controller *ctrl, u8 num)
1088{
1089 u8 reg, val;
1090 val = 0x54 + (num >> 1);
1091 reg = pci_read_config8(MEMCTRL, val);
1092 reg &= (0xf << (4 * (num & 0x1)));
1093 reg |= (((0x8 | num) << 4) >> (4 * (num & 0x1)));
1094 pci_write_config8(MEMCTRL, val, reg);
1095}
1096static void sdram_ending_addr(const struct mem_controller *ctrl, u8 num)
1097{
1098 u8 reg, val;
1099 /* Set Ending Address */
1100 val = 0x40 + num;
1101 reg = pci_read_config8(MEMCTRL, val);
1102 reg += 0x10;
1103 pci_write_config8(MEMCTRL, val, reg);
1104 /* Set Beginning Address */
1105 val = 0x48 + num;
1106 pci_write_config8(MEMCTRL, val, 0x0);
1107}
1108
1109static void sdram_clear_vr_addr(const struct mem_controller *ctrl, u8 num)
1110{
1111 u8 reg, val;
1112 val = 0x54 + (num >> 1);
1113 reg = pci_read_config8(MEMCTRL, val);
1114 reg = ~(0x80 >> (4 * (num & 0x1)));
1115 pci_write_config8(MEMCTRL, val, reg);
1116 val = 0x40 + num;
1117 reg = pci_read_config8(MEMCTRL, val);
1118 reg -= 0x10;
1119 pci_write_config8(MEMCTRL, val, reg);
1120 val = 0x48 + num;
1121 pci_write_config8(MEMCTRL, val, 0x0);
1122}
1123
1124/* Perform sizing DRAM by dynamic method */
1125static void sdram_calc_size(const struct mem_controller *ctrl, u8 num)
1126{
1127 u8 ca, ra, ba, reg;
1128 ba = pci_read_config8(PCI_DEV(0, 0, 4), SCRATCH_FLAGS);
1129 if (ba == 8) {
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -08001130 write8((void *)0, 0x0d);
1131 ra = read8((void *)0);
1132 write8((void *)(1 << SDRAM1X_RA_12_8bk), 0x0c);
1133 ra = read8((void *)0);
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001134
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -08001135 write8((void *)0, 0x0a);
1136 ca = read8((void *)0);
1137 write8((void *)(1 << SDRAM1X_CA_09_8bk), 0x0c);
1138 ca = read8((void *)0);
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001139
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -08001140 write8((void *)0, 0x03);
1141 ba = read8((void *)0);
1142 write8((void *)(1 << SDRAM1X_BA2_8bk), 0x02);
1143 ba = read8((void *)0);
1144 write8((void *)(1 << SDRAM1X_BA1_8bk), 0x01);
1145 ba = read8((void *)0);
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001146 } else {
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -08001147 write8((void *)0, 0x0f);
1148 ra = read8((void *)0);
1149 write8((void *)(1 << SDRAM1X_RA_14), 0x0e);
1150 ra = read8((void *)0);
1151 write8((void *)(1 << SDRAM1X_RA_13), 0x0d);
1152 ra = read8((void *)0);
1153 write8((void *)(1 << SDRAM1X_RA_12), 0x0c);
1154 ra = read8((void *)0);
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001155
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -08001156 write8((void *)0, 0x0c);
1157 ca = read8((void *)0);
1158 write8((void *)(1 << SDRAM1X_CA_12), 0x0b);
1159 ca = read8((void *)0);
1160 write8((void *)(1 << SDRAM1X_CA_11), 0x0a);
1161 ca = read8((void *)0);
1162 write8((void *)(1 << SDRAM1X_CA_09), 0x09);
1163 ca = read8((void *)0);
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001164
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -08001165 write8((void *)0, 0x02);
1166 ba = read8((void *)0);
1167 write8((void *)(1 << SDRAM1X_BA1), 0x01);
1168 ba = read8((void *)0);
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001169 }
1170
1171 if (ra < 10 || ra > 15)
1172 die("bad RA");
1173 if (ca < 8 || ca > 12)
1174 die("bad CA");
1175 if (ba < 1 || ba > 3)
1176 die("bad BA");
1177
1178 /* Calculate MA type save to scratch register */
1179 reg = 0;
1180
1181 switch (ra) {
1182 case 12:
1183 reg |= MA_12_Row;
1184 break;
1185 case 13:
1186 reg |= MA_13_Row;
1187 break;
1188 case 14:
1189 reg |= MA_14_Row;
1190 break;
1191 default:
1192 reg |= MA_15_Row;
1193 }
1194
1195 switch (ca) {
1196 case 9:
1197 reg |= MA_9_Column;
1198 break;
1199 case 10:
1200 reg |= MA_10_Column;
1201 break;
1202 case 11:
1203 reg |= MA_11_Column;
1204 break;
1205 default:
1206 reg |= MA_12_Column;
1207 }
1208
1209 switch (ba) {
1210 case 3:
1211 reg |= MA_8_Bank;
1212 break;
1213 default:
1214 reg |= MA_4_Bank;
1215 }
1216
1217 pci_write_config8(PCI_DEV(0, 0, 4), (SCRATCH_RANK0_MA_REG + num), reg);
1218
1219 if (ra >= 13)
1220 pci_write_config8(PCI_DEV(0, 0, 4), SCRATCH_DRAM_256M_BIT, 1);
1221
1222 /* Calculate rank size save to scratch register */
1223 ra = ra + ca + ba + 3 - 26; /* 1 unit = 64M */
1224 ra = 1 << ra;
1225 pci_write_config8(PCI_DEV(0, 0, 4), (SCRATCH_RANK0_SIZE_REG + num), ra);
1226}
1227
1228static void sdram_enable(const struct mem_controller *ctrl)
1229{
1230 u8 reg8;
1231 u8 val, i;
1232 device_t dev;
1233 u8 dl, dh;
1234 u32 quot;
1235
1236 /* Init Present Bank */
1237 val = sizeof(Init_Rank_Reg_Table) / sizeof(Init_Rank_Reg_Table[0]);
1238 for (i = 0; i < val; i++)
1239 pci_write_config8(MEMCTRL, Init_Rank_Reg_Table[i], 0x0);
1240
1241 /* Init other banks */
1242 for (i = 0; i < 4; i++) {
1243 reg8 = pci_read_config8(PCI_DEV(0, 0, 4), (SCRATCH_RANK_0 + i));
1244 if (reg8) {
1245 sdram_set_vr(ctrl, i);
1246 sdram_ending_addr(ctrl, i);
1247 step_2_19(ctrl);
1248 step_20_21(ctrl);
1249 sdram_clear_vr_addr(ctrl, i);
1250 }
1251 }
1252
Patrick Georgidd4390b2015-10-31 16:12:51 +01001253 if (IS_ENABLED(MEM_WIDTH_32BIT_MODE)) {
1254 /********************************************************/
1255 /* Set Dram 32bit Mode */
1256 /********************************************************/
1257 reg8 = pci_read_config8(MEMCTRL, 0x6c);
1258 reg8 |= 0x20;
1259 pci_write_config8(MEMCTRL, 0x6c, reg8);
1260 }
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001261
1262 /****************************************************************/
1263 /* Find the DQSI Low/High bound and save it to Scratch register */
1264 /****************************************************************/
1265 for (dl = 0; dl < 0x3f; dl += 2) {
1266 reg8 = dl & 0x3f;
1267 reg8 |= 0x80; /* Set Manual Mode */
1268 pci_write_config8(MEMCTRL, 0x77, reg8);
1269 for (i = 0; i < 4; i++) {
1270 reg8 = pci_read_config8(PCI_DEV(0, 0, 4), (SCRATCH_RANK_0 + i));
1271 if (reg8) {
1272 sdram_set_vr(ctrl, i);
1273 sdram_ending_addr(ctrl, i);
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -08001274 write32((void *)0, 0x55555555);
1275 write32((void *)4, 0x55555555);
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001276 udelay(15);
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -08001277 if (read32((void *)0) != 0x55555555)
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001278 break;
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -08001279 if (read32((void *)4) != 0x55555555)
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001280 break;
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -08001281 write32((void *)0, 0xaaaaaaaa);
1282 write32((void *)4, 0xaaaaaaaa);
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001283 udelay(15);
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -08001284 if (read32((void *)0) != 0xaaaaaaaa)
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001285 break;
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -08001286 if (read32((void *)4) != 0xaaaaaaaa)
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001287 break;
1288 sdram_clear_vr_addr(ctrl, i);
1289 }
1290 }
1291 if (i == 4)
1292 break;
1293 else
1294 sdram_clear_vr_addr(ctrl, i);
1295 }
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +00001296 printk(BIOS_DEBUG, "\nDQSI Low %08x", dl);
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001297 for (dh = dl; dh < 0x3f; dh += 2) {
1298 reg8 = dh & 0x3f;
1299 reg8 |= 0x80; /* Set Manual Mode */
1300 pci_write_config8(MEMCTRL, 0x77, reg8);
1301 for (i = 0; i < 4; i++) {
1302 reg8 = pci_read_config8(PCI_DEV(0, 0, 4), (SCRATCH_RANK_0 + i));
1303 if (reg8) {
1304 sdram_set_vr(ctrl, i);
1305 sdram_ending_addr(ctrl, i);
1306
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -08001307 write32((void *)0, 0x55555555);
1308 write32((void *)4, 0x55555555);
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001309 udelay(15);
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -08001310 if (read32((void *)0) != 0x55555555)
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001311 break;
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -08001312 if (read32((void *)4) != 0x55555555)
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001313 break;
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -08001314 write32((void *)0, 0xaaaaaaaa);
1315 write32((void *)4, 0xaaaaaaaa);
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001316 udelay(15);
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -08001317 if (read32((void *)0) != 0xaaaaaaaa)
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001318 break;
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -08001319 if (read32((void *)4) != 0xaaaaaaaa)
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001320 break;
1321 sdram_clear_vr_addr(ctrl, i);
1322 }
1323 }
1324 if (i != 4) {
1325 sdram_clear_vr_addr(ctrl, i);
1326 break;
1327 }
1328 }
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +00001329 printk(BIOS_DEBUG, "\nDQSI High %02x", dh);
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001330 pci_write_config8(PCI_DEV(0, 0, 4), SCRATCH_CHA_DQSI_LOW_REG, dl);
1331 pci_write_config8(PCI_DEV(0, 0, 4), SCRATCH_CHA_DQSI_HIGH_REG, dh);
1332 reg8 = pci_read_config8(MEMCTRL, 0X90) & 0X7;
1333 val = DQSI_Rate_Table[reg8];
1334 quot = dh - dl;
1335 quot = quot * val;
1336 quot >>= 4;
1337 val = quot + dl;
1338 pci_write_config8(PCI_DEV(0, 0, 4), SCRATCH_ChA_DQSI_REG, val);
1339 reg8 = val & 0x3f;
1340 reg8 |= 0x80;
1341 pci_write_config8(MEMCTRL, 0x77, reg8);
1342
1343 /****************************************************************/
1344 /* Find out the lowest Bank Interleave and Set Register */
1345 /****************************************************************/
1346#if 0
1347 //TODO
1348 reg8 = pci_read_config8(MEMCTRL, 0x69);
1349 reg8 &= ~0xc0;
1350 reg8 |= 0x80; //8 banks
1351 pci_write_config8(MEMCTRL, 0x69, reg8);
1352#endif
1353 dl = 2;
1354 for (i = 0; i < 4; i++) {
1355 reg8 = pci_read_config8(PCI_DEV(0, 0, 4), (SCRATCH_RANK_0 + i));
1356 if (reg8) {
1357 reg8 = get_spd_data(ctrl, (i >> 1), 17);
1358 sdram_set_vr(ctrl, i);
1359 sdram_ending_addr(ctrl, i);
1360 if (reg8 == 4) {
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -08001361 write8((void *)0, 0x02);
1362 val = read8((void *)0);
1363 write8((void *)(1 << SDRAM1X_BA1), 0x01);
1364 val = read8((void *)0);
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001365 } else {
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -08001366 write8((void *)0, 0x03);
1367 val = read8((void *)0);
1368 write8((void *)(1 << SDRAM1X_BA2_8bk), 0x02);
1369 val = read8((void *)0);
1370 write8((void *)(1 << SDRAM1X_BA1_8bk), 0x01);
1371 val = read8((void *)0);
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001372 }
1373 if (val < dl)
1374 dl = val;
1375 sdram_clear_vr_addr(ctrl, i);
1376 }
1377 }
1378 dl <<= 6;
1379 reg8 = pci_read_config8(MEMCTRL, 0x69);
1380 reg8 &= ~0xc0;
1381 reg8 |= dl;
1382 pci_write_config8(MEMCTRL, 0x69, reg8);
1383
1384 /****************************************************************/
1385 /* DRAM Sizing and Fill MA type */
1386 /****************************************************************/
1387 for (i = 0; i < 4; i++) {
1388 val = pci_read_config8(PCI_DEV(0, 0, 4), (SCRATCH_RANK_0 + i));
1389 if (val) {
1390 reg8 = get_spd_data(ctrl, (i >> 1), 17);
1391 pci_write_config8(PCI_DEV(0, 0, 4), SCRATCH_FLAGS, reg8);
1392 if (reg8 == 4) {
1393 /* Use MA Type 3 for DRAM sizing */
1394 reg8 = pci_read_config8(MEMCTRL, 0x50);
1395 reg8 &= 0x11;
1396 reg8 |= 0x66;
1397 pci_write_config8(MEMCTRL, 0x50, reg8);
1398 pci_write_config8(MEMCTRL, 0x51, reg8);
1399 } else {
1400 /* Use MA Type 5 for DRAM sizing */
1401 reg8 = pci_read_config8(MEMCTRL, 0x50);
1402 reg8 &= 0x11;
1403 reg8 |= 0xaa;
1404 pci_write_config8(MEMCTRL, 0x50, reg8);
1405 pci_write_config8(MEMCTRL, 0x51, reg8);
1406 reg8 = pci_read_config8(MEMCTRL, 0x53);
1407 reg8 &= 0x0f;
1408 reg8 |= 0x90;
1409 pci_write_config8(MEMCTRL, 0x53, reg8);
1410 }
1411 sdram_set_vr(ctrl, i);
1412 val = 0x40 + i;
1413 reg8 = pci_read_config8(MEMCTRL, val);
1414 /* max size 3G for new MA table */
1415 reg8 += 0x30;
1416 pci_write_config8(MEMCTRL, val, reg8);
1417 /* Set Beginning Address */
1418 val = 0x48 + i;
1419 pci_write_config8(MEMCTRL, val, 0x0);
1420
1421 sdram_calc_size(ctrl, i);
1422
1423 /* Clear */
1424 val = 0x54 + (i >> 1);
1425 reg8 = pci_read_config8(MEMCTRL, val);
1426 reg8 = ~(0x80 >> (4 * (i & 0x1)));
1427 pci_write_config8(MEMCTRL, val, reg8);
1428 val = 0x40 + i;
1429 reg8 = pci_read_config8(MEMCTRL, val);
1430 reg8 -= 0x30;
1431 pci_write_config8(MEMCTRL, val, reg8);
1432 val = 0x48 + i;
1433 pci_write_config8(MEMCTRL, val, 0x0);
1434
1435 }
1436 }
1437 /* Clear MA Type */
1438 reg8 = pci_read_config8(MEMCTRL, 0x50);
1439 reg8 &= 0x11;
1440 pci_write_config8(MEMCTRL, 0x50, reg8);
1441 pci_write_config8(MEMCTRL, 0x51, reg8);
1442 reg8 = pci_read_config8(MEMCTRL, 0x6b);
1443 reg8 &= ~0x08;
1444 pci_write_config8(MEMCTRL, 0x6b, reg8);
1445
1446 /****************************************************************/
1447 /* DRAM re-initialize for burst length */
1448 /****************************************************************/
1449 for (i = 0; i < 4; i++) {
1450 reg8 = pci_read_config8(PCI_DEV(0, 0, 4), (SCRATCH_RANK_0 + i));
1451 if (reg8) {
1452 sdram_set_vr(ctrl, i);
1453 sdram_ending_addr(ctrl, i);
1454 step_2_19(ctrl);
1455 step_20_21(ctrl);
1456 sdram_clear_vr_addr(ctrl, i);
1457 }
1458 }
1459
1460 /****************************************************************/
1461 /* Set the MA Type */
1462 /****************************************************************/
1463 reg8 = pci_read_config8(MEMCTRL, 0x50);
1464 reg8 &= 0x11;
1465 pci_write_config8(MEMCTRL, 0x50, reg8);
1466
1467 reg8 = pci_read_config8(MEMCTRL, 0x51);
1468 reg8 &= 0x11;
1469 pci_write_config8(MEMCTRL, 0x51, reg8);
1470
1471 reg8 = pci_read_config8(MEMCTRL, 0x6b);
1472 reg8 &= ~0x08;
1473 pci_write_config8(MEMCTRL, 0x6b, reg8);
1474
1475 for (i = 0; i < 4; i += 2) {
1476 reg8 = pci_read_config8(PCI_DEV(0, 0, 4), (SCRATCH_RANK_0 + i));
1477 if (reg8) {
1478 reg8 = pci_read_config8(PCI_DEV(0, 0, 4), (SCRATCH_RANK0_MA_REG + i));
1479 reg8 &= (MA_Bank + MA_Column);
1480 val = pci_read_config8(MEMCTRL, 0x50);
1481 if (i == 0) {
1482 reg8 <<= 4;
1483 val &= 0x1f;
1484 } else
1485 val &= 0xf1;
1486 val |= reg8;
1487 pci_write_config8(MEMCTRL, 0x50, val);
1488 }
1489 }
1490
1491 /****************************************************************/
1492 /* Set Start and Ending Address */
1493 /****************************************************************/
1494 dl = 0; /* Begin Address */
1495 dh = 0; /* Ending Address */
1496 for (i = 0; i < 4; i++) {
1497 reg8 = pci_read_config8(PCI_DEV(0, 0, 4), (SCRATCH_RANK_0 + i));
1498 if (reg8) {
1499 reg8 = pci_read_config8(PCI_DEV(0, 0, 4), (SCRATCH_RANK0_SIZE_REG + i));
1500 if (reg8 == 0)
1501 continue;
1502 dh += reg8;
1503 pci_write_config8(MEMCTRL, (0x40 + i), dh);
1504 pci_write_config8(MEMCTRL, (0x48 + i), dl);
1505 dl = dh;
1506 }
1507 }
1508 dh <<= 2;
1509 // F7_Rx57 Ending address mirror register
1510 pci_write_config8(PCI_DEV(0, 0, 7), 0x57, dh);
1511 dev = pci_locate_device(PCI_ID(0x1106, 0x324e), 0);
1512 pci_write_config8(dev, 0x57, dh);
1513 // LOW TOP Address
1514 pci_write_config8(MEMCTRL, 0x88, dh);
1515 pci_write_config8(MEMCTRL, 0x85, dh);
1516 // also program vlink mirror
1517 pci_write_config8(PCI_DEV(0, 0, 7), 0xe5, dh);
1518
1519 /****************************************************************/
1520 /* Set Physical to Virtual Rank mapping */
1521 /****************************************************************/
1522 pci_write_config32(MEMCTRL, 0x54, 0x0);
1523 for (i = 0; i < 4; i++) {
1524 reg8 = pci_read_config8(PCI_DEV(0, 0, 4), (SCRATCH_RANK_0 + i));
1525 if (reg8) {
1526 reg8 = pci_read_config8(MEMCTRL, (0x54 + (i >> 1)));
1527 if (i & 0x1) { /* Odd Rank */
1528 reg8 &= 0xf0;
1529 reg8 |= (0x8 | i);
1530 } else { /* Even Rank */
1531
1532 reg8 &= 0x0f;
1533 reg8 |= ((0x8 | i) << 4);
1534 }
1535 pci_write_config8(MEMCTRL, (0x54 + (i >> 1)), reg8);
1536 }
1537 }
1538
1539 /****************************************************************/
1540 /* Set DRAM Refresh Counter */
1541 /****************************************************************/
1542 val = pci_read_config8(MEMCTRL, 0X90) & 0X7;
1543 val <<= 1;
1544 reg8 = pci_read_config8(PCI_DEV(0, 0, 4), SCRATCH_DRAM_256M_BIT);
1545 if (reg8)
1546 val++;
1547 pci_write_config8(MEMCTRL, 0x6a, REFC_Table[val]);
1548
1549 /****************************************************************/
1550 /* Chipset Performance UP and other setting after DRAM Sizing */
1551 /****************************************************************/
1552 /* Dram Registers */
1553 val = sizeof(Dram_Table) / sizeof(Dram_Table[0]);
1554 for (i = 0; i < val; i += 3) {
1555 reg8 = pci_read_config8(MEMCTRL, Dram_Table[i]);
1556 reg8 &= Dram_Table[i + 1];
1557 reg8 |= Dram_Table[i + 2];
1558 pci_write_config8(MEMCTRL, Dram_Table[i], reg8);
1559 }
1560
1561 /* Host Registers */
1562 val = sizeof(Host_Table) / sizeof(Host_Table[0]);
1563 for (i = 0; i < val; i += 3) {
1564 reg8 = pci_read_config8(HOSTCTRL, Host_Table[i]);
1565 reg8 &= Host_Table[i + 1];
1566 reg8 |= Host_Table[i + 2];
1567 pci_write_config8(HOSTCTRL, Host_Table[i], reg8);
1568 }
1569
1570 /* PM Registers */
1571#ifdef SETUP_PM_REGISTERS
1572 val = sizeof(PM_Table) / sizeof(PM_Table[0]);
1573 for (i = 0; i < val; i += 3) {
1574 reg8 = pci_read_config8(PCI_DEV(0, 0, 4), PM_Table[i]);
1575 reg8 &= PM_Table[i + 1];
1576 reg8 |= PM_Table[i + 2];
1577 pci_write_config8(PCI_DEV(0, 0, 4), PM_Table[i], reg8);
1578 }
1579#endif
1580 pci_write_config8(HOSTCTRL, 0x5d, 0xb2);
1581
1582 /****************************************************************/
1583 /* UMA registers for N-series projects */
1584 /****************************************************************/
1585
1586 /* Manual setting frame buffer bank */
1587 for (i = 0; i < 4; i++) {
1588 reg8 = pci_read_config8(PCI_DEV(0, 0, 4), (SCRATCH_RANK_0 + i));
1589 if (reg8)
1590 val = i;
1591 }
1592 pci_write_config8(MEMCTRL, 0xb0, val);
1593 reg8 = 0x40; // Frame buffer size 64M
1594 reg8 |= 0x80; // VGA Enable
1595 reg8 |= 0x0a; // A[31:28] = 1010b
1596 pci_write_config8(MEMCTRL, 0xa1, reg8);
1597
1598#ifdef ECC
1599 // Clear Ecc
1600 outl(0x80000180, 0xcf8);
1601 outb(0xff, 0xcfc);
1602 // Enable Ecc
1603 outl(0x80000188, 0xcf8);
1604 outb(0xcf, 0xcfc);
1605
1606 reg8 = pci_read_config8(PCI_DEV(0, 0, 0), 0xa5);
1607 reg8 |= 0x10;
1608 pci_write_config8(PCI_DEV(0, 0, 0), 0xa5, reg8);
1609
1610 reg8 = pci_read_config8(PCI_DEV(0, 0, 0), 0x91);
1611 reg8 |= 0x20;
1612 pci_write_config8(PCI_DEV(0, 0, 0), 0x91, reg8);
1613#endif
1614
1615 static const struct regmask {
1616 u8 reg;
1617 u8 mask;
1618 u8 val;
1619 } b0d1f0[] = {
Stefan Reinauer14e22772010-04-27 06:56:47 +00001620 { 0x40, 0x00, 0x8b},
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001621 { 0x41, 0x80, 0x43},
1622 { 0x42, 0x00, 0x62},
1623 { 0x43, 0x00, 0x44},
1624 { 0x44, 0x00, 0x34},
1625 { 0x45, 0x00, 0x72}
1626 }, b0d0f3[] = {
1627 { 0x53, 0xf0, 0x0f},
1628 { 0x60, 0x00, 0x03},
1629 { 0x65, 0x00, 0xd9},
1630 { 0x66, 0x00, 0x80},
1631 { 0x67, 0x00, 0x00},
1632 { 0x68, 0x00, 0x01},
1633 { 0x69, 0xe0, 0x03},
1634 { 0x6b, 0x00, 0x10},
1635 { 0x6c, 0xc1, 0x08},
1636 { 0x6e, 0x00, 0x89},
1637 { 0x6f, 0x00, 0x51},
1638 { 0x75, ~0x40, 0x40},
1639 { 0x76, 0x8f, 0x00},
1640 { 0x7b, 0x00, 0xa0},
1641 { 0x86, 0x01, 0x24},
1642 { 0x86, 0x04, 0x29},
1643 { 0x8c, 0x00, 0x00},
1644 { 0x8d, 0x00, 0x00},
1645 { 0x95, ~0x40, 0x00},
1646 { 0xa2, 0x00, 0x44},
1647 { 0xb1, 0x00, 0xaa}
1648 }, b0d0f0[] = {
1649 { 0x4d, 0x00, 0x24},
1650 { 0x4f, 0x00, 0x01},
1651 { 0xbc, 0x00, 0x21},
1652 { 0xbe, 0x00, 0x00},
1653 { 0xbf, 0x7f, 0x80}
1654 }, b0d17f0[] = {
1655 { 0x40, ~0x01, 0x01}, // enable timer/counter shadow registers
1656 { 0x67, ~0x03, 0x01},
1657 { 0x5b, ~0x01, 0x00},
1658 { 0x8d, ~0x02, 0x02},
Stefan Reinauerc65666f2010-04-03 12:41:41 +00001659 { 0x97, 0x7f, 0x00},
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001660 { 0xd2, ~0x18, 0x00},
1661 { 0xe2, ~0x36, 0x06},
Stefan Reinauerc65666f2010-04-03 12:41:41 +00001662 { 0xe4, 0x7f, 0x00},
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001663 { 0xe5, 0x00, 0x40},
1664 { 0xe6, 0x00, 0x20},
Stefan Reinauerc65666f2010-04-03 12:41:41 +00001665 { 0xe7, 0x2f, 0xc0},
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001666 { 0xec, ~0x08, 0x00}
1667 }, b0d17f7[] = {
Stefan Reinauerc65666f2010-04-03 12:41:41 +00001668 { 0x4e, 0x7f, 0x80},
Stefan Reinaueraeba92a2009-04-17 08:37:18 +00001669 { 0x4f, ~(1 << 6), 1 << 6 }, /* PG_CX700: 14.1.1 enable P2P Bridge Header for External PCI Bus */
1670 { 0x74, ~0x00, 0x04}, /* PG_CX700: 14.1.2 APIC FSB directly up to snmic, not on pci */
1671 { 0x7c, ~0x00, 0x02}, /* PG_CX700: 14.1.1 APIC FSB directly up to snmic, not on pci */
1672 { 0xe6, 0x0, 0x04} // MSI post
1673 }, b0d19f0[] = { /* P2PE */
1674 { 0x42, ~0x08, 0x08}, // Disable HD Audio,
Stefan Reinauerc65666f2010-04-03 12:41:41 +00001675 { 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 +00001676 }, b0d0f2[] = {
1677 { 0x50, ~0x40, 0x88},
1678 { 0x51, 0x80, 0x7b},
1679 { 0x52, 0x90, 0x6f},
1680 { 0x53, 0x00, 0x88},
1681 { 0x54, 0xe4, 0x16},
1682 { 0x55, 0xf2, 0x04},
1683 { 0x56, 0x0f, 0x00},
1684 { 0x57, ~0x04, 0x00},
1685 { 0x5d, 0x00, 0xb2},
1686 { 0x5e, 0x00, 0x88},
1687 { 0x5f, 0x00, 0xc7},
1688 { 0x5c, 0x00, 0x01}
1689 };
1690
1691 REGISTERPRESET(0, 0, 0, b0d0f0);
1692 REGISTERPRESET(0, 0, 2, b0d0f2);
1693 REGISTERPRESET(0, 0, 3, b0d0f3);
1694 REGISTERPRESET(0, 1, 0, b0d1f0);
1695 REGISTERPRESET(0, 17, 0, b0d17f0);
1696 REGISTERPRESET(0, 17, 7, b0d17f7);
1697 REGISTERPRESET(0, 19, 0, b0d19f0);
1698}