xref: /aosp_15_r20/external/coreboot/src/northbridge/intel/pineview/raminit.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
3 #include <cf9_reset.h>
4 #include <device/mmio.h>
5 #include <device/pci_ops.h>
6 #include <device/smbus_host.h>
7 #include <commonlib/helpers.h>
8 #include <console/console.h>
9 #include <delay.h>
10 #include <lib.h>
11 #include <southbridge/intel/common/hpet.h>
12 #include "pineview.h"
13 #include "raminit.h"
14 #include <spd.h>
15 #include <string.h>
16 
17 /* Debugging macros */
18 #if CONFIG(DEBUG_RAM_SETUP)
19 #define PRINTK_DEBUG(x...)	printk(BIOS_DEBUG, x)
20 #else
21 #define PRINTK_DEBUG(x...)
22 #endif
23 
24 #define MAX_TCLK_667	0x30
25 #define MAX_TCLK_800	0x25
26 #define MAX_TAC_667	0x45
27 #define MAX_TAC_800	0x40
28 
29 #define NOP_CMD		(1 << 1)
30 #define PRE_CHARGE_CMD	(1 << 2)
31 #define MRS_CMD		((1 << 2) | (1 << 1))
32 #define EMRS_CMD	(1 << 3)
33 #define EMRS1_CMD	(EMRS_CMD | (1 << 4))
34 #define EMRS2_CMD	(EMRS_CMD | (1 << 5))
35 #define EMRS3_CMD	(EMRS_CMD | (1 << 5) | (1 << 4))
36 #define ZQCAL_CMD	((1 << 3) | (1 << 1))
37 #define CBR_CMD		((1 << 3) | (1 << 2))
38 #define NORMAL_OP_CMD	((1 << 3) | (1 << 2) | (1 << 1))
39 
40 #define UBDIMM 1
41 #define SODIMM 2
42 
43 #define TOTAL_CHANNELS 1
44 #define TOTAL_DIMMS 2
45 
46 #define DIMM_IS_POPULATED(dimms, idx) (dimms[idx].card_type != 0)
47 #define IF_DIMM_POPULATED(dimms, idx) if (dimms[idx].card_type != 0)
48 #define ONLY_DIMMA_IS_POPULATED(dimms, ch) (\
49 	(DIMM_IS_POPULATED(dimms, (ch == 0) ? 0 : 2) && \
50 	!DIMM_IS_POPULATED(dimms, (ch == 0) ? 1 : 3)))
51 #define ONLY_DIMMB_IS_POPULATED(dimms, ch) (\
52 	(DIMM_IS_POPULATED(dimms, (ch == 0) ? 1 : 3) && \
53 	!DIMM_IS_POPULATED(dimms, (ch == 0) ? 0 : 2)))
54 #define BOTH_DIMMS_ARE_POPULATED(dimms, ch) (\
55 	(DIMM_IS_POPULATED(dimms, (ch == 0) ? 0 : 2) && \
56 	(DIMM_IS_POPULATED(dimms, (ch == 0) ? 1 : 3))))
57 #define FOR_EACH_DIMM(idx) \
58 	for (idx = 0; idx < TOTAL_DIMMS; ++idx)
59 #define FOR_EACH_POPULATED_DIMM(dimms, idx) \
60 	FOR_EACH_DIMM(idx) IF_DIMM_POPULATED(dimms, idx)
61 #define CHANNEL_IS_POPULATED(dimms, idx) ((dimms[idx<<1].card_type != 0) || (dimms[(idx<<1) + 1].card_type != 0))
62 #define CHANNEL_IS_CARDF(dimms, idx) ((dimms[idx<<1].card_type == 0xf) || (dimms[(idx<<1) + 1].card_type == 0xf))
63 #define IF_CHANNEL_POPULATED(dimms, idx) if ((dimms[idx<<1].card_type != 0) || (dimms[(idx<<1) + 1].card_type != 0))
64 #define FOR_EACH_CHANNEL(idx) \
65 	for (idx = 0; idx < TOTAL_CHANNELS; ++idx)
66 #define FOR_EACH_POPULATED_CHANNEL(dimms, idx) \
67 	FOR_EACH_CHANNEL(idx) IF_CHANNEL_POPULATED(dimms, idx)
68 
69 #define RANKS_PER_CHANNEL 4
70 
71 #define FOR_EACH_RANK_IN_CHANNEL(r) \
72 	for (r = 0; r < RANKS_PER_CHANNEL; ++r)
73 #define FOR_EACH_POPULATED_RANK_IN_CHANNEL(dimms, ch, r) \
74 	FOR_EACH_RANK_IN_CHANNEL(r) if (rank_is_populated(dimms, ch, r))
75 #define FOR_EACH_RANK(ch, r) \
76 	FOR_EACH_CHANNEL(ch) FOR_EACH_RANK_IN_CHANNEL(r)
77 #define FOR_EACH_POPULATED_RANK(dimms, ch, r) \
78 	FOR_EACH_RANK(ch, r) if (rank_is_populated(dimms, ch, r))
79 
rank_is_populated(struct dimminfo dimms[],u8 ch,u8 r)80 static bool rank_is_populated(struct dimminfo dimms[], u8 ch, u8 r)
81 {
82 	return ((dimms[ch<<1].card_type && ((r) < dimms[ch<<1].ranks))
83 		|| (dimms[(ch<<1) + 1].card_type
84 			&& ((r) >= 2)
85 			&& ((r) < (dimms[(ch<<1) + 1].ranks + 2))));
86 }
87 
barrier(void)88 static inline void barrier(void)
89 {
90 	 __asm__ __volatile__("": : :"memory");
91 }
92 
decode_spd(struct dimminfo * d,int i)93 static int decode_spd(struct dimminfo *d, int i)
94 {
95 	d->type = 0;
96 	if (d->spd_data[20] == 0x2) {
97 		d->type = UBDIMM;
98 	} else if (d->spd_data[20] == 0x4) {
99 		d->type = SODIMM;
100 	}
101 	d->sides = (d->spd_data[5] & 0x7) + 1;
102 	d->banks = (d->spd_data[17] >> 2) - 1;
103 	d->chip_capacity = d->banks;
104 	d->rows = d->spd_data[3];// - 12;
105 	d->cols = d->spd_data[4];// - 9;
106 	d->cas_latencies = 0x78;
107 	d->cas_latencies &= d->spd_data[18];
108 	if (d->cas_latencies == 0)
109 		d->cas_latencies = 7;
110 	d->tAAmin = d->spd_data[26];
111 	d->tCKmin = d->spd_data[25];
112 	d->width = (d->spd_data[13] >> 3) - 1;
113 	d->page_size = (d->width+1) * (1 << d->cols); // Bytes
114 	d->tRAS = d->spd_data[30];
115 	d->tRP = d->spd_data[27];
116 	d->tRCD = d->spd_data[29];
117 	d->tWR = d->spd_data[36];
118 	d->ranks = d->sides; // XXX
119 #if CONFIG(DEBUG_RAM_SETUP)
120 	const char *ubso[2] = { "UB", "SO" };
121 #endif
122 	PRINTK_DEBUG("%s-DIMM %d\n", &ubso[d->type][0], i);
123 	PRINTK_DEBUG("  Sides     : %d\n", d->sides);
124 	PRINTK_DEBUG("  Banks     : %d\n", d->banks);
125 	PRINTK_DEBUG("  Ranks     : %d\n", d->ranks);
126 	PRINTK_DEBUG("  Rows      : %d\n", d->rows);
127 	PRINTK_DEBUG("  Cols      : %d\n", d->cols);
128 	PRINTK_DEBUG("  Page size : %d\n", d->page_size);
129 	PRINTK_DEBUG("  Width     : %d\n", (d->width + 1) * 8);
130 
131 	return 0;
132 }
133 
134 /*
135  * RAM Config:    DIMMB-DIMMA
136  *		0 EMPTY-EMPTY
137  *		1 EMPTY-x16SS
138  *		2 EMPTY-x16DS
139  *		3 x16SS-x16SS
140  *		4 x16DS-x16DS
141  *		5 EMPTY- x8DS
142  *		6 x8DS - x8DS
143  */
find_ramconfig(struct sysinfo * s,u32 chan)144 static void find_ramconfig(struct sysinfo *s, u32 chan)
145 {
146 	if (s->dimms[chan>>1].sides == 0) {
147 		// NC
148 		if (s->dimms[(chan>>1) + 1].sides == 0) {
149 			// NC/NC
150 			s->dimm_config[chan] = 0;
151 		} else if (s->dimms[(chan>>1) + 1].sides == 1) {
152 			// NC/{8,16}SS
153 			s->dimm_config[chan] = 1;
154 		} else {
155 			// NC/DS
156 			if (s->dimms[(chan>>1) + 1].width == 0) {
157 				// NC/8DS
158 				s->dimm_config[chan] = 5;
159 			} else {
160 				// NC/16DS
161 				s->dimm_config[chan] = 2;
162 			}
163 		}
164 	} else if (s->dimms[chan>>1].sides == 1) {
165 		// SS
166 		if (s->dimms[(chan>>1) + 1].sides == 0) {
167 			// {8,16}SS/NC
168 			s->dimm_config[chan] = 1;
169 		} else if (s->dimms[(chan>>1) + 1].sides == 1) {
170 			// SS/SS
171 			if (s->dimms[chan>>1].width == 0) {
172 				if (s->dimms[(chan>>1) + 1].width == 0) {
173 					// 8SS/8SS
174 					s->dimm_config[chan] = 3;
175 				} else {
176 					// 8SS/16SS
177 					die("Mixed Not supported\n");
178 				}
179 			} else {
180 				if (s->dimms[(chan>>1) + 1].width == 0) {
181 					// 16SS/8SS
182 					die("Mixed Not supported\n");
183 				} else {
184 					// 16SS/16SS
185 					s->dimm_config[chan] = 3;
186 				}
187 			}
188 		} else {
189 			// {8,16}SS/8DS
190 			die("Mixed Not supported\n");
191 		}
192 	} else {
193 		// DS
194 		if (s->dimms[(chan>>1) + 1].sides == 0) {
195 			// DS/NC
196 			if (s->dimms[chan>>1].width == 0) {
197 				// 8DS/NC
198 				s->dimm_config[chan] = 5;
199 			} else {
200 				s->dimm_config[chan] = 4;
201 			}
202 		} else if (s->dimms[(chan>>1) + 1].sides == 1) {
203 			// 8DS/{8,16}SS
204 			if (s->dimms[chan>>1].width == 0) {
205 				die("Mixed Not supported\n");
206 			} else {
207 				if (s->dimms[(chan>>1) + 1].width == 0) {
208 					die("Mixed Not supported\n");
209 				} else {
210 					// 16DS/16DS
211 					s->dimm_config[chan] = 4;
212 				}
213 			}
214 		} else {
215 			// DS/DS
216 			if (s->dimms[chan>>1].width == 0 && s->dimms[(chan>>1)+1].width == 0) {
217 				// 8DS/8DS
218 				s->dimm_config[chan] = 6;
219 			}
220 		}
221 	}
222 }
223 
sdram_read_spds(struct sysinfo * s)224 static void sdram_read_spds(struct sysinfo *s)
225 {
226 	u8 i, chan;
227 	s->dt0mode = 0;
228 	FOR_EACH_DIMM(i) {
229 		if (i2c_eeprom_read(s->spd_map[i], 0, 64, s->dimms[i].spd_data) != 64)
230 			s->dimms[i].card_type = 0;
231 
232 		s->dimms[i].card_type = s->dimms[i].spd_data[62] & 0x1f;
233 		hexdump(s->dimms[i].spd_data, 64);
234 	}
235 
236 	s->spd_type = 0;
237 	FOR_EACH_POPULATED_DIMM(s->dimms, i) {
238 		switch (s->dimms[i].spd_data[2]) {
239 			case 0x8:
240 				s->spd_type = DDR2;
241 				break;
242 			case 0xb:
243 			default:
244 				die("DIMM type mismatch\n");
245 				break;
246 		}
247 	}
248 
249 	int err = 1;
250 	FOR_EACH_POPULATED_DIMM(s->dimms, i) {
251 		err = decode_spd(&s->dimms[i], i);
252 		s->dt0mode |= (s->dimms[i].spd_data[49] & 0x2) >> 1;
253 	}
254 	if (err) {
255 		die("No memory dimms, halt\n");
256 	}
257 
258 	FOR_EACH_POPULATED_CHANNEL(s->dimms, chan) {
259 		find_ramconfig(s, chan);
260 		PRINTK_DEBUG("  Config[CH%d] : %d\n", chan, s->dimm_config[chan]);
261 	}
262 }
263 
264 #if CONFIG(DEBUG_RAM_SETUP)
fsb_reg_to_mhz(u32 speed)265 static u32 fsb_reg_to_mhz(u32 speed)
266 {
267 	return (speed * 133) + 667;
268 }
269 
ddr_reg_to_mhz(u32 speed)270 static u32 ddr_reg_to_mhz(u32 speed)
271 {
272 	return (speed == 0) ? 667 : (speed == 1) ? 800 : 0;
273 }
274 #endif
275 
276 // Return the position of the least significant set bit, 0-indexed.
277 // 0 does not have a lsb, so return -1 for error.
lsbpos(u8 val)278 static int lsbpos(u8 val)
279 {
280 	for (int i = 0; i < 8; i++)
281 		if (val & (1 << i))
282 			return i;
283 	return -1;
284 }
285 
286 // Return the position of the most significant set bit, 0-indexed.
287 // 0 does not have a msb, so return -1 for error.
msbpos(u8 val)288 static int msbpos(u8 val)
289 {
290 	for (int i = 7; i >= 0; i--)
291 		if (val & (1 << i))
292 			return i;
293 	return -1;
294 }
295 
sdram_detect_smallest_params(struct sysinfo * s)296 static void sdram_detect_smallest_params(struct sysinfo *s)
297 {
298 	static const u16 mult[6] = {
299 		3000, // 667
300 		2500, // 800
301 	};
302 
303 	u8 i;
304 	u32 maxtras = 0;
305 	u32 maxtrp  = 0;
306 	u32 maxtrcd = 0;
307 	u32 maxtwr  = 0;
308 	u32 maxtrfc = 0;
309 	u32 maxtwtr = 0;
310 	u32 maxtrrd = 0;
311 	u32 maxtrtp = 0;
312 
313 	FOR_EACH_POPULATED_DIMM(s->dimms, i) {
314 		maxtras = MAX(maxtras, (s->dimms[i].spd_data[30] * 1000));
315 		maxtrp  = MAX(maxtrp,  (s->dimms[i].spd_data[27] * 1000) >> 2);
316 		maxtrcd = MAX(maxtrcd, (s->dimms[i].spd_data[29] * 1000) >> 2);
317 		maxtwr  = MAX(maxtwr,  (s->dimms[i].spd_data[36] * 1000) >> 2);
318 		maxtrfc = MAX(maxtrfc, (s->dimms[i].spd_data[42] * 1000) +
319 				       (s->dimms[i].spd_data[40] & 0xf));
320 		maxtwtr = MAX(maxtwtr, (s->dimms[i].spd_data[37] * 1000) >> 2);
321 		maxtrrd = MAX(maxtrrd, (s->dimms[i].spd_data[28] * 1000) >> 2);
322 		maxtrtp = MAX(maxtrtp, (s->dimms[i].spd_data[38] * 1000) >> 2);
323 	}
324 	/*
325 	 * TODO: on DDR3 there might be some minimal required values for some
326 	 * Timings: MIN_TRAS = 9, MIN_TRP = 3, MIN_TRCD = 3, MIN_TWR = 3,
327 	 * MIN_TWTR = 4, MIN_TRRD = 2, MIN_TRTP = 4
328 	 */
329 	s->selected_timings.tRAS = MIN(24, DIV_ROUND_UP(maxtras,
330 					mult[s->selected_timings.mem_clock]));
331 	s->selected_timings.tRP = MIN(10, DIV_ROUND_UP(maxtrp,
332 					mult[s->selected_timings.mem_clock]));
333 	s->selected_timings.tRCD = MIN(10, DIV_ROUND_UP(maxtrcd,
334 					mult[s->selected_timings.mem_clock]));
335 	s->selected_timings.tWR = MIN(15, DIV_ROUND_UP(maxtwr,
336 					mult[s->selected_timings.mem_clock]));
337 	/* Needs to be even */
338 	s->selected_timings.tRFC = 0xfe & (MIN(78, DIV_ROUND_UP(maxtrfc,
339 				mult[s->selected_timings.mem_clock])) + 1);
340 	s->selected_timings.tWTR = MIN(15, DIV_ROUND_UP(maxtwtr,
341 					mult[s->selected_timings.mem_clock]));
342 	s->selected_timings.tRRD = MIN(15, DIV_ROUND_UP(maxtrrd,
343 					mult[s->selected_timings.mem_clock]));
344 	s->selected_timings.tRTP = MIN(15, DIV_ROUND_UP(maxtrtp,
345 					mult[s->selected_timings.mem_clock]));
346 
347 	PRINTK_DEBUG("Selected timings:\n");
348 	PRINTK_DEBUG("\tFSB:  %dMHz\n", fsb_reg_to_mhz(s->selected_timings.fsb_clock));
349 	PRINTK_DEBUG("\tDDR:  %dMHz\n", ddr_reg_to_mhz(s->selected_timings.mem_clock));
350 
351 	PRINTK_DEBUG("\tCAS:  %d\n", s->selected_timings.CAS);
352 	PRINTK_DEBUG("\ttRAS: %d\n", s->selected_timings.tRAS);
353 	PRINTK_DEBUG("\ttRP:  %d\n", s->selected_timings.tRP);
354 	PRINTK_DEBUG("\ttRCD: %d\n", s->selected_timings.tRCD);
355 	PRINTK_DEBUG("\ttWR:  %d\n", s->selected_timings.tWR);
356 	PRINTK_DEBUG("\ttRFC: %d\n", s->selected_timings.tRFC);
357 	PRINTK_DEBUG("\ttWTR: %d\n", s->selected_timings.tWTR);
358 	PRINTK_DEBUG("\ttRRD: %d\n", s->selected_timings.tRRD);
359 	PRINTK_DEBUG("\ttRTP: %d\n", s->selected_timings.tRTP);
360 }
361 
sdram_detect_ram_speed(struct sysinfo * s)362 static void sdram_detect_ram_speed(struct sysinfo *s)
363 {
364 	u8 cas, reg8;
365 	u32 reg32;
366 	u32 freq = 0;
367 	u32 fsb = 0;
368 	u8 i;
369 	u8 commoncas = 0;
370 	u8 highcas   = 0;
371 	u8 lowcas    = 0;
372 
373 	// Core frequency
374 	fsb = (pci_read_config8(HOST_BRIDGE, 0xe3) & 0x70) >> 4;
375 	if (fsb) {
376 		fsb = 5 - fsb;
377 	} else {
378 		fsb = FSB_CLOCK_800MHz;
379 	}
380 
381 	// DDR frequency
382 	freq  = (pci_read_config8(HOST_BRIDGE, 0xe3) & 0x80) >> 7;
383 	freq |= (pci_read_config8(HOST_BRIDGE, 0xe4) & 0x03) << 1;
384 	if (freq) {
385 		freq = 6 - freq;
386 	} else {
387 		freq = MEM_CLOCK_800MHz;
388 	}
389 
390 	// Detect a common CAS latency
391 	commoncas = 0xff;
392 	FOR_EACH_POPULATED_DIMM(s->dimms, i) {
393 		commoncas &= s->dimms[i].spd_data[18];
394 	}
395 	if (commoncas == 0) {
396 		die("No common CAS among dimms\n");
397 	}
398 
399 	// commoncas is nonzero, so these calls will not error
400 	u8 msbp = (u8)msbpos(commoncas);
401 	u8 lsbp = (u8)lsbpos(commoncas);
402 
403 	// Start with fastest common CAS
404 	cas = 0;
405 	highcas = msbp;
406 	lowcas = MAX(lsbp, 5);
407 
408 	while (cas == 0 && highcas >= lowcas) {
409 		FOR_EACH_POPULATED_DIMM(s->dimms, i) {
410 			switch (freq) {
411 			case MEM_CLOCK_800MHz:
412 				if ((s->dimms[i].spd_data[9]  > 0x25) ||
413 				    (s->dimms[i].spd_data[10] > 0x40)) {
414 					// CAS too fast, lower it
415 					highcas--;
416 					break;
417 				} else {
418 					cas = highcas;
419 				}
420 				break;
421 			case MEM_CLOCK_667MHz:
422 			default:
423 				if ((s->dimms[i].spd_data[9]  > 0x30) ||
424 				    (s->dimms[i].spd_data[10] > 0x45)) {
425 					// CAS too fast, lower it
426 					highcas--;
427 					break;
428 				} else {
429 					cas = highcas;
430 				}
431 				break;
432 			}
433 		}
434 	}
435 	if (highcas < lowcas) {
436 		// Timings not supported by MCH, lower the frequency
437 		if (freq == MEM_CLOCK_800MHz) {
438 			freq--;
439 			PRINTK_DEBUG("Run DDR clock speed reduced due to timings\n");
440 		} else {
441 			die("Timings not supported by MCH\n");
442 		}
443 		cas = 0;
444 		highcas = msbp;
445 		lowcas = lsbp;
446 		while (cas == 0 && highcas >= lowcas) {
447 			FOR_EACH_POPULATED_DIMM(s->dimms, i) {
448 				if ((s->dimms[i].spd_data[9]  > 0x30) ||
449 				    (s->dimms[i].spd_data[10] > 0x45)) {
450 					// CAS too fast, lower it
451 					highcas--;
452 				} else {
453 					cas = highcas;
454 				}
455 			}
456 		}
457 		if (cas == 0) {
458 			die("Unsupported dimms\n");
459 		}
460 	}
461 
462 	s->selected_timings.CAS = cas;
463 	s->selected_timings.mem_clock = freq;
464 	s->selected_timings.fsb_clock = fsb;
465 
466 	PRINTK_DEBUG("Drive Memory at %dMHz with CAS = %d clocks\n",
467 		     ddr_reg_to_mhz(s->selected_timings.mem_clock), s->selected_timings.CAS);
468 
469 	// Set memory frequency
470 	if (s->boot_path == BOOT_PATH_RESET)
471 		return;
472 
473 	mchbar_setbits32(PMSTS, 1 << 0);
474 
475 	reg32 = (mchbar_read32(CLKCFG) & ~0x70) | (1 << 10);
476 	if (s->selected_timings.mem_clock == MEM_CLOCK_800MHz) {
477 		reg8 = 3;
478 	} else {
479 		reg8 = 2;
480 	}
481 	reg32 |= reg8 << 4;
482 	mchbar_write32(CLKCFG, reg32);
483 
484 	s->selected_timings.mem_clock = ((mchbar_read32(CLKCFG) >> 4) & 0x7) - 2;
485 	if (s->selected_timings.mem_clock == MEM_CLOCK_800MHz) {
486 		PRINTK_DEBUG("MCH validated at 800MHz\n");
487 		s->nodll = 0;
488 		s->maxpi = 63;
489 		s->pioffset = 0;
490 	} else if (s->selected_timings.mem_clock == MEM_CLOCK_667MHz) {
491 		PRINTK_DEBUG("MCH validated at 667MHz\n");
492 		s->nodll = 1;
493 		s->maxpi = 15;
494 		s->pioffset = 1;
495 	} else {
496 		PRINTK_DEBUG("MCH set to unknown (%02x)\n",
497 			(uint8_t)s->selected_timings.mem_clock & 0xff);
498 	}
499 }
500 
sdram_clk_crossing(struct sysinfo * s)501 static void sdram_clk_crossing(struct sysinfo *s)
502 {
503 	u8 ddr_freq, fsb_freq;
504 	static const u32 clkcross[2][2][4] = {
505 	{
506 		{0xffffffff, 0x05030305, 0x0000ffff, 0x00000000}, /* FSB = 667, DDR = 667 */
507 		{0x1f1f1f1f, 0x2a1f1fa5, 0x00000000, 0x05000002}, /* FSB = 667, DDR = 800 */
508 	},
509 	{
510 		{0x1f1f1f1f, 0x0d07070b, 0x00000000, 0x00000000}, /* FSB = 800, DDR = 667 */
511 		{0xffffffff, 0x05030305, 0x0000ffff, 0x00000000}, /* FSB = 800, DDR = 800 */
512 	},
513 	};
514 
515 	ddr_freq = s->selected_timings.mem_clock;
516 	fsb_freq = s->selected_timings.fsb_clock;
517 
518 	mchbar_write32(HMCCMP,   clkcross[fsb_freq][ddr_freq][0]);
519 	mchbar_write32(HMDCMP,   clkcross[fsb_freq][ddr_freq][1]);
520 	mchbar_write32(HMBYPCP,  clkcross[fsb_freq][ddr_freq][2]);
521 	mchbar_write32(HMCCPEXT, 0);
522 	mchbar_write32(HMDCPEXT, clkcross[fsb_freq][ddr_freq][3]);
523 
524 	mchbar_setbits32(HMCCMC, 1 << 7);
525 
526 	if ((fsb_freq == 0) && (ddr_freq == 1)) {
527 		mchbar_write8(CLKXSSH2MCBYPPHAS, 0);
528 		mchbar_write32(CLKXSSH2MD, 0);
529 		mchbar_write32(CLKXSSH2MD + 4, 0);
530 	}
531 
532 	static const u32 clkcross2[2][2][8] = {
533 	{
534 		{	// FSB = 667, DDR = 667
535 			0x00000000, 0x08010204, 0x00000000, 0x08010204,
536 			0x00000000, 0x00000000, 0x00000000, 0x04080102,
537 		},
538 		{	// FSB = 667, DDR = 800
539 			0x04080000, 0x10010002, 0x10000000, 0x20010208,
540 			0x00000000, 0x00000004, 0x02040000, 0x08100102,
541 		},
542 	},
543 	{
544 		{	// FSB = 800, DDR = 667
545 			0x10000000, 0x20010208, 0x04080000, 0x10010002,
546 			0x00000000, 0x00000000, 0x08000000, 0x10200204,
547 		},
548 		{	// FSB = 800, DDR = 800
549 			0x00000000, 0x08010204, 0x00000000, 0x08010204,
550 			0x00000000, 0x00000000, 0x00000000, 0x04080102,
551 		},
552 	},
553 	};
554 
555 	mchbar_write32(CLKXSSH2MCBYP,       clkcross2[fsb_freq][ddr_freq][0]);
556 	mchbar_write32(CLKXSSH2MCRDQ,       clkcross2[fsb_freq][ddr_freq][0]);
557 	mchbar_write32(CLKXSSH2MCRDCST,     clkcross2[fsb_freq][ddr_freq][0]);
558 	mchbar_write32(CLKXSSH2MCBYP + 4,   clkcross2[fsb_freq][ddr_freq][1]);
559 	mchbar_write32(CLKXSSH2MCRDQ + 4,   clkcross2[fsb_freq][ddr_freq][1]);
560 	mchbar_write32(CLKXSSH2MCRDCST + 4, clkcross2[fsb_freq][ddr_freq][1]);
561 	mchbar_write32(CLKXSSMC2H,          clkcross2[fsb_freq][ddr_freq][2]);
562 	mchbar_write32(CLKXSSMC2H + 4,      clkcross2[fsb_freq][ddr_freq][3]);
563 	mchbar_write32(CLKXSSMC2HALT,       clkcross2[fsb_freq][ddr_freq][4]);
564 	mchbar_write32(CLKXSSMC2HALT + 4,   clkcross2[fsb_freq][ddr_freq][5]);
565 	mchbar_write32(CLKXSSH2X2MD,        clkcross2[fsb_freq][ddr_freq][6]);
566 	mchbar_write32(CLKXSSH2X2MD + 4,    clkcross2[fsb_freq][ddr_freq][7]);
567 }
568 
sdram_clkmode(struct sysinfo * s)569 static void sdram_clkmode(struct sysinfo *s)
570 {
571 	u8  ddr_freq;
572 	u16 mpll_ctl;
573 
574 	mchbar_clrbits16(CSHRMISCCTL1, 1 << 8);
575 	mchbar_clrbits8(CSHRMISCCTL1, 0x3f);
576 
577 	if (s->selected_timings.mem_clock == MEM_CLOCK_667MHz) {
578 		ddr_freq = 0;
579 		mpll_ctl = 1;
580 	} else {
581 		ddr_freq = 1;
582 		mpll_ctl = (1 << 8) | (1 << 5);
583 	}
584 	if (s->boot_path != BOOT_PATH_RESET)
585 		mchbar_clrsetbits16(MPLLCTL, 0x033f, mpll_ctl);
586 
587 	mchbar_write32(C0GNT2LNCH1, 0x58001117);
588 	mchbar_setbits32(C0STATRDCTRL, 1 << 23);
589 
590 	const u32 cas_to_reg[2][4] = {
591 		{0x00000000, 0x00030100, 0x0c240201, 0x00000000}, /* DDR = 667 */
592 		{0x00000000, 0x00030100, 0x0c240201, 0x10450302}  /* DDR = 800 */
593 	};
594 
595 	mchbar_write32(C0GNT2LNCH2, cas_to_reg[ddr_freq][s->selected_timings.CAS - 3]);
596 }
597 
sdram_timings(struct sysinfo * s)598 static void sdram_timings(struct sysinfo *s)
599 {
600 	u8 i, j, ch, r, ta1, ta2, ta3, ta4, trp, bank, page, flag;
601 	u8 reg8, wl;
602 	u16 reg16;
603 	u32 reg32, reg2;
604 
605 	static const u8 pagetab[2][2] = {
606 		{0x0e, 0x12},
607 		{0x10, 0x14},
608 	};
609 
610 	/* Only consider DDR2 */
611 	wl   = s->selected_timings.CAS - 1;
612 	ta1  = ta2 = 6;
613 	ta3  = s->selected_timings.CAS;
614 	ta4  = 8;
615 	s->selected_timings.tRFC = (s->selected_timings.tRFC + 1) & 0xfe;
616 	trp  = 0;
617 	bank = 1;
618 	page = 0;
619 
620 	mchbar_write8(C0LATCTRL, (wl - 3) << 4 | (s->selected_timings.CAS - 3));
621 
622 	FOR_EACH_POPULATED_RANK(s->dimms, ch, r) {
623 		i = ch << 1;
624 		if (s->dimms[i].banks == 1) {
625 			trp = 1;
626 			bank = 0;
627 		}
628 		if (s->dimms[i].page_size == 2048) {
629 			page = 1;
630 		}
631 	}
632 	PRINTK_DEBUG("trp=%d bank=%d page=%d\n",trp, bank, page);
633 
634 	if (s->selected_timings.mem_clock == MEM_CLOCK_667MHz) {
635 		flag = 0;
636 	} else {
637 		flag = 1;
638 	}
639 
640 	mchbar_setbits8(C0PVCFG, 3);
641 	mchbar_write16(C0CYCTRKPCHG, (wl + 4 + s->selected_timings.tWR) << 6 |
642 				 (2 + MAX(s->selected_timings.tRTP, 2)) << 2 | 1);
643 
644 	reg32 = (bank << 21) | (s->selected_timings.tRRD << 17) |
645 		(s->selected_timings.tRP << 13) | ((s->selected_timings.tRP + trp) << 9) |
646 		 s->selected_timings.tRFC;
647 
648 	if (bank == 0) {
649 		reg32 |= (pagetab[flag][page] << 22);
650 	}
651 	/* FIXME: Why not do a single dword write? */
652 	mchbar_write16(C0CYCTRKACT + 0, (u16)(reg32));
653 	mchbar_write16(C0CYCTRKACT + 2, (u16)(reg32 >> 16));
654 
655 	/* FIXME: Only applies to DDR2 */
656 	reg16 = (mchbar_read16(C0CYCTRKACT + 2) & 0x0fc0) >> 6;
657 	mchbar_clrsetbits16(SHCYCTRKCKEL, 0x3f << 7, reg16 << 7);
658 
659 	reg16 = (s->selected_timings.tRCD << 12) | (4 << 8) | (ta2 << 4) | ta4;
660 	mchbar_write16(C0CYCTRKWR, reg16);
661 
662 	reg32 = (s->selected_timings.tRCD << 17) | ((wl + 4 + s->selected_timings.tWTR) << 12) |
663 		(ta3 << 8) | (4 << 4) | ta1;
664 	mchbar_write32(C0CYCTRKRD, reg32);
665 
666 	reg16 = ((s->selected_timings.tRP + trp) << 9) | s->selected_timings.tRFC;
667 
668 	/* FIXME: Why not do a single word write? */
669 	mchbar_write8(C0CYCTRKREFR + 0, (u8)(reg16));
670 	mchbar_write8(C0CYCTRKREFR + 1, (u8)(reg16 >> 8));
671 
672 	mchbar_clrsetbits16(C0CKECTRL, 0x1ff << 1, 100 << 1);
673 	mchbar_clrsetbits8(C0CYCTRKPCHG2, 0x3f, s->selected_timings.tRAS);
674 	mchbar_write16(C0ARBCTRL, 0x2310);
675 	mchbar_clrsetbits8(C0ADDCSCTRL, 0x1f, 1);
676 
677 	if (s->selected_timings.mem_clock == MEM_CLOCK_667MHz) {
678 		reg32 = 3000;
679 	} else {
680 		reg32 = 2500;
681 	}
682 	if (s->selected_timings.fsb_clock == FSB_CLOCK_667MHz) {
683 		reg2 = 6000;
684 	} else {
685 		reg2 = 5000;
686 	}
687 	reg16 = (u16)((((s->selected_timings.CAS + 7) * (reg32)) / reg2) << 8);
688 	mchbar_clrsetbits16(C0STATRDCTRL, 0x1f << 8, reg16);
689 
690 	flag = 0;
691 	if (wl > 2) {
692 		flag = 1;
693 	}
694 	reg16 = (u8)(wl - 1 - flag);
695 	reg16 |= reg16 << 4;
696 	reg16 |= flag << 8;
697 	mchbar_clrsetbits16(C0WRDATACTRL, 0x1ff, reg16);
698 
699 	mchbar_write16(C0RDQCTRL, 0x1585);
700 	mchbar_clrbits8(C0PWLRCTRL, 0x1f);
701 
702 	/* rdmodwr_window[5..0] = CL+4+5  265[13..8] (264[21..16]) */
703 	mchbar_clrsetbits16(C0PWLRCTRL, 0x3f << 8, (s->selected_timings.CAS + 9) << 8);
704 
705 	if (s->selected_timings.mem_clock == MEM_CLOCK_667MHz) {
706 		reg16 = 0x0514;
707 		reg32 = 0x0a28;
708 	} else {
709 		reg16 = 0x0618;
710 		reg32 = 0x0c30;
711 	}
712 	mchbar_clrsetbits32(C0REFRCTRL2, 0xfffff << 8, 0x3f << 22 | reg32 << 8);
713 
714 	/* FIXME: Is this weird access necessary? Reference code does it */
715 	mchbar_write8(C0REFRCTRL + 3, 0);
716 	mchbar_clrsetbits16(C0REFCTRL, 0x3fff, reg16);
717 
718 	/* NPUT Static Mode */
719 	mchbar_setbits8(C0DYNRDCTRL, 1 << 0);
720 
721 	mchbar_clrsetbits32(C0STATRDCTRL, 0x7f << 24, 0xb << 25);
722 	i = s->selected_timings.mem_clock;
723 	j = s->selected_timings.fsb_clock;
724 	if (i > j) {
725 		mchbar_setbits32(C0STATRDCTRL, 1 << 24);
726 	}
727 
728 	mchbar_clrbits8(C0RDFIFOCTRL, 3);
729 	mchbar_clrsetbits16(C0WRDATACTRL, 0x1f << 10, (wl + 10) << 10);
730 	mchbar_clrsetbits32(C0CKECTRL, 7 << 24 | 7 << 17, 3 << 24 | 3 << 17);
731 	reg16 = 0x15 << 6;
732 	reg16 |= 0x1f;
733 	reg16 |= (0x6 << 12);
734 	mchbar_clrsetbits16(C0REFRCTRL + 4, 0x7fff, reg16);
735 
736 	reg32 = (0x6 << 27) | (1 << 25);	/* FIXME: For DDR3, set BIT26 as well */
737 	mchbar_clrsetbits32(C0REFRCTRL2, 3 << 28, reg32 << 8);
738 	mchbar_clrsetbits8(C0REFRCTRL + 3, 0xfa, reg32 >> 24);
739 	mchbar_clrbits8(C0JEDEC, 1 << 7);
740 	mchbar_clrbits8(C0DYNRDCTRL, 3 << 1);
741 
742 	/* Note: This is a 64-bit register, [34..30] = 0b00110 is split across two writes */
743 	reg32 = ((6 & 3) << 30) | (4 << 25) | (1 << 20) | (8 << 15) | (6 << 10) | (4 << 5) | 1;
744 	mchbar_write32(C0WRWMFLSH, reg32);
745 	mchbar_clrsetbits16(C0WRWMFLSH + 4, 0x1ff, 8 << 3 | 6 >> 2);
746 	mchbar_setbits16(SHPENDREG, 0x1c00 | 0x1f << 5);
747 
748 	/* FIXME: Why not do a single word write? */
749 	mchbar_clrsetbits8(SHPAGECTRL,     0xff, 0x40);
750 	mchbar_clrsetbits8(SHPAGECTRL + 1, 0x07, 0x05);
751 	mchbar_setbits8(SHCMPLWRCMD, 0x1f);
752 
753 	reg8  = (3 << 6);
754 	reg8 |= (s->dt0mode << 4);
755 	reg8 |= 0x0c;
756 	mchbar_clrsetbits8(SHBONUSREG, 0xdf, reg8);
757 	mchbar_clrbits8(CSHRWRIOMLNS, 1 << 1);
758 	mchbar_clrsetbits8(C0MISCTM, 0x07, 0x02);
759 	mchbar_clrsetbits16(C0BYPCTRL, 0xff << 2, 4 << 2);
760 
761 	/* [31..29] = 0b010 for kN = 2 (2N) */
762 	reg32 = (2 << 29) | (1 << 28) | (1 << 23);
763 	mchbar_clrsetbits32(WRWMCONFIG, 0xffb << 20, reg32);
764 
765 	reg8  = (u8)((mchbar_read16(C0CYCTRKACT)     & 0xe000) >> 13);
766 	reg8 |= (u8)((mchbar_read16(C0CYCTRKACT + 2) & 1) << 3);
767 	mchbar_clrsetbits8(BYPACTSF, 0xf << 4, reg8 << 4);
768 
769 	reg8 = (u8)((mchbar_read32(C0CYCTRKRD) & 0x000f0000) >> 17);
770 	mchbar_clrsetbits8(BYPACTSF, 0xf, reg8);
771 
772 	/* FIXME: Why not clear everything at once? */
773 	mchbar_clrbits8(BYPKNRULE, 0xfc);
774 	mchbar_clrbits8(BYPKNRULE, 0x03);
775 	mchbar_clrbits8(SHBONUSREG, 0x03);
776 	mchbar_setbits8(C0BYPCTRL, 1 << 0);
777 	mchbar_setbits16(CSHRMISCCTL1, 1 << 9);
778 
779 	for (i = 0; i < 8; i++) {
780 		/* FIXME: Hardcoded for DDR2 SO-DIMMs */
781 		mchbar_clrsetbits32(C0DLLRCVCTLy(i), 0x3f3f3f3f, 0x0c0c0c0c);
782 	}
783 	/* RDCS to RCVEN delay: Program coarse common to all bytelanes to default tCL + 1 */
784 	mchbar_clrsetbits32(C0STATRDCTRL, 0xf << 16, (s->selected_timings.CAS + 1) << 16);
785 
786 	/* Program RCVEN delay with DLL-safe settings */
787 	for (i = 0; i < 8; i++) {
788 		mchbar_clrbits8(C0RXRCVyDLL(i), 0x3f);
789 		mchbar_clrbits16(C0RCVMISCCTL2, 3 << (i * 2));
790 		mchbar_clrbits16(C0RCVMISCCTL1, 3 << (i * 2));
791 		mchbar_clrbits16(C0COARSEDLY0, 3 << (i * 2));
792 	}
793 	mchbar_clrbits8(C0DLLPIEN, 1 << 0);	/* Power up receiver */
794 	mchbar_setbits8(C0DLLPIEN, 1 << 1);	/* Enable RCVEN DLL */
795 	mchbar_setbits8(C0DLLPIEN, 1 << 2);	/* Enable receiver DQS DLL */
796 	mchbar_setbits32(C0COREBONUS, 0x000c0400);
797 	mchbar_setbits32(C0CMDTX1, 1 << 31);
798 }
799 
800 /* Program clkset0's register for Kcoarse, Tap, PI, DBEn and DBSel */
sdram_p_clkset0(const struct pllparam * pll,u8 f,u8 i)801 static void sdram_p_clkset0(const struct pllparam *pll, u8 f, u8 i)
802 {
803 	mchbar_clrsetbits16(C0CKTX, 0xc440,
804 			(pll->clkdelay[f][i] << 14) |
805 			(pll->dben[f][i] << 10) |
806 			(pll->dbsel[f][i] << 6));
807 
808 	mchbar_clrsetbits8(C0TXCK0DLL, 0x3f, pll->pi[f][i]);
809 }
810 
811 /* Program clkset1's register for Kcoarse, Tap, PI, DBEn and DBSel */
sdram_p_clkset1(const struct pllparam * pll,u8 f,u8 i)812 static void sdram_p_clkset1(const struct pllparam *pll, u8 f, u8 i)
813 {
814 	mchbar_clrsetbits32(C0CKTX, 0x00030880,
815 			(pll->clkdelay[f][i] << 16) |
816 			(pll->dben[f][i] << 11) |
817 			(pll->dbsel[f][i] << 7));
818 
819 	mchbar_clrsetbits8(C0TXCK1DLL, 0x3f, pll->pi[f][i]);
820 }
821 
822 /* Program CMD0 and CMD1 registers for Kcoarse, Tap, PI, DBEn and DBSel */
sdram_p_cmd(const struct pllparam * pll,u8 f,u8 i)823 static void sdram_p_cmd(const struct pllparam *pll, u8 f, u8 i)
824 {
825 	u8 reg8;
826 	/* Clock Group Index 3 */
827 	reg8 = pll->dbsel[f][i] << 5;
828 	reg8 |= pll->dben[f][i] << 6;
829 	mchbar_clrsetbits8(C0CMDTX1, 3 << 5, reg8);
830 
831 	reg8 = pll->clkdelay[f][i] << 4;
832 	mchbar_clrsetbits8(C0CMDTX2, 3 << 4, reg8);
833 
834 	reg8 = pll->pi[f][i];
835 	mchbar_clrsetbits8(C0TXCMD0DLL, 0x3f, reg8);
836 	mchbar_clrsetbits8(C0TXCMD1DLL, 0x3f, reg8);
837 }
838 
839 /* Program CTRL registers for Kcoarse, Tap, PI, DBEn and DBSel */
sdram_p_ctrl(const struct pllparam * pll,u8 f,u8 i)840 static void sdram_p_ctrl(const struct pllparam *pll, u8 f, u8 i)
841 {
842 	u8 reg8;
843 	u32 reg32;
844 
845 	/* CTRL0 and CTRL1 */
846 	reg32  = ((u32)pll->dbsel[f][i]) << 20;
847 	reg32 |= ((u32)pll->dben[f][i])  << 21;
848 	reg32 |= ((u32)pll->dbsel[f][i]) << 22;
849 	reg32 |= ((u32)pll->dben[f][i])  << 23;
850 	reg32 |= ((u32)pll->clkdelay[f][i]) << 24;
851 	reg32 |= ((u32)pll->clkdelay[f][i]) << 27;
852 	mchbar_clrsetbits32(C0CTLTX2, 0x01bf0000, reg32);
853 
854 	reg8 = pll->pi[f][i];
855 	mchbar_clrsetbits8(C0TXCTL0DLL, 0x3f, reg8);
856 	mchbar_clrsetbits8(C0TXCTL1DLL, 0x3f, reg8);
857 
858 	/* CTRL2 and CTRL3 */
859 	reg32  = ((u32)pll->dbsel[f][i]) << 12;
860 	reg32 |= ((u32)pll->dben[f][i])  << 13;
861 	reg32 |= ((u32)pll->dbsel[f][i]) << 8;
862 	reg32 |= ((u32)pll->dben[f][i])  << 9;
863 	reg32 |= ((u32)pll->clkdelay[f][i]) << 14;
864 	reg32 |= ((u32)pll->clkdelay[f][i]) << 10;
865 	mchbar_clrsetbits32(C0CMDTX2, 0xff << 8, reg32);
866 
867 	reg8 = pll->pi[f][i];
868 	mchbar_clrsetbits8(C0TXCTL2DLL, 0x3f, reg8);
869 	mchbar_clrsetbits8(C0TXCTL3DLL, 0x3f, reg8);
870 }
871 
sdram_p_dqs(struct pllparam * pll,u8 f,u8 clk)872 static void sdram_p_dqs(struct pllparam *pll, u8 f, u8 clk)
873 {
874 	u8 rank, dqs, reg8, j;
875 	u32 reg32;
876 
877 	j     = clk - 40;
878 	reg8  = 0;
879 	reg32 = 0;
880 	rank  = j % 4;
881 	dqs   = j / 4;
882 
883 	reg32 |= ((u32)pll->dben[f][clk])  << (dqs + 9);
884 	reg32 |= ((u32)pll->dbsel[f][clk]) << dqs;
885 
886 	mchbar_clrsetbits32(C0DQSRyTX1(rank), 1 << (dqs + 9) | 1 << dqs, reg32);
887 
888 	reg32 = ((u32)pll->clkdelay[f][clk]) << ((dqs * 2) + 16);
889 	mchbar_clrsetbits32(C0DQSDQRyTX3(rank), 1 << (dqs * 2 + 17) | 1 << (dqs * 2 + 16),
890 			reg32);
891 
892 	reg8 = pll->pi[f][clk];
893 	mchbar_clrsetbits8(C0TXDQS0R0DLL + j, 0x3f, reg8);
894 }
895 
sdram_p_dq(struct pllparam * pll,u8 f,u8 clk)896 static void sdram_p_dq(struct pllparam *pll, u8 f, u8 clk)
897 {
898 	u8 rank, dq, reg8, j;
899 	u32 reg32;
900 
901 	j     = clk - 8;
902 	reg8  = 0;
903 	reg32 = 0;
904 	rank  = j % 4;
905 	dq    = j / 4;
906 
907 	reg32 |= ((u32)pll->dben[f][clk])  << (dq + 9);
908 	reg32 |= ((u32)pll->dbsel[f][clk]) << dq;
909 
910 	mchbar_clrsetbits32(C0DQRyTX1(rank), 1 << (dq + 9) | 1 << dq, reg32);
911 
912 	reg32 = ((u32)pll->clkdelay[f][clk]) << (dq*2);
913 	mchbar_clrsetbits32(C0DQSDQRyTX3(rank), 1 << (dq * 2 + 1) | 1 << (dq * 2), reg32);
914 
915 	reg8 = pll->pi[f][clk];
916 	mchbar_clrsetbits8(C0TXDQ0R0DLL + j, 0x3f, reg8);
917 }
918 
919 /* WDLL programming: Perform HPLL/MPLL calibration after write levelization */
sdram_calibratepll(struct sysinfo * s,u8 pidelay)920 static void sdram_calibratepll(struct sysinfo *s, u8 pidelay)
921 {
922 	struct pllparam pll = {
923 		.pi = {
924 		{	/* DDR = 667 */
925 			3, 3, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
926 			7, 7, 7, 7, 4, 4, 4, 4, 4, 4, 4, 4,
927 			4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5,
928 			7, 7, 7, 7, 3, 3, 3, 3, 3, 3, 3, 3,
929 			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
930 			0, 0, 0, 0, 1, 1, 1, 1, 3, 3, 3, 3,
931 		},
932 		{	/* DDR = 800 */
933 			53, 53, 10, 10,  5,  5,  5,  5, 27, 27, 27, 27,
934 			34, 34, 34, 34, 34, 34, 34, 34, 39, 39, 39, 39,
935 			47, 47, 47, 47, 44, 44, 44, 44, 47, 47, 47, 47,
936 			47, 47, 47, 47, 59, 59, 59, 59,  2,  2,  2,  2,
937 			 2,  2,  2,  2,  7,  7,  7,  7, 15, 15, 15, 15,
938 			12, 12, 12, 12, 15, 15, 15, 15, 15, 15, 15, 15,
939 		}},
940 
941 		.dben = {
942 		{	/* DDR = 667 */
943 			0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
944 			1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
945 			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
946 			1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
947 			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
948 			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
949 		},
950 		{	/* DDR = 800 */
951 			1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0,
952 			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
953 			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
954 			0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1,
955 			1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0,
956 			1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
957 		}},
958 
959 		.dbsel = {
960 		{	/* DDR = 667 */
961 			0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
962 			1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
963 			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
964 			1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
965 			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
966 			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
967 		},
968 		{	/* DDR = 800 */
969 			0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0,
970 			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
971 			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
972 			0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
973 			1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0,
974 			1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
975 		}},
976 
977 		.clkdelay = {
978 		{	/* DDR = 667 */
979 			0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1,
980 			1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
981 			1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
982 			1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
983 			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
984 			0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
985 		},
986 		{	/* DDR = 800 */
987 			0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
988 			1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
989 			1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
990 			1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1,
991 			1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
992 			1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
993 		}}
994 	};
995 
996 	u8 i, f;
997 	if (s->selected_timings.mem_clock == MEM_CLOCK_667MHz) {
998 		f = 0;
999 	} else {
1000 		f = 1;
1001 	}
1002 	for (i = 0; i < 72; i++) {
1003 		pll.pi[f][i] += pidelay;
1004 	}
1005 
1006 	/* Disable Dynamic DQS Slave Setting Per Rank */
1007 	mchbar_clrbits8(CSHRDQSCMN, 1 << 7);
1008 	mchbar_clrsetbits16(CSHRPDCTL4, 0x3fff, 0x1fff);
1009 
1010 	sdram_p_clkset0(&pll, f, 0);
1011 	sdram_p_clkset1(&pll, f, 1);
1012 	sdram_p_cmd(&pll,     f, 2);
1013 	sdram_p_ctrl(&pll,    f, 4);
1014 
1015 	for (i = 0; i < 32; i++) {
1016 		sdram_p_dqs(&pll, f, i + 40);
1017 	}
1018 	for (i = 0; i < 32; i++) {
1019 		sdram_p_dq(&pll, f, i + 8);
1020 	}
1021 }
1022 
1023 /* Perform HMC hardware calibration */
sdram_calibratehwpll(struct sysinfo * s)1024 static void sdram_calibratehwpll(struct sysinfo *s)
1025 {
1026 	u8 reg8;
1027 
1028 	s->async = 0;
1029 	reg8 = 0;
1030 
1031 	mchbar_setbits16(CSHRPDCTL, 1 << 15);
1032 	mchbar_clrbits8(CSHRPDCTL, 1 << 7);
1033 	mchbar_setbits8(CSHRPDCTL, 1 << 3);
1034 	mchbar_setbits8(CSHRPDCTL, 1 << 2);
1035 
1036 	/* Start hardware HMC calibration */
1037 	mchbar_setbits8(CSHRPDCTL, 1 << 7);
1038 
1039 	/* Busy-wait until calibration is done */
1040 	while ((mchbar_read8(CSHRPDCTL) & (1 << 2)) == 0)
1041 		;
1042 
1043 	/* If hardware HMC calibration failed */
1044 	reg8 = (mchbar_read8(CSHRPDCTL) & (1 << 3)) >> 3;
1045 	if (reg8 != 0) {
1046 		s->async = 1;
1047 	}
1048 }
1049 
sdram_dlltiming(struct sysinfo * s)1050 static void sdram_dlltiming(struct sysinfo *s)
1051 {
1052 	u8 reg8, i;
1053 	u16 reg16;
1054 	u32 reg32;
1055 
1056 	/* Configure the Master DLL */
1057 	if (s->selected_timings.mem_clock == MEM_CLOCK_667MHz) {
1058 		reg32 = 0x08014227;
1059 	} else {
1060 		reg32 = 0x00014221;
1061 	}
1062 	mchbar_clrsetbits32(CSHRMSTRCTL1, 0x0fffffff, reg32);
1063 	mchbar_setbits32(CSHRMSTRCTL1, 1 << 23);
1064 	mchbar_setbits32(CSHRMSTRCTL1, 1 << 15);
1065 	mchbar_clrbits32(CSHRMSTRCTL1, 1 << 15);
1066 
1067 	if (s->nodll) {
1068 		/* Disable the Master DLLs by setting these bits, IN ORDER! */
1069 		mchbar_setbits16(CSHRMSTRCTL0, 1 << 0);
1070 		mchbar_setbits16(CSHRMSTRCTL0, 1 << 2);
1071 		mchbar_setbits16(CSHRMSTRCTL0, 1 << 4);
1072 		mchbar_setbits16(CSHRMSTRCTL0, 1 << 8);
1073 		mchbar_setbits16(CSHRMSTRCTL0, 1 << 10);
1074 		mchbar_setbits16(CSHRMSTRCTL0, 1 << 12);
1075 		mchbar_setbits16(CSHRMSTRCTL0, 1 << 14);
1076 	} else {
1077 		/* Enable the Master DLLs by clearing these bits, IN ORDER! */
1078 		mchbar_clrbits16(CSHRMSTRCTL0, 1 << 0);
1079 		mchbar_clrbits16(CSHRMSTRCTL0, 1 << 2);
1080 		mchbar_clrbits16(CSHRMSTRCTL0, 1 << 4);
1081 		mchbar_clrbits16(CSHRMSTRCTL0, 1 << 8);
1082 		mchbar_clrbits16(CSHRMSTRCTL0, 1 << 10);
1083 		mchbar_clrbits16(CSHRMSTRCTL0, 1 << 12);
1084 		mchbar_clrbits16(CSHRMSTRCTL0, 1 << 14);
1085 	}
1086 
1087 	/* Initialize the Transmit DLL PI values in the following sequence. */
1088 	if (s->nodll) {
1089 		mchbar_clrsetbits8(CREFPI, 0x3f, 0x07);
1090 	} else {
1091 		mchbar_clrbits8(CREFPI, 0x3f);
1092 	}
1093 
1094 	sdram_calibratepll(s, 0); // XXX check
1095 
1096 	/* Enable all modular Slave DLL */
1097 	mchbar_setbits16(C0DLLPIEN, 1 << 11);
1098 	mchbar_setbits16(C0DLLPIEN, 1 << 12);
1099 
1100 	for (i = 0; i < 8; i++) {
1101 		mchbar_setbits16(C0DLLPIEN, (1 << 10) >> i);
1102 	}
1103 	/* Enable DQ/DQS output */
1104 	mchbar_setbits8(C0SLVDLLOUTEN, 1 << 0);
1105 	mchbar_write16(CSPDSLVWT, 0x5005);
1106 	mchbar_clrsetbits16(CSHRPDCTL2, 0x1f1f, 0x051a);
1107 	mchbar_clrsetbits16(CSHRPDCTL5, 0xbf3f, 0x9010);
1108 
1109 	if (s->nodll) {
1110 		mchbar_clrsetbits8(CSHRPDCTL3, 0x7f, 0x6b);
1111 	} else {
1112 		mchbar_clrsetbits8(CSHRPDCTL3, 0x7f, 0x55);
1113 		sdram_calibratehwpll(s);
1114 	}
1115 	/* Disable Dynamic Diff Amp */
1116 	mchbar_clrbits32(C0STATRDCTRL, 1 << 22);
1117 
1118 	/* Now, start initializing the transmit FIFO */
1119 	mchbar_clrbits8(C0MISCCTL, 1 << 1);
1120 
1121 	/* Disable (gate) mdclk and mdclkb */
1122 	mchbar_setbits8(CSHWRIOBONUS, 3 << 6);
1123 
1124 	/* Select mdmclk */
1125 	mchbar_clrbits8(CSHWRIOBONUS, 1 << 5);
1126 
1127 	/* Ungate mdclk */
1128 	mchbar_clrsetbits8(CSHWRIOBONUS, 3 << 6, 1 << 6);
1129 	mchbar_clrsetbits8(CSHRFIFOCTL, 0x3f, 0x1a);
1130 
1131 	/* Enable the write pointer count */
1132 	mchbar_setbits8(CSHRFIFOCTL, 1 << 0);
1133 
1134 	/* Set the DDR3 Reset Enable bit */
1135 	mchbar_setbits8(CSHRDDR3CTL, 1 << 0);
1136 
1137 	/* Configure DQS-DQ Transmit */
1138 	mchbar_write32(CSHRDQSTXPGM, 0x00551803);
1139 
1140 	reg8 = 0; /* Switch all clocks on anyway */
1141 
1142 	/* Enable clock groups depending on rank population */
1143 	mchbar_clrsetbits32(C0CKTX, 0x3f << 24, reg8 << 24);
1144 
1145 	/* Enable DDR command output buffers from core */
1146 	mchbar_clrbits8(0x594, 1 << 0);
1147 
1148 	reg16 = 0;
1149 	if (!rank_is_populated(s->dimms, 0, 0)) {
1150 		reg16 |= (1 <<  8) | (1 << 4) | (1 << 0);
1151 	}
1152 	if (!rank_is_populated(s->dimms, 0, 1)) {
1153 		reg16 |= (1 <<  9) | (1 << 5) | (1 << 1);
1154 	}
1155 	if (!rank_is_populated(s->dimms, 0, 2)) {
1156 		reg16 |= (1 << 10) | (1 << 6) | (1 << 2);
1157 	}
1158 	if (!rank_is_populated(s->dimms, 0, 3)) {
1159 		reg16 |= (1 << 11) | (1 << 7) | (1 << 3);
1160 	}
1161 	mchbar_setbits16(C0CTLTX2, reg16);
1162 }
1163 
1164 /* Define a shorter name for these to make the lines fit in 96 characters */
1165 #define TABLE static const
1166 
1167 /* Loop over each RCOMP group, but skip group 1 because it does not exist */
1168 #define FOR_EACH_RCOMP_GROUP(idx) for (idx = 0; idx < 7; idx++) if (idx != 1)
1169 
1170 /* Define accessors for the RCOMP register banks */
1171 #define C0RCOMPCTRLx(x)	(rcompctl[(x)] + 0x00)
1172 #define C0RCOMPMULTx(x)	(rcompctl[(x)] + 0x04)
1173 #define C0RCOMPOVRx(x)	(rcompctl[(x)] + 0x06)
1174 #define C0RCOMPOSVx(x)	(rcompctl[(x)] + 0x0a)
1175 #define C0SCOMPVREFx(x)	(rcompctl[(x)] + 0x0e)
1176 #define C0SCOMPOVRx(x)	(rcompctl[(x)] + 0x10)
1177 #define C0SCOMPOFFx(x)	(rcompctl[(x)] + 0x12)
1178 #define C0DCOMPx(x)	(rcompctl[(x)] + 0x14)
1179 #define C0SLEWBASEx(x)	(rcompctl[(x)] + 0x16)
1180 #define C0SLEWPULUTx(x)	(rcompctl[(x)] + 0x18)
1181 #define C0SLEWPDLUTx(x)	(rcompctl[(x)] + 0x1c)
1182 #define C0DCOMPOVRx(x)	(rcompctl[(x)] + 0x20)
1183 #define C0DCOMPOFFx(x)	(rcompctl[(x)] + 0x24)
1184 
1185 /* FIXME: This only applies to DDR2 */
sdram_rcomp(struct sysinfo * s)1186 static void sdram_rcomp(struct sysinfo *s)
1187 {
1188 	u8  i, j, reg8, rcompp, rcompn, srup, srun;
1189 	u16 reg16;
1190 	u32 reg32, rcomp1, rcomp2;
1191 
1192 	static const u8  rcompslew = 0x0a;
1193 	static const u16 rcompctl[7] = {
1194 		C0RCOMPCTRL0,
1195 		0,		/* This register does not exist */
1196 		C0RCOMPCTRL2,
1197 		C0RCOMPCTRL3,
1198 		C0RCOMPCTRL4,
1199 		C0RCOMPCTRL5,
1200 		C0RCOMPCTRL6,
1201 	};
1202 
1203 	/* RCOMP settings tables = { NC-NC,  x16SS,  x16DS, x16SS2, x16DS2,   x8DS,  x8DS2}; */
1204 	TABLE u8  rcompupdate[7] = {     0,      0,      0,      1,      1,      0,      0};
1205 	TABLE u8  rcompstr[7]    = {  0x66,   0x00,   0xaa,   0x55,   0x55,   0x77,   0x77};
1206 	TABLE u16 rcompscomp[7]  = {0xa22a, 0x0000, 0xe22e, 0xe22e, 0xe22e, 0xa22a, 0xa22a};
1207 	TABLE u8  rcompdelay[7]  = {     1,      0,      0,      0,      0,      1,      1};
1208 	TABLE u16 rcompf[7]      = {0x1114, 0x0000, 0x0505, 0x0909, 0x0909, 0x0a0a, 0x0a0a};
1209 	TABLE u8  rcompstr2[7]   = {  0x00,   0x55,   0x55,   0xaa,   0xaa,   0x55,   0xaa};
1210 	TABLE u16 rcompscomp2[7] = {0x0000, 0xe22e, 0xe22e, 0xe22e, 0x8228, 0xe22e, 0x8228};
1211 	TABLE u8  rcompdelay2[7] = {     0,      0,      0,      0,      2,      0,      2};
1212 
1213 	TABLE u8 rcomplut[64][12] = {
1214 		{ 9,  9, 11, 11,  2,  2,  5,  5,  6,  6,  5,  5},
1215 		{ 9,  9, 11, 11,  2,  2,  5,  5,  6,  6,  5,  5},
1216 		{ 9,  9, 11, 11,  2,  2,  5,  5,  6,  6,  5,  5},
1217 		{ 9,  9, 11, 11,  2,  2,  5,  5,  6,  6,  5,  5},
1218 		{ 9,  9, 11, 11,  2,  2,  5,  5,  6,  6,  5,  5},
1219 		{ 9,  9, 11, 11,  2,  2,  5,  5,  6,  6,  5,  5},
1220 		{ 9,  9, 11, 11,  2,  2,  5,  5,  6,  6,  5,  5},
1221 		{ 9,  9, 11, 11,  2,  2,  5,  5,  6,  6,  5,  5},
1222 		{ 9,  9, 11, 11,  2,  2,  5,  5,  6,  6,  5,  5},
1223 		{ 9,  9, 11, 11,  2,  2,  5,  5,  6,  6,  5,  5},
1224 		{ 9,  9, 11, 11,  2,  2,  5,  5,  6,  6,  5,  5},
1225 		{ 9,  9, 11, 11,  2,  2,  5,  5,  6,  6,  5,  5},
1226 		{ 9,  9, 11, 11,  2,  2,  5,  5,  6,  6,  5,  5},
1227 		{ 9,  9, 11, 11,  2,  2,  5,  5,  6,  6,  5,  5},
1228 		{ 9,  9, 11, 11,  2,  2,  5,  5,  6,  6,  5,  5},
1229 		{10,  9, 12, 11,  2,  2,  5,  5,  6,  6,  5,  5},
1230 		{10,  9, 12, 11,  2,  2,  6,  5,  7,  6,  6,  5},
1231 		{10, 10, 12, 12,  2,  2,  6,  5,  7,  6,  6,  5},
1232 		{10, 10, 12, 12,  2,  2,  6,  6,  7,  7,  6,  6},
1233 		{10, 10, 12, 12,  3,  2,  6,  6,  7,  7,  6,  6},
1234 		{10, 10, 12, 12,  3,  2,  6,  6,  7,  7,  6,  6},
1235 		{10, 10, 12, 12,  3,  2,  6,  6,  7,  7,  6,  6},
1236 		{10, 10, 12, 12,  3,  3,  6,  6,  7,  7,  6,  6},
1237 		{10, 10, 12, 12,  3,  3,  6,  6,  7,  7,  6,  6},
1238 		{10, 10, 12, 12,  3,  3,  6,  6,  7,  7,  6,  6},
1239 		{10, 10, 12, 12,  3,  3,  6,  6,  7,  7,  6,  6},
1240 		{10, 10, 12, 12,  3,  3,  6,  6,  7,  7,  6,  6},
1241 		{11, 10, 12, 12,  3,  3,  6,  6,  7,  7,  6,  6},
1242 		{11, 10, 14, 13,  3,  3,  6,  6,  7,  7,  6,  6},
1243 		{12, 10, 14, 13,  3,  3,  6,  6,  7,  7,  6,  6},
1244 		{12, 12, 14, 13,  3,  3,  7,  6,  7,  7,  7,  6},
1245 		{13, 12, 16, 15,  3,  3,  7,  6,  8,  7,  7,  6},
1246 		{13, 14, 16, 15,  4,  3,  7,  7,  8,  8,  7,  7},
1247 		{14, 14, 16, 17,  4,  3,  7,  7,  8,  8,  7,  7},
1248 		{14, 16, 18, 17,  4,  4,  8,  7,  8,  8,  8,  7},
1249 		{15, 16, 18, 19,  4,  4,  8,  7,  9,  8,  8,  7},
1250 		{15, 18, 18, 19,  4,  4,  8,  8,  9,  9,  8,  8},
1251 		{16, 18, 20, 21,  4,  4,  8,  8,  9,  9,  8,  8},
1252 		{16, 19, 20, 21,  5,  4,  9,  8, 10,  9,  9,  8},
1253 		{16, 19, 20, 23,  5,  5,  9,  9, 10, 10,  9,  9},
1254 		{17, 19, 22, 23,  5,  5,  9,  9, 10, 10,  9,  9},
1255 		{17, 20, 22, 25,  5,  5,  9,  9, 10, 10,  9,  9},
1256 		{17, 20, 22, 25,  5,  5,  9,  9, 10, 10,  9,  9},
1257 		{18, 20, 22, 25,  5,  5,  9,  9, 10, 10,  9,  9},
1258 		{18, 21, 24, 25,  5,  5,  9,  9, 11, 10,  9,  9},
1259 		{19, 21, 24, 27,  5,  5,  9,  9, 11, 11,  9,  9},
1260 		{19, 22, 24, 27,  5,  5, 10,  9, 11, 11, 10,  9},
1261 		{20, 22, 24, 27,  6,  5, 10, 10, 11, 11, 10, 10},
1262 		{20, 23, 26, 27,  6,  6, 10, 10, 12, 12, 10, 10},
1263 		{20, 23, 26, 29,  6,  6, 10, 10, 12, 12, 10, 10},
1264 		{21, 24, 26, 29,  6,  6, 10, 10, 12, 12, 10, 10},
1265 		{21, 24, 26, 29,  6,  6, 11, 10, 12, 13, 11, 10},
1266 		{22, 25, 28, 29,  6,  6, 11, 11, 13, 13, 11, 11},
1267 		{22, 25, 28, 31,  6,  6, 11, 11, 13, 13, 11, 11},
1268 		{22, 26, 28, 31,  6,  6, 11, 11, 13, 14, 11, 11},
1269 		{23, 26, 30, 31,  7,  6, 12, 11, 14, 14, 12, 11},
1270 		{23, 27, 30, 33,  7,  7, 12, 12, 14, 14, 12, 12},
1271 		{23, 27, 30, 33,  7,  7, 12, 12, 14, 15, 12, 12},
1272 		{24, 28, 32, 33,  7,  7, 12, 12, 15, 15, 12, 12},
1273 		{24, 28, 32, 33,  7,  7, 12, 12, 15, 16, 12, 12},
1274 		{24, 29, 32, 35,  7,  7, 12, 12, 15, 16, 12, 12},
1275 		{25, 29, 32, 35,  7,  7, 12, 12, 15, 17, 12, 12},
1276 		{25, 30, 32, 35,  7,  7, 12, 12, 15, 17, 12, 12},
1277 		{25, 30, 32, 35,  7,  7, 12, 12, 15, 17, 12, 12},
1278 	};
1279 
1280 	srup = 0;
1281 	srun = 0;
1282 
1283 	if (s->selected_timings.mem_clock == MEM_CLOCK_667MHz) {
1284 		rcomp1 = 0x00050431;
1285 	} else {
1286 		rcomp1 = 0x00050542;
1287 	}
1288 	if (s->selected_timings.fsb_clock == FSB_CLOCK_667MHz) {
1289 		rcomp2 = 0x14c42827;
1290 	} else {
1291 		rcomp2 = 0x19042827;
1292 	}
1293 
1294 	FOR_EACH_RCOMP_GROUP(i) {
1295 		reg8 = rcompupdate[i];
1296 		mchbar_clrsetbits8(C0RCOMPCTRLx(i), 1 << 0, reg8);
1297 		mchbar_clrbits8(C0RCOMPCTRLx(i), 1 << 1);
1298 
1299 		reg16 = rcompslew;
1300 		mchbar_clrsetbits16(C0RCOMPCTRLx(i), 0xf << 12, reg16 << 12);
1301 
1302 		mchbar_write8(C0RCOMPMULTx(i), rcompstr[i]);
1303 		mchbar_write16(C0SCOMPVREFx(i), rcompscomp[i]);
1304 		mchbar_clrsetbits8(C0DCOMPx(i), 0x03, rcompdelay[i]);
1305 		if (i == 2) {
1306 			/* FIXME: Why are we rewriting this? */
1307 			mchbar_clrsetbits16(C0RCOMPCTRLx(i), 0xf << 12, reg16 << 12);
1308 
1309 			mchbar_write8(C0RCOMPMULTx(i), rcompstr2[s->dimm_config[0]]);
1310 			mchbar_write16(C0SCOMPVREFx(i), rcompscomp2[s->dimm_config[0]]);
1311 			mchbar_clrsetbits8(C0DCOMPx(i), 0x03, rcompdelay2[s->dimm_config[0]]);
1312 		}
1313 
1314 		mchbar_clrbits16(C0SLEWBASEx(i), 0x7f7f);
1315 
1316 		/* FIXME: Why not do a single dword write? */
1317 		mchbar_clrbits16(C0SLEWPULUTx(i),     0x3f3f);
1318 		mchbar_clrbits16(C0SLEWPULUTx(i) + 2, 0x3f3f);
1319 
1320 		/* FIXME: Why not do a single dword write? */
1321 		mchbar_clrbits16(C0SLEWPDLUTx(i),     0x3f3f);
1322 		mchbar_clrbits16(C0SLEWPDLUTx(i) + 2, 0x3f3f);
1323 	}
1324 
1325 	/* FIXME: Hardcoded */
1326 	mchbar_clrsetbits8(C0ODTRECORDX,    0x3f, 0x36);
1327 	mchbar_clrsetbits8(C0DQSODTRECORDX, 0x3f, 0x36);
1328 
1329 	FOR_EACH_RCOMP_GROUP(i) {
1330 		mchbar_clrbits8(C0RCOMPCTRLx(i), 3 << 5);
1331 		mchbar_clrbits16(C0RCOMPCTRLx(i) + 2, 0x0706);
1332 		mchbar_clrbits16(C0RCOMPOSVx(i), 0x7f7f);
1333 		mchbar_clrbits16(C0SCOMPOFFx(i), 0x3f3f);
1334 		mchbar_clrbits16(C0DCOMPOFFx(i), 0x1f1f);
1335 		mchbar_clrbits8(C0DCOMPOFFx(i) + 2, 0x1f);
1336 	}
1337 
1338 	mchbar_clrbits16(C0ODTRECORDX,     0xffc0);
1339 	mchbar_clrbits16(C0ODTRECORDX + 2, 0x000f);
1340 
1341 	/* FIXME: Why not do a single dword write? */
1342 	mchbar_clrbits16(C0DQSODTRECORDX,     0xffc0);
1343 	mchbar_clrbits16(C0DQSODTRECORDX + 2, 0x000f);
1344 
1345 	FOR_EACH_RCOMP_GROUP(i) {
1346 		mchbar_write16(C0SCOMPOVRx(i), rcompf[i]);
1347 
1348 		/* FIXME: Why not do a single dword write? */
1349 		mchbar_write16(C0DCOMPOVRx(i) + 0, 0x1219);
1350 		mchbar_write16(C0DCOMPOVRx(i) + 2, 0x000c);
1351 	}
1352 
1353 	mchbar_clrsetbits32(DCMEASBUFOVR, 0x001f1f1f, 0x000c1219);
1354 
1355 	/* FIXME: Why not do a single word write? */
1356 	mchbar_clrsetbits16(XCOMPSDR0BNS, 0x1f << 8, 0x12 << 8);
1357 	mchbar_clrsetbits8(XCOMPSDR0BNS,  0x1f << 0, 0x12 << 0);
1358 
1359 	mchbar_write32(COMPCTRL3, 0x007c9007);
1360 	mchbar_write32(OFREQDELSEL, rcomp1);
1361 	mchbar_write16(XCOMPCMNBNS, 0x1f7f);
1362 	mchbar_write32(COMPCTRL2, rcomp2);
1363 	mchbar_clrsetbits16(XCOMPDFCTRL, 0xf, 1);
1364 	mchbar_write16(ZQCALCTRL, 0x0134);
1365 	mchbar_write32(COMPCTRL1, 0x4c293600);
1366 
1367 	mchbar_clrsetbits8(COMPCTRL1 + 3, 0x44, 1 << 6 | 1 << 2);
1368 	mchbar_clrbits16(XCOMPSDR0BNS, 1 << 13);
1369 	mchbar_clrbits8(XCOMPSDR0BNS, 1 << 5);
1370 
1371 	FOR_EACH_RCOMP_GROUP(i) {
1372 		/* POR values are zero */
1373 		mchbar_clrbits8(C0RCOMPCTRLx(i) + 2, 0x71);
1374 	}
1375 
1376 	if ((mchbar_read32(COMPCTRL1) & (1 << 30)) == 0) {
1377 		/* Start COMP */
1378 		mchbar_setbits8(COMPCTRL1, 1 << 0);
1379 
1380 		/* Wait until COMP is done */
1381 		while ((mchbar_read8(COMPCTRL1) & 1) != 0)
1382 			;
1383 
1384 		reg32 = mchbar_read32(XCOMP);
1385 		rcompp = (u8)((reg32 & ~(1 << 31)) >> 24);
1386 		rcompn = (u8)((reg32 & ~(0xff800000)) >> 16);
1387 
1388 		FOR_EACH_RCOMP_GROUP(i) {
1389 			srup = (mchbar_read8(C0RCOMPCTRLx(i) + 1) & 0xc0) >> 6;
1390 			srun = (mchbar_read8(C0RCOMPCTRLx(i) + 1) & 0x30) >> 4;
1391 
1392 			/* FIXME: Why not do a single word write? */
1393 			reg16 = (u16)(rcompp - (1 << (srup + 1))) << 8;
1394 			mchbar_clrsetbits16(C0SLEWBASEx(i), 0x7f << 8, reg16);
1395 
1396 			reg16 = (u16)(rcompn - (1 << (srun + 1)));
1397 			mchbar_clrsetbits8(C0SLEWBASEx(i), 0x7f, (u8)reg16);
1398 		}
1399 
1400 		reg8 = rcompp - (1 << (srup + 1));
1401 		for (i = 0, j = reg8; i < 4; i++, j += (1 << srup)) {
1402 			mchbar_clrsetbits8(C0SLEWPULUTx(0) + i, 0x3f, rcomplut[j][0]);
1403 		}
1404 
1405 		for (i = 0, j = reg8; i < 4; i++, j += (1 << srup)) {
1406 			if (s->dimm_config[0] < 3 || s->dimm_config[0] == 5) {
1407 				mchbar_clrsetbits8(C0SLEWPULUTx(2) + i, 0x3f, rcomplut[j][10]);
1408 			}
1409 		}
1410 
1411 		for (i = 0, j = reg8; i < 4; i++, j += (1 << srup)) {
1412 			mchbar_clrsetbits8(C0SLEWPULUTx(3) + i, 0x3f, rcomplut[j][6]);
1413 			mchbar_clrsetbits8(C0SLEWPULUTx(4) + i, 0x3f, rcomplut[j][6]);
1414 		}
1415 
1416 		for (i = 0, j = reg8; i < 4; i++, j += (1 << srup)) {
1417 			mchbar_clrsetbits8(C0SLEWPULUTx(5) + i, 0x3f, rcomplut[j][8]);
1418 			mchbar_clrsetbits8(C0SLEWPULUTx(6) + i, 0x3f, rcomplut[j][8]);
1419 		}
1420 
1421 		reg8 = rcompn - (1 << (srun + 1));
1422 		for (i = 0, j = reg8; i < 4; i++, j += (1 << srun)) {
1423 			mchbar_clrsetbits8(C0SLEWPDLUTx(0) + i, 0x3f, rcomplut[j][1]);
1424 		}
1425 
1426 		for (i = 0, j = reg8; i < 4; i++, j += (1 << srun)) {
1427 			if (s->dimm_config[0] < 3 || s->dimm_config[0] == 5) {
1428 				mchbar_clrsetbits8(C0SLEWPDLUTx(2) + i, 0x3f, rcomplut[j][11]);
1429 			}
1430 		}
1431 
1432 		for (i = 0, j = reg8; i < 4; i++, j += (1 << srun)) {
1433 			mchbar_clrsetbits8(C0SLEWPDLUTx(3) + i, 0x3f, rcomplut[j][7]);
1434 			mchbar_clrsetbits8(C0SLEWPDLUTx(4) + i, 0x3f, rcomplut[j][7]);
1435 		}
1436 
1437 		for (i = 0, j = reg8; i < 4; i++, j += (1 << srun)) {
1438 			mchbar_clrsetbits8(C0SLEWPDLUTx(5) + i, 0x3f, rcomplut[j][9]);
1439 			mchbar_clrsetbits8(C0SLEWPDLUTx(6) + i, 0x3f, rcomplut[j][9]);
1440 		}
1441 	}
1442 	mchbar_setbits8(COMPCTRL1, 1 << 0);
1443 }
1444 
1445 /* FIXME: The ODT tables are for DDR2 only! */
sdram_odt(struct sysinfo * s)1446 static void sdram_odt(struct sysinfo *s)
1447 {
1448 	u8 rankindex = 0;
1449 
1450 	static const u16 odt_rankctrl[16] = {
1451 	/*	 NC_NC,  1R_NC,     NV,  2R_NC,  NC_1R,  1R_1R,     NV,  2R_1R, */
1452 		0x0000, 0x0000, 0x0000, 0x0000, 0x0044, 0x1111, 0x0000, 0x1111,
1453 	/*	    NV,     NV,     NV,     NV,  NC_2R,  1R_2R,     NV,  2R_2R, */
1454 		0x0000, 0x0000, 0x0000, 0x0000, 0x0044, 0x1111, 0x0000, 0x1111,
1455 	};
1456 	static const u16 odt_matrix[16] = {
1457 	/*	 NC_NC,  1R_NC,     NV,  2R_NC,  NC_1R,  1R_1R,     NV,  2R_1R, */
1458 		0x0000, 0x0011, 0x0000, 0x0011, 0x0000, 0x4444, 0x0000, 0x4444,
1459 	/*	    NV,     NV,     NV,     NV,  NC_2R,  1R_2R,     NV,  2R_2R, */
1460 		0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4444, 0x0000, 0x4444,
1461 	};
1462 
1463 	switch (s->dimms[0].ranks) {
1464 	case 0:
1465 		if (s->dimms[1].ranks == 0) {
1466 			rankindex = 0;
1467 		} else if (s->dimms[1].ranks == 1) {
1468 			rankindex = 4;
1469 		} else if (s->dimms[1].ranks == 2) {
1470 			rankindex = 12;
1471 		}
1472 		break;
1473 	case 1:
1474 		if (s->dimms[1].ranks == 0) {
1475 			rankindex = 1;
1476 		} else if (s->dimms[1].ranks == 1) {
1477 			rankindex = 5;
1478 		} else if (s->dimms[1].ranks == 2) {
1479 			rankindex = 13;
1480 		}
1481 		break;
1482 	case 2:
1483 		if (s->dimms[1].ranks == 0) {
1484 			rankindex = 3;
1485 		} else if (s->dimms[1].ranks == 1) {
1486 			rankindex = 7;
1487 		} else if (s->dimms[1].ranks == 2) {
1488 			rankindex = 15;
1489 		}
1490 		break;
1491 	}
1492 
1493 	/* Program the ODT Matrix */
1494 	mchbar_write16(C0ODT, odt_matrix[rankindex]);
1495 
1496 	/* Program the ODT Rank Control */
1497 	mchbar_write16(C0ODTRKCTRL, odt_rankctrl[rankindex]);
1498 }
1499 
sdram_mmap(struct sysinfo * s)1500 static void sdram_mmap(struct sysinfo *s)
1501 {
1502 	TABLE u32 w260[7] = {0, 0x400001,  0xc00001, 0x500000,  0xf00000,  0xc00001,  0xf00000};
1503 	TABLE u32 w208[7] = {0,  0x10000, 0x1010000,  0x10001, 0x1010101, 0x1010000, 0x1010101};
1504 	TABLE u32 w200[7] = {0,        0,         0,  0x20002,   0x40002,         0,   0x40002};
1505 	TABLE u32 w204[7] = {0,  0x20002,   0x40002,  0x40004,   0x80006,   0x40002,   0x80006};
1506 
1507 	TABLE u16 tolud[7]  = {2048, 2048, 4096, 4096, 8192, 4096, 8192};
1508 	TABLE u16 tom[7]    = {   2,    2,    4,    4,    8,    4,    8};
1509 	TABLE u16 touud[7]  = { 128,  128,  256,  256,  512,  256,  512};
1510 	TABLE u32 gbsm[7]   = {1 << 27, 1 << 27, 1 << 28, 1 << 27, 1 << 29, 1 << 28, 1 << 29};
1511 	TABLE u32 bgsm[7]   = {1 << 27, 1 << 27, 1 << 28, 1 << 27, 1 << 29, 1 << 28, 1 << 29};
1512 	TABLE u32 tsegmb[7] = {1 << 27, 1 << 27, 1 << 28, 1 << 27, 1 << 29, 1 << 28, 1 << 29};
1513 
1514 	if ((s->dimm_config[0] < 3) && rank_is_populated(s->dimms, 0, 0)) {
1515 		if (s->dimms[0].sides > 1) {
1516 			// 2R/NC
1517 			mchbar_clrsetbits32(C0CKECTRL, 1, 0x300001);
1518 			mchbar_write32(C0DRA01, 0x00000101);
1519 			mchbar_write32(C0DRB0, 0x00040002);
1520 			mchbar_write32(C0DRB2, w204[s->dimm_config[0]]);
1521 		} else {
1522 			// 1R/NC
1523 			mchbar_clrsetbits32(C0CKECTRL, 1, 0x100001);
1524 			mchbar_write32(C0DRA01, 0x00000001);
1525 			mchbar_write32(C0DRB0, 0x00020002);
1526 			mchbar_write32(C0DRB2, w204[s->dimm_config[0]]);
1527 		}
1528 	} else if ((s->dimm_config[0] == 5) && rank_is_populated(s->dimms, 0, 0)) {
1529 		mchbar_clrsetbits32(C0CKECTRL, 1, 0x300001);
1530 		mchbar_write32(C0DRA01, 0x00000101);
1531 		mchbar_write32(C0DRB0, 0x00040002);
1532 		mchbar_write32(C0DRB2, 0x00040004);
1533 	} else {
1534 		mchbar_clrsetbits32(C0CKECTRL, 1, w260[s->dimm_config[0]]);
1535 		mchbar_write32(C0DRA01, w208[s->dimm_config[0]]);
1536 		mchbar_write32(C0DRB0, w200[s->dimm_config[0]]);
1537 		mchbar_write32(C0DRB2, w204[s->dimm_config[0]]);
1538 	}
1539 	pci_write_config16(HOST_BRIDGE, 0xb0,  tolud[s->dimm_config[0]]);
1540 	pci_write_config16(HOST_BRIDGE, 0xa0,    tom[s->dimm_config[0]]);
1541 	pci_write_config16(HOST_BRIDGE, 0xa2,  touud[s->dimm_config[0]]);
1542 	pci_write_config32(HOST_BRIDGE, 0xa4,   gbsm[s->dimm_config[0]]);
1543 	pci_write_config32(HOST_BRIDGE, 0xa8,   bgsm[s->dimm_config[0]]);
1544 	pci_write_config32(HOST_BRIDGE, 0xac, tsegmb[s->dimm_config[0]]);
1545 }
1546 
sdram_checkrcompoverride(void)1547 static u8 sdram_checkrcompoverride(void)
1548 {
1549 	u32 xcomp;
1550 	u8 aa, bb, a, b, c, d;
1551 
1552 	xcomp = mchbar_read32(XCOMP);
1553 	a = (u8)((xcomp & 0x7f000000) >> 24);
1554 	b = (u8)((xcomp & 0x007f0000) >> 16);
1555 	c = (u8)((xcomp & 0x00003f00) >>  8);
1556 	d = (u8)((xcomp & 0x0000003f) >>  0);
1557 
1558 	if (a > b) {
1559 		aa = a - b;
1560 	} else {
1561 		aa = b - a;
1562 	}
1563 	if (c > d) {
1564 		bb = c - d;
1565 	} else {
1566 		bb = d - c;
1567 	}
1568 	if ((aa > 18) || (bb > 7) || (a <= 5) || (b <= 5) || (c <= 5) || (d <= 5) ||
1569 			(a >= 0x7a) || (b >= 0x7a) || (c >= 0x3a) || (d >= 0x3a)) {
1570 		mchbar_write32(RCMEASBUFXOVR, 0x9718a729);
1571 		return 1;
1572 	}
1573 	return 0;
1574 }
1575 
sdram_rcompupdate(struct sysinfo * s)1576 static void sdram_rcompupdate(struct sysinfo *s)
1577 {
1578 	u8 i, ok;
1579 	u32 reg32a, reg32b;
1580 
1581 	ok = 0;
1582 	mchbar_clrbits8(XCOMPDFCTRL, 1 << 3);
1583 	mchbar_clrbits8(COMPCTRL1, 1 << 7);
1584 	for (i = 0; i < 3; i++) {
1585 		mchbar_setbits8(COMPCTRL1, 1 << 0);
1586 		hpet_udelay(1000);
1587 		while ((mchbar_read8(COMPCTRL1) & 1) != 0)
1588 			;
1589 		ok |= sdram_checkrcompoverride();
1590 	}
1591 	if (!ok) {
1592 		reg32a = mchbar_read32(XCOMP);
1593 		reg32b = ((reg32a >> 16) & 0x0000ffff);
1594 		reg32a = ((reg32a << 16) & 0xffff0000) | reg32b;
1595 		reg32a |= (1 << 31) | (1 << 15);
1596 		mchbar_write32(RCMEASBUFXOVR, reg32a);
1597 	}
1598 	mchbar_setbits8(COMPCTRL1, 1 << 0);
1599 	hpet_udelay(1000);
1600 	while ((mchbar_read8(COMPCTRL1) & 1) != 0)
1601 		;
1602 }
1603 
1604 static void __attribute__((noinline))
sdram_jedec(struct sysinfo * s,u8 rank,u8 jmode,u16 jval)1605 sdram_jedec(struct sysinfo *s, u8 rank, u8 jmode, u16 jval)
1606 {
1607 	u32 reg32;
1608 
1609 	reg32 = jval << 3;
1610 	reg32 |= rank * (1 << 27);
1611 	mchbar_clrsetbits8(C0JEDEC, 0x3e, jmode);
1612 	read32p(reg32);
1613 	barrier();
1614 	hpet_udelay(1); // 1us
1615 }
1616 
sdram_zqcl(struct sysinfo * s)1617 static void sdram_zqcl(struct sysinfo *s)
1618 {
1619 	if (s->boot_path == BOOT_PATH_RESUME) {
1620 		mchbar_setbits32(C0CKECTRL, 1 << 27);
1621 		mchbar_clrsetbits8(C0JEDEC, 0x0e, NORMAL_OP_CMD);
1622 		mchbar_clrbits8(C0JEDEC, 3 << 4);
1623 		mchbar_clrsetbits32(C0REFRCTRL2, 3 << 30, 3 << 30);
1624 	}
1625 }
1626 
sdram_jedecinit(struct sysinfo * s)1627 static void sdram_jedecinit(struct sysinfo *s)
1628 {
1629 	u8 r, i, ch;
1630 	u16 reg16, mrs, rttnom;
1631 	struct jedeclist {
1632 		char debug[15];
1633 		u8 cmd;
1634 		u16 val;
1635 	};
1636 
1637 	static const struct jedeclist jedec[12] = {
1638 			{ "   NOP        ", NOP_CMD, 0 },
1639 			{ "   PRE CHARGE ", PRE_CHARGE_CMD, 0 },
1640 			{ "   EMRS2      ", EMRS2_CMD, 0 },
1641 			{ "   EMRS3      ", EMRS3_CMD, 0 },
1642 			{ "   EMRS1      ", EMRS1_CMD, 0 },
1643 			{ "   DLL RESET  ", MRS_CMD, (1 << 8) },
1644 			{ "   PRE CHARGE ", PRE_CHARGE_CMD, 0 },
1645 			{ "   AUTOREFRESH", CBR_CMD, 0 },
1646 			{ "   AUTOREFRESH", CBR_CMD, 0 },
1647 			{ "   INITIALISE ", MRS_CMD, 0 },
1648 			{ "   EMRS1 OCD  ", EMRS1_CMD, (1 << 9) | (1 << 8) | (1 << 7) },
1649 			{ "   EMRS1 EXIT ", EMRS1_CMD, 0 }
1650 	};
1651 
1652 	mrs = (s->selected_timings.CAS << 4) |
1653 		((s->selected_timings.tWR - 1) << 9) | (1 << 3) | (1 << 1) | 3;
1654 
1655 	rttnom = (1 << 2);
1656 	if (rank_is_populated(s->dimms, 0, 0) && rank_is_populated(s->dimms, 0, 2)) {
1657 		rttnom |= (1 << 6);
1658 	}
1659 
1660 	hpet_udelay(200); // 200us
1661 	reg16 = 0;
1662 	FOR_EACH_POPULATED_RANK(s->dimms, ch, r) {
1663 		for (i = 0; i < 12; i++) {
1664 			PRINTK_DEBUG("Rank:%d Jedec:%14s...", r, jedec[i].debug);
1665 			reg16 = jedec[i].val;
1666 			switch (jedec[i].cmd) {
1667 			case EMRS1_CMD:
1668 				reg16 |= rttnom;
1669 				break;
1670 			case MRS_CMD:
1671 				reg16 |= mrs;
1672 				break;
1673 			default:
1674 				break;
1675 			}
1676 			sdram_jedec(s, r, jedec[i].cmd, reg16);
1677 			PRINTK_DEBUG("done\n");
1678 		}
1679 	}
1680 }
1681 
sdram_misc(struct sysinfo * s)1682 static void sdram_misc(struct sysinfo *s)
1683 {
1684 	u32 reg32;
1685 
1686 	reg32 = 0;
1687 	reg32 |= (4 << 13);
1688 	reg32 |= (6 <<  8);
1689 	mchbar_clrsetbits32(C0DYNRDCTRL, 0x3ff << 8, reg32);
1690 	mchbar_clrbits8(C0DYNRDCTRL, 1 << 7);
1691 	mchbar_setbits8(C0REFRCTRL + 3, 1 << 0);
1692 	if (s->boot_path != BOOT_PATH_RESUME) {
1693 		mchbar_clrsetbits8(C0JEDEC, 0x0e, NORMAL_OP_CMD);
1694 		mchbar_clrbits8(C0JEDEC, 3 << 4);
1695 	} else {
1696 		sdram_zqcl(s);
1697 	}
1698 }
1699 
sdram_checkreset(void)1700 static void sdram_checkreset(void)
1701 {
1702 	u8 pmcon2, pmcon3, reset;
1703 
1704 	pmcon2 = pci_read_config8(PCI_DEV(0, 0x1f, 0), 0xa2);
1705 	pmcon3 = pci_read_config8(PCI_DEV(0, 0x1f, 0), 0xa4);
1706 	pmcon3 &= ~0x2;
1707 	if (pmcon2 & 0x80) {
1708 		pmcon2 &= ~0x80;
1709 		reset = 1;
1710 	} else {
1711 		pmcon2 |= 0x80;
1712 		reset = 0;
1713 	}
1714 	if (pmcon2 & 0x4) {
1715 		pmcon2 |= 0x4;
1716 		pmcon3 = (pmcon3 & ~0x30) | 0x30;
1717 		pmcon3 |= (1 << 3);
1718 	}
1719 	pci_write_config8(PCI_DEV(0, 0x1f, 0), 0xa2, pmcon2);
1720 	pci_write_config8(PCI_DEV(0, 0x1f, 0), 0xa4, pmcon3);
1721 	if (reset)
1722 		full_reset();
1723 }
1724 
sdram_dradrb(struct sysinfo * s)1725 static void sdram_dradrb(struct sysinfo *s)
1726 {
1727 	u8 i, reg8, ch, r;
1728 	u32 reg32, ind, c0dra, c0drb, dra;
1729 	u16 addr;
1730 	i = 0;
1731 	static const u8 dratab[2][2][2][4] =
1732 	{{
1733 		{
1734 		 {0xff, 0xff, 0xff, 0xff},
1735 		 {0xff, 0x00, 0x02, 0xff}
1736 		},
1737 		{
1738 		 {0xff, 0x01, 0xff, 0xff},
1739 		 {0xff, 0x03, 0xff, 0x06}
1740 		}
1741 	},
1742 	{
1743 		{
1744 		 {0xff, 0xff, 0xff, 0xff},
1745 		 {0xff, 0x04, 0x06, 0x08}
1746 		},
1747 		{
1748 		 {0xff, 0xff, 0xff, 0xff},
1749 		 {0x05, 0x07, 0x09, 0xff}
1750 		}
1751 	}};
1752 
1753 	static const u8 dradrb[10][6]  =  {
1754 		//Row   Col   Bank  Width         DRB
1755 		{0x01,  0x01,  0x00,  0x08,  0,  0x04},
1756 		{0x01,  0x00,  0x00,  0x10,  0,  0x02},
1757 		{0x02,  0x01,  0x00,  0x08,  1,  0x08},
1758 		{0x01,  0x01,  0x00,  0x10,  1,  0x04},
1759 		{0x01,  0x01,  0x01,  0x08,  1,  0x08},
1760 		{0x00,  0x01,  0x01,  0x10,  1,  0x04},
1761 		{0x02,  0x01,  0x01,  0x08,  2,  0x10},
1762 		{0x01,  0x01,  0x01,  0x10,  2,  0x08},
1763 		{0x03,  0x01,  0x01,  0x08,  3,  0x20},
1764 		{0x02,  0x01,  0x01,  0x10,  3,  0x10},
1765 	};
1766 
1767 	reg32 = 0;
1768 	FOR_EACH_POPULATED_RANK(s->dimms, ch, r) {
1769 		i = r / 2;
1770 		PRINTK_DEBUG("RANK %d PRESENT\n", r);
1771 		dra = dratab
1772 			[s->dimms[i].banks]
1773 			[s->dimms[i].width]
1774 			[s->dimms[i].cols - 9]
1775 			[s->dimms[i].rows - 12];
1776 
1777 		if (s->dimms[i].banks == 1) {
1778 			dra |= (1 << 7);
1779 		}
1780 		reg32 |= (dra << (r * 8));
1781 	}
1782 	mchbar_write32(C0DRA01, reg32);
1783 	c0dra = reg32;
1784 	PRINTK_DEBUG("C0DRA = 0x%08x\n", c0dra);
1785 
1786 	reg32 = 0;
1787 	FOR_EACH_POPULATED_RANK(s->dimms, ch, r) {
1788 		reg32 |= (1 << r);
1789 	}
1790 	reg8 = (u8)(reg32 << 4) & 0xf0;
1791 	mchbar_clrsetbits8(C0CKECTRL + 2, 0xf0, reg8);
1792 
1793 	if (ONLY_DIMMA_IS_POPULATED(s->dimms, 0) || ONLY_DIMMB_IS_POPULATED(s->dimms, 0)) {
1794 		mchbar_setbits8(C0CKECTRL, 1 << 0);
1795 	}
1796 
1797 	addr = C0DRB0;
1798 	c0drb = 0;
1799 	FOR_EACH_RANK(ch, r) {
1800 		if (rank_is_populated(s->dimms, ch, r)) {
1801 			ind = (c0dra >> (8 * r)) & 0x7f;
1802 			c0drb = (u16)(c0drb + dradrb[ind][5]);
1803 			s->channel_capacity[0] += dradrb[ind][5] << 6;
1804 		}
1805 		mchbar_write16(addr, c0drb);
1806 		addr += 2;
1807 	}
1808 	printk(BIOS_DEBUG, "Total memory = %dMB\n", s->channel_capacity[0]);
1809 }
1810 
sampledqs(u32 dqshighaddr,u32 strobeaddr,u8 highlow,u8 count)1811 static u8 sampledqs(u32 dqshighaddr, u32 strobeaddr, u8 highlow, u8 count)
1812 {
1813 	u8 dqsmatches = 1;
1814 	while (count--) {
1815 		mchbar_clrbits8(C0RSTCTL, 1 << 1);
1816 		hpet_udelay(1);
1817 		mchbar_setbits8(C0RSTCTL, 1 << 1);
1818 		hpet_udelay(1);
1819 		barrier();
1820 		read32p(strobeaddr);
1821 		barrier();
1822 		hpet_udelay(1);
1823 
1824 		if (((mchbar_read8(dqshighaddr) & (1 << 6)) >> 6) != highlow) {
1825 			dqsmatches = 0;
1826 		}
1827 	}
1828 
1829 	return dqsmatches;
1830 }
1831 
rcvenclock(u8 * coarse,u8 * medium,u8 lane)1832 static void rcvenclock(u8 *coarse, u8 *medium, u8 lane)
1833 {
1834 	if (*medium < 3) {
1835 		(*medium)++;
1836 		mchbar_clrsetbits16(C0RCVMISCCTL2, 3 << (lane * 2), *medium << (lane * 2));
1837 	} else {
1838 		*medium = 0;
1839 		(*coarse)++;
1840 		mchbar_clrsetbits32(C0STATRDCTRL, 0xf << 16, *coarse << 16);
1841 		mchbar_clrsetbits16(C0RCVMISCCTL2, 3 << (lane * 2), *medium << (lane * 2));
1842 	}
1843 }
1844 
sdram_rcven(struct sysinfo * s)1845 static void sdram_rcven(struct sysinfo *s)
1846 {
1847 	u8 coarse, savecoarse;
1848 	u8 medium, savemedium;
1849 	u8 pi, savepi;
1850 	u8 lane;
1851 	u8 lanecoarse[8] = {0};
1852 	u8 minlanecoarse = 0xff;
1853 	u8 offset;
1854 	u8 maxlane = 8;
1855 	/* Since dra/drb is already set up we know that at address 0x00000000
1856 	   we will always find the first available rank */
1857 	u32 strobeaddr = 0;
1858 	u32 dqshighaddr;
1859 
1860 	mchbar_clrbits8(C0RSTCTL, 3 << 2);
1861 	mchbar_clrbits8(CMNDQFIFORST, 1 << 7);
1862 
1863 	PRINTK_DEBUG("rcven 0\n");
1864 	for (lane = 0; lane < maxlane; lane++) {
1865 		PRINTK_DEBUG("rcven lane %d\n", lane);
1866 // trylaneagain:
1867 		dqshighaddr = C0MISCCTLy(lane);
1868 
1869 		coarse = s->selected_timings.CAS + 1;
1870 		pi = 0;
1871 		medium = 0;
1872 
1873 		mchbar_clrsetbits32(C0STATRDCTRL, 0xf << 16, coarse << 16);
1874 		mchbar_clrsetbits16(C0RCVMISCCTL2, 3 << (lane * 2), medium << (lane * 2));
1875 
1876 		mchbar_clrbits8(C0RXRCVyDLL(lane), 0x3f);
1877 
1878 		savecoarse = coarse;
1879 		savemedium = medium;
1880 		savepi = pi;
1881 
1882 		PRINTK_DEBUG("rcven 0.1\n");
1883 
1884 		// XXX comment out
1885 		// mchbar_clrsetbits16(C0RCVMISCCTL1, 3 << (lane * 2), 1 << (lane * 2));
1886 
1887 		while (sampledqs(dqshighaddr, strobeaddr, 0, 3) == 0) {
1888 			// printk(BIOS_DEBUG, "coarse=%d medium=%d\n", coarse, medium);
1889 			rcvenclock(&coarse, &medium, lane);
1890 			if (coarse > 0xf) {
1891 				PRINTK_DEBUG("Error: coarse > 0xf\n");
1892 				// goto trylaneagain;
1893 				break;
1894 			}
1895 		}
1896 		PRINTK_DEBUG("rcven 0.2\n");
1897 
1898 		savecoarse = coarse;
1899 		savemedium = medium;
1900 		rcvenclock(&coarse, &medium, lane);
1901 
1902 		while (sampledqs(dqshighaddr, strobeaddr, 1, 3) == 0) {
1903 			savecoarse = coarse;
1904 			savemedium = medium;
1905 			rcvenclock(&coarse, &medium, lane);
1906 			if (coarse > 0xf) {
1907 				PRINTK_DEBUG("Error: coarse > 0xf\n");
1908 				//goto trylaneagain;
1909 				break;
1910 			}
1911 		}
1912 
1913 		PRINTK_DEBUG("rcven 0.3\n");
1914 		coarse = savecoarse;
1915 		medium = savemedium;
1916 		mchbar_clrsetbits32(C0STATRDCTRL, 0xf << 16, coarse << 16);
1917 		mchbar_clrsetbits16(C0RCVMISCCTL2, 3 << (lane * 2), medium << (lane * 2));
1918 
1919 		while (sampledqs(dqshighaddr, strobeaddr, 1, 3) == 0) {
1920 			savepi = pi;
1921 			pi++;
1922 			if (pi > s->maxpi) {
1923 				// if (s->nodll) {
1924 					pi = savepi = s->maxpi;
1925 					break;
1926 				// }
1927 			}
1928 			mchbar_clrsetbits8(C0RXRCVyDLL(lane), 0x3f, pi << s->pioffset);
1929 		}
1930 		PRINTK_DEBUG("rcven 0.4\n");
1931 
1932 		pi = savepi;
1933 		mchbar_clrsetbits8(C0RXRCVyDLL(lane), 0x3f, pi << s->pioffset);
1934 		rcvenclock(&coarse, &medium, lane);
1935 
1936 		if (sampledqs(dqshighaddr, strobeaddr, 1, 1) == 0) {
1937 			PRINTK_DEBUG("Error: DQS not high\n");
1938 			// goto trylaneagain;
1939 		}
1940 		PRINTK_DEBUG("rcven 0.5\n");
1941 		while (sampledqs(dqshighaddr, strobeaddr, 0, 3) == 0) {
1942 			coarse--;
1943 			mchbar_clrsetbits32(C0STATRDCTRL, 0xf << 16, coarse << 16);
1944 			if (coarse == 0) {
1945 				PRINTK_DEBUG("Error: DQS did not hit 0\n");
1946 				break;
1947 			}
1948 		}
1949 
1950 		PRINTK_DEBUG("rcven 0.6\n");
1951 		rcvenclock(&coarse, &medium, lane);
1952 		s->pi[lane] = pi;
1953 		lanecoarse[lane] = coarse;
1954 	}
1955 
1956 	PRINTK_DEBUG("rcven 1\n");
1957 
1958 	lane = maxlane;
1959 	do {
1960 		lane--;
1961 		if (minlanecoarse > lanecoarse[lane]) {
1962 			minlanecoarse = lanecoarse[lane];
1963 		}
1964 	} while (lane != 0);
1965 
1966 	lane = maxlane;
1967 	do {
1968 		lane--;
1969 		offset = lanecoarse[lane] - minlanecoarse;
1970 		mchbar_clrsetbits16(C0COARSEDLY0, 3 << (lane * 2), offset << (lane * 2));
1971 	} while (lane != 0);
1972 
1973 	mchbar_clrsetbits32(C0STATRDCTRL, 0xf << 16, minlanecoarse << 16);
1974 
1975 	s->coarsectrl   = minlanecoarse;
1976 	s->coarsedelay  = mchbar_read16(C0COARSEDLY0);
1977 	s->mediumphase  = mchbar_read16(C0RCVMISCCTL2);
1978 	s->readptrdelay = mchbar_read16(C0RCVMISCCTL1);
1979 
1980 	PRINTK_DEBUG("rcven 2\n");
1981 	mchbar_clrbits8(C0RSTCTL, 7 << 1);
1982 	mchbar_setbits8(C0RSTCTL, 1 << 1);
1983 	mchbar_setbits8(C0RSTCTL, 1 << 2);
1984 	mchbar_setbits8(C0RSTCTL, 1 << 3);
1985 
1986 	mchbar_setbits8(CMNDQFIFORST, 1 << 7);
1987 	mchbar_clrbits8(CMNDQFIFORST, 1 << 7);
1988 	mchbar_setbits8(CMNDQFIFORST, 1 << 7);
1989 	PRINTK_DEBUG("rcven 3\n");
1990 }
1991 
1992 /* NOTE: Unless otherwise specified, the values are expressed in MiB */
sdram_mmap_regs(struct sysinfo * s)1993 static void sdram_mmap_regs(struct sysinfo *s)
1994 {
1995 	bool reclaim;
1996 	u32 mmiosize, tom, tolud, touud, reclaimbase, reclaimlimit;
1997 	u32 gfxbase, gfxsize, gttbase, gttsize, tsegbase, tsegsize;
1998 	u16 ggc;
1999 	u16 ggc_to_uma[10] = {0, 1, 4, 8, 16, 32, 48, 64, 128, 256};
2000 	u8  ggc_to_gtt[4]  = {0, 1, 0, 0};
2001 
2002 	reclaimbase  = 0;
2003 	reclaimlimit = 0;
2004 
2005 	ggc = pci_read_config16(HOST_BRIDGE, GGC);
2006 	printk(BIOS_DEBUG, "GGC = 0x%04x\n", ggc);
2007 
2008 	gfxsize = ggc_to_uma[(ggc & 0x00f0) >> 4];
2009 
2010 	gttsize = ggc_to_gtt[(ggc & 0x0300) >> 8];
2011 
2012 	tom = s->channel_capacity[0];
2013 
2014 	/* With GTT always being 1M, TSEG 1M is the only setting that can
2015 	   be covered by SMRR which has alignment requirements. */
2016 	tsegsize = 1;
2017 	mmiosize = 1024;
2018 
2019 	reclaim = false;
2020 	tolud = MIN(4096 - mmiosize, tom);
2021 	if ((tom - tolud) > 64) {
2022 		reclaim = true;
2023 	}
2024 	if (reclaim) {
2025 		tolud = tolud & ~0x3f;
2026 		tom   = tom   & ~0x3f;
2027 		reclaimbase = MAX(4096, tom);
2028 		reclaimlimit = reclaimbase + (MIN(4096, tom) - tolud) - 0x40;
2029 	}
2030 	touud = tom;
2031 	if (reclaim) {
2032 		touud = reclaimlimit + 64;
2033 	}
2034 
2035 	gfxbase  = tolud   - gfxsize;
2036 	gttbase  = gfxbase - gttsize;
2037 	tsegbase = gttbase - tsegsize;
2038 
2039 	/* Program the regs */
2040 	pci_write_config16(HOST_BRIDGE, TOLUD, (u16)(tolud << 4));
2041 	pci_write_config16(HOST_BRIDGE, TOM,   (u16)(tom   >> 6));
2042 	if (reclaim) {
2043 		pci_write_config16(HOST_BRIDGE, 0x98, (u16)(reclaimbase  >> 6));
2044 		pci_write_config16(HOST_BRIDGE, 0x9a, (u16)(reclaimlimit >> 6));
2045 	}
2046 	pci_write_config16(HOST_BRIDGE, TOUUD, (u16)(touud));
2047 	pci_write_config32(HOST_BRIDGE, GBSM, gfxbase  << 20);
2048 	pci_write_config32(HOST_BRIDGE, BGSM, gttbase  << 20);
2049 	pci_write_config32(HOST_BRIDGE, TSEG, tsegbase << 20);
2050 
2051 	u8 reg8 = pci_read_config8(HOST_BRIDGE, ESMRAMC);
2052 	reg8 &= ~0x07;
2053 	reg8 |= (0 << 1) | (1 << 0); /* 1M and TSEG_Enable */
2054 	pci_write_config8(HOST_BRIDGE, ESMRAMC, reg8);
2055 
2056 	printk(BIOS_DEBUG, "GBSM (igd) = verified %08x (written %08x)\n",
2057 		pci_read_config32(HOST_BRIDGE, GBSM), gfxbase  << 20);
2058 	printk(BIOS_DEBUG, "BGSM (gtt) = verified %08x (written %08x)\n",
2059 		pci_read_config32(HOST_BRIDGE, BGSM), gttbase  << 20);
2060 	printk(BIOS_DEBUG, "TSEG (smm) = verified %08x (written %08x)\n",
2061 		pci_read_config32(HOST_BRIDGE, TSEG), tsegbase << 20);
2062 }
2063 
sdram_enhancedmode(struct sysinfo * s)2064 static void sdram_enhancedmode(struct sysinfo *s)
2065 {
2066 	u8 reg8, ch, r, fsb_freq, ddr_freq;
2067 	u32 mask32, reg32;
2068 	mchbar_setbits8(C0ADDCSCTRL, 1 << 0);
2069 	mchbar_setbits8(C0REFRCTRL + 3, 1 << 0);
2070 	mask32 = (0x1f << 15) | (0x1f << 10) | (0x1f << 5) | 0x1f;
2071 	reg32  = (0x1e << 15) | (0x10 << 10) | (0x1e << 5) | 0x10;
2072 	mchbar_clrsetbits32(WRWMCONFIG, mask32, reg32);
2073 	mchbar_write8(C0DITCTRL + 1, 2);
2074 	mchbar_write16(C0DITCTRL + 2, 0x0804);
2075 	mchbar_write16(C0DITCTRL + 4, 0x2010);
2076 	mchbar_write8(C0DITCTRL + 6,  0x40);
2077 	mchbar_write16(C0DITCTRL + 8, 0x091c);
2078 	mchbar_write8(C0DITCTRL + 10, 0xf2);
2079 	mchbar_setbits8(C0BYPCTRL, 1 << 0);
2080 	mchbar_setbits8(C0CWBCTRL, 1 << 0);
2081 	mchbar_setbits16(C0ARBSPL, 1 << 8);
2082 
2083 	pci_or_config8(HOST_BRIDGE, 0xf0, 1);
2084 	mchbar_write32(SBCTL, 0x00000002);
2085 	mchbar_write32(SBCTL2, 0x20310002);
2086 	mchbar_write32(SLIMCFGTMG, 0x02020302);
2087 	mchbar_write32(HIT0, 0x001f1806);
2088 	mchbar_write32(HIT1, 0x01102800);
2089 	mchbar_write32(HIT2, 0x07000000);
2090 	mchbar_write32(HIT3, 0x01014010);
2091 	mchbar_write32(HIT4, 0x0f038000);
2092 	pci_and_config8(HOST_BRIDGE, 0xf0, ~1);
2093 
2094 	u32 nranks, curranksize, maxranksize, dra;
2095 	u8 rankmismatch;
2096 	static const u8 drbtab[10] = {0x4, 0x2, 0x8, 0x4, 0x8, 0x4, 0x10, 0x8, 0x20, 0x10};
2097 
2098 	nranks = 0;
2099 	curranksize = 0;
2100 	maxranksize = 0;
2101 	rankmismatch = 0;
2102 
2103 	FOR_EACH_POPULATED_RANK(s->dimms, ch, r) {
2104 		nranks++;
2105 		dra = (u8)((mchbar_read32(C0DRA01) >> (8 * r)) & 0x7f);
2106 		curranksize = drbtab[dra];
2107 		if (maxranksize == 0) {
2108 			maxranksize = curranksize;
2109 		}
2110 		if (curranksize != maxranksize) {
2111 			rankmismatch = 1;
2112 		}
2113 	}
2114 
2115 	reg8 = 0;
2116 	switch (nranks) {
2117 	case 4:
2118 		if (rankmismatch) {
2119 			reg8 = 0x64;
2120 		} else {
2121 			reg8 = 0xa4;
2122 		}
2123 		break;
2124 	case 1:
2125 	case 3:
2126 		reg8 = 0x64;
2127 		break;
2128 	case 2:
2129 		if (rankmismatch) {
2130 			reg8 = 0x64;
2131 		} else {
2132 			reg8 = 0x24;
2133 		}
2134 		break;
2135 	default:
2136 		die("Invalid number of ranks found, halt\n");
2137 		break;
2138 	}
2139 	mchbar_clrsetbits8(CHDECMISC, 0xfc, reg8 & 0xfc);
2140 	mchbar_clrbits32(NOACFGBUSCTL, 1 << 31);
2141 
2142 	mchbar_write32(HTBONUS0, 0xf);
2143 	mchbar_setbits8(C0COREBONUS + 4, 1 << 0);
2144 
2145 	mchbar_clrbits32(HIT3, 7 << 25);
2146 	mchbar_clrsetbits32(HIT4, 3 << 18, 1 << 18);
2147 
2148 	u32 clkcx[2][2][3] = {
2149 	{
2150 		{0x00000000, 0x0c080302, 0x08010204},	/* FSB = 667, DDR = 667 */
2151 		{0x02040000, 0x08100102, 0x00000000},	/* FSB = 667, DDR = 800 */
2152 	},
2153 	{
2154 		{0x18000000, 0x3021060c, 0x20010208},	/* FSB = 800, DDR = 667 */
2155 		{0x00000000, 0x0c090306, 0x00000000},	/* FSB = 800, DDR = 800 */
2156 	}
2157 	};
2158 
2159 	fsb_freq = s->selected_timings.fsb_clock;
2160 	ddr_freq = s->selected_timings.mem_clock;
2161 
2162 	mchbar_write32(CLKXSSH2X2MD + 0,  clkcx[fsb_freq][ddr_freq][0]);
2163 	mchbar_write32(CLKXSSH2X2MD + 4,  clkcx[fsb_freq][ddr_freq][1]);
2164 	mchbar_write32(CLKXSSH2MCBYP + 4, clkcx[fsb_freq][ddr_freq][2]);
2165 
2166 	mchbar_clrbits8(HIT4, 1 << 1);
2167 }
2168 
sdram_periodic_rcomp(void)2169 static void sdram_periodic_rcomp(void)
2170 {
2171 	mchbar_clrbits8(COMPCTRL1, 1 << 1);
2172 	while ((mchbar_read32(COMPCTRL1) & (1 << 31)) > 0) {
2173 		;
2174 	}
2175 	mchbar_clrbits16(CSHRMISCCTL, 3 << 12);
2176 	mchbar_setbits8(CMNDQFIFORST, 1 << 7);
2177 	mchbar_clrsetbits16(XCOMPDFCTRL, 0x0f, 0x09);
2178 
2179 	mchbar_setbits8(COMPCTRL1, 1 << 7 | 1 << 1);
2180 }
2181 
sdram_new_trd(struct sysinfo * s)2182 static void sdram_new_trd(struct sysinfo *s)
2183 {
2184 	u8 pidelay, i, j, k, cc, trd_perphase[5];
2185 	u8 bypass, freqgb, trd, reg8, txfifo;
2186 	u32 reg32, datadelay, tio, rcvendelay, maxrcvendelay;
2187 	u16 tmclk, thclk, buffertocore, postcalib;
2188 	static const u8 txfifo_lut[8] = { 0, 7, 6, 5, 2, 1, 4, 3 };
2189 	static const u16 trd_adjust[2][2][5] = {
2190 			{
2191 				{3000, 3000, 0,0,0},
2192 				{1000,2000,3000,1500,2500}
2193 			},
2194 			{
2195 				{2000,1000,3000,0,0},
2196 				{2500, 2500, 0,0,0}
2197 			}};
2198 
2199 	freqgb = 110;
2200 	buffertocore = 5000;
2201 	postcalib = (s->selected_timings.mem_clock == MEM_CLOCK_667MHz) ? 1250 : 500;
2202 	tmclk = (s->selected_timings.mem_clock == MEM_CLOCK_667MHz) ? 3000 : 2500;
2203 	tmclk = tmclk * 100 / freqgb;
2204 	thclk = (s->selected_timings.fsb_clock == FSB_CLOCK_667MHz) ? 6000 : 5000;
2205 	switch (s->selected_timings.mem_clock) {
2206 	case MEM_CLOCK_667MHz:
2207 		if (s->selected_timings.fsb_clock == FSB_CLOCK_667MHz) {
2208 			cc = 2;
2209 		} else {
2210 			cc = 3;
2211 		}
2212 		break;
2213 	default:
2214 	case MEM_CLOCK_800MHz:
2215 		if (s->selected_timings.fsb_clock == FSB_CLOCK_667MHz) {
2216 			cc = 5;
2217 		} else {
2218 			cc = 2;
2219 		}
2220 		break;
2221 	}
2222 	tio = (s->selected_timings.mem_clock == MEM_CLOCK_667MHz) ? 2700 : 3240;
2223 	maxrcvendelay = 0;
2224 	pidelay = (s->selected_timings.mem_clock == MEM_CLOCK_667MHz) ? 24 : 20;
2225 
2226 	for (i = 0; i < 8; i++) {
2227 		rcvendelay  = ((u32)((s->coarsedelay  >> (i << 1)) & 3) * (u32)(tmclk));
2228 		rcvendelay += ((u32)((s->readptrdelay >> (i << 1)) & 3) * (u32)(tmclk) / 2);
2229 		rcvendelay += ((u32)((s->mediumphase  >> (i << 1)) & 3) * (u32)(tmclk) / 4);
2230 		rcvendelay +=  (u32)(pidelay * s->pi[i]);
2231 		maxrcvendelay = MAX(maxrcvendelay, rcvendelay);
2232 	}
2233 
2234 	if ((mchbar_read8(HMBYPCP + 3) == 0xff) && (mchbar_read8(HMCCMC) & (1 << 7))) {
2235 		bypass = 1;
2236 	} else {
2237 		bypass = 0;
2238 	}
2239 
2240 	txfifo = 0;
2241 	reg8 = (mchbar_read8(CSHRFIFOCTL) & 0x0e) >> 1;
2242 	txfifo = txfifo_lut[reg8] & 0x07;
2243 
2244 	datadelay = tmclk * (2*txfifo + 4*s->coarsectrl + 4*(bypass-1) + 13) / 4
2245 			+ tio + maxrcvendelay + pidelay + buffertocore + postcalib;
2246 	if (s->async) {
2247 		datadelay += tmclk / 2;
2248 	}
2249 
2250 	j = (s->selected_timings.mem_clock == MEM_CLOCK_667MHz) ? 0 : 1;
2251 	k = (s->selected_timings.fsb_clock == FSB_CLOCK_667MHz) ? 0 : 1;
2252 
2253 	if (j == 0 && k == 0) {
2254 		datadelay -= 3084;
2255 	}
2256 
2257 	trd = 0;
2258 	for (i = 0; i < cc; i++) {
2259 		reg32 = datadelay - (trd_adjust[k][j][i] * 100 / freqgb);
2260 		trd_perphase[i] = (u8)(reg32 / thclk) - 2;
2261 		trd_perphase[i] += 1;
2262 		if (trd_perphase[i] > trd) {
2263 			trd = trd_perphase[i];
2264 		}
2265 	}
2266 
2267 	mchbar_clrsetbits16(C0STATRDCTRL, 0x1f << 8, trd << 8);
2268 }
2269 
sdram_powersettings(struct sysinfo * s)2270 static void sdram_powersettings(struct sysinfo *s)
2271 {
2272 	u8 j;
2273 	u32 reg32;
2274 
2275 	/* Thermal sensor */
2276 	mchbar_write8(TSC1, 0x9b);
2277 	mchbar_clrsetbits32(TSTTP, 0x00ffffff, 0x1d00);
2278 	mchbar_write8(THERM1, 0x08);
2279 	mchbar_write8(TSC3, 0);
2280 	mchbar_clrsetbits8(TSC2, 0x0f, 0x04);
2281 	mchbar_clrsetbits8(THERM1, 1, 1);
2282 	mchbar_clrsetbits8(TCO, 1 << 7, 1 << 7);
2283 
2284 	/* Clock gating */
2285 	mchbar_clrbits32(PMMISC, 1 << 18 | 1 << 0);
2286 	mchbar_clrbits8(SBCTL3 + 3, 1 << 7);
2287 	mchbar_clrbits8(CISDCTRL + 3, 1 << 7);
2288 	mchbar_clrbits16(CICGDIS, 0x1fff);
2289 	mchbar_clrbits32(SBCLKGATECTRL, 0x1ffff);
2290 	mchbar_clrsetbits16(HICLKGTCTL, 0x03ff, 0x06);
2291 	mchbar_clrsetbits32(HTCLKGTCTL, ~0, 0x20);
2292 	mchbar_clrbits8(TSMISC, 1 << 0);
2293 	mchbar_write8(C0WRDPYN, s->selected_timings.CAS - 1 + 0x15);
2294 	mchbar_clrsetbits16(CLOCKGATINGI, 0x07fc, 0x0040);
2295 	mchbar_clrsetbits16(CLOCKGATINGII, 0x0fff, 0x0d00);
2296 	mchbar_clrbits16(CLOCKGATINGIII, 0x0d80);
2297 	mchbar_write16(GTDPCGC + 2, 0xffff);
2298 
2299 	/* Sequencing */
2300 	mchbar_clrsetbits32(HPWRCTL1, 0x1fffffff, 0x1f643fff);
2301 	mchbar_clrsetbits32(HPWRCTL2, 0xffffff7f, 0x02010000);
2302 	mchbar_clrsetbits16(HPWRCTL3, 7 << 12, 3 << 12);
2303 
2304 	/* Power */
2305 	mchbar_clrsetbits32(GFXC3C4, 0xffff0003, 0x10100000);
2306 	mchbar_clrsetbits32(PMDSLFRC, 0x0001bff7, 0x00000078);
2307 
2308 	if (s->selected_timings.fsb_clock == FSB_CLOCK_667MHz)
2309 		mchbar_clrsetbits16(PMMSPMRES, 0x03ff, 0x00c8);
2310 	else
2311 		mchbar_clrsetbits16(PMMSPMRES, 0x03ff, 0x0100);
2312 
2313 	j = (s->selected_timings.mem_clock == MEM_CLOCK_667MHz) ? 0 : 1;
2314 
2315 	mchbar_clrsetbits32(PMCLKRC, 0x01fff37f, 0x10810700);
2316 	mchbar_clrsetbits8(PMPXPRC,  7, 1);
2317 	mchbar_clrbits8(PMBAK, 1 << 1);
2318 
2319 	static const u16 ddr2lut[2][4][2] = {
2320 	{
2321 		{0x0000, 0x0000},
2322 		{0x019A, 0x0039},
2323 		{0x0099, 0x1049},
2324 		{0x0000, 0x0000},
2325 	},
2326 	{
2327 		{0x0000, 0x0000},
2328 		{0x019A, 0x0039},
2329 		{0x0099, 0x1049},
2330 		{0x0099, 0x2159},
2331 	},
2332 	};
2333 
2334 	mchbar_write16(C0C2REG, 0x7a89);
2335 	mchbar_write8(SHC2REGII, 0xaa);
2336 	mchbar_write16(SHC2REGII + 1, ddr2lut[j][s->selected_timings.CAS - 3][1]);
2337 	mchbar_clrsetbits16(SHC2REGI, 0x7fff, ddr2lut[j][s->selected_timings.CAS - 3][0]);
2338 	mchbar_clrsetbits16(CLOCKGATINGIII, 0xf000, 0xf000);
2339 	mchbar_clrsetbits8(CSHWRIOBONUSX, 0x77, 4 << 4 | 4);
2340 
2341 	reg32 = s->nodll ? 0x30000000 : 0;
2342 
2343 	mchbar_clrsetbits32(C0COREBONUS, 0xf << 24, 1 << 29 | reg32);
2344 
2345 	mchbar_clrsetbits32(CLOCKGATINGI, 0xf << 20, 0xf << 20);
2346 	mchbar_clrsetbits32(CLOCKGATINGII - 1, 0x001ff000, 0xbf << 20);
2347 	mchbar_clrsetbits16(SHC3C4REG2, 0x1f7f, 0x0b << 8 | 7 << 4 | 0x0b);
2348 	mchbar_write16(SHC3C4REG3, 0x3264);
2349 	mchbar_clrsetbits16(SHC3C4REG4, 0x3f3f, 0x14 << 8 | 0x0a);
2350 
2351 	mchbar_setbits32(C1COREBONUS, 1 << 31 | 1 << 13);
2352 }
2353 
sdram_programddr(void)2354 static void sdram_programddr(void)
2355 {
2356 	mchbar_clrsetbits16(CLOCKGATINGII, 0x03ff, 0x0100);
2357 	mchbar_clrsetbits16(CLOCKGATINGIII, 0x003f, 0x0010);
2358 	mchbar_clrsetbits16(CLOCKGATINGI, 0x7000, 0x2000);
2359 
2360 	mchbar_clrbits8(CSHRPDCTL, 7 << 1);
2361 	mchbar_clrbits8(CSHRWRIOMLNS,  3 << 2);
2362 	mchbar_clrbits8(C0MISCCTLy(0), 7 << 1);
2363 	mchbar_clrbits8(C0MISCCTLy(1), 7 << 1);
2364 	mchbar_clrbits8(C0MISCCTLy(2), 7 << 1);
2365 	mchbar_clrbits8(C0MISCCTLy(3), 7 << 1);
2366 	mchbar_clrbits8(C0MISCCTLy(4), 7 << 1);
2367 	mchbar_clrbits8(C0MISCCTLy(5), 7 << 1);
2368 	mchbar_clrbits8(C0MISCCTLy(6), 7 << 1);
2369 	mchbar_clrbits8(C0MISCCTLy(7), 7 << 1);
2370 	mchbar_clrbits8(CSHRWRIOMLNS, 1 << 1);
2371 
2372 	mchbar_clrbits16(CSHRMISCCTL, 1 << 10);
2373 	mchbar_clrbits16(CLOCKGATINGIII, 0x0dc0);
2374 	mchbar_clrbits8(C0WRDPYN, 1 << 7);
2375 	mchbar_clrbits32(C0COREBONUS, 1 << 22);
2376 	mchbar_clrbits16(CLOCKGATINGI, 0x80fc);
2377 	mchbar_clrbits16(CLOCKGATINGII, 0x0c00);
2378 
2379 	mchbar_clrbits8(CSHRPDCTL, 0x0d);
2380 	mchbar_clrbits8(C0MISCCTLy(0), 1 << 0);
2381 	mchbar_clrbits8(C0MISCCTLy(1), 1 << 0);
2382 	mchbar_clrbits8(C0MISCCTLy(2), 1 << 0);
2383 	mchbar_clrbits8(C0MISCCTLy(3), 1 << 0);
2384 	mchbar_clrbits8(C0MISCCTLy(4), 1 << 0);
2385 	mchbar_clrbits8(C0MISCCTLy(5), 1 << 0);
2386 	mchbar_clrbits8(C0MISCCTLy(6), 1 << 0);
2387 	mchbar_clrbits8(C0MISCCTLy(7), 1 << 0);
2388 
2389 	mchbar_clrsetbits32(C0STATRDCTRL, 7 << 20, 3 << 20);
2390 	mchbar_clrbits32(C0COREBONUS, 1 << 20);
2391 	mchbar_setbits8(C0DYNSLVDLLEN, 0x1e);
2392 	mchbar_setbits8(C0DYNSLVDLLEN2, 0x03);
2393 	mchbar_clrsetbits32(SHCYCTRKCKEL, 3 << 26, 1 << 26);
2394 	mchbar_setbits16(C0STATRDCTRL, 3 << 13);
2395 	mchbar_setbits32(C0CKECTRL, 1 << 16);
2396 	mchbar_setbits8(C0COREBONUS, 1 << 4);
2397 	mchbar_setbits32(CLOCKGATINGI - 1, 0xf << 24);
2398 	mchbar_setbits8(CSHWRIOBONUS, 7);
2399 	mchbar_setbits8(C0DYNSLVDLLEN, 3 << 6);
2400 	mchbar_setbits8(SHC2REGIII, 7);
2401 	mchbar_clrsetbits16(SHC2MINTM, ~0, 1 << 7);
2402 	mchbar_clrsetbits8(SHC2IDLETM, 0xff, 0x10);
2403 	mchbar_setbits16(C0COREBONUS, 0xf << 5);
2404 	mchbar_setbits8(CSHWRIOBONUS, 3 << 3);
2405 	mchbar_setbits8(CSHRMSTDYNDLLENB, 0x0d);
2406 	mchbar_setbits16(SHC3C4REG1, 0x0a3f);
2407 	mchbar_setbits8(C0STATRDCTRL, 3);
2408 	mchbar_clrsetbits8(C0REFRCTRL2, 0xff, 0x4a);
2409 	mchbar_clrbits8(C0COREBONUS + 4, 3 << 5);
2410 	mchbar_setbits16(C0DYNSLVDLLEN, 0x0321);
2411 }
2412 
sdram_programdqdqs(struct sysinfo * s)2413 static void sdram_programdqdqs(struct sysinfo *s)
2414 {
2415 	u16 mdclk, tpi, refclk, dqdqs_out, dqdqs_outdelay, dqdqs_delay;
2416 	u32 coretomcp, txdelay, tmaxunmask, tmaxpi;
2417 	u8 repeat, halfclk, feature, reg8, push;
2418 	u16 cwb, pimdclk;
2419 	u32 reg32;
2420 	static const u8 txfifotab[8] = {0, 7, 6, 5, 2, 1, 4, 3};
2421 
2422 	tpi = 3000;
2423 	dqdqs_out = 4382;
2424 	dqdqs_outdelay = 5083;
2425 	dqdqs_delay = 4692;
2426 	coretomcp = 0;
2427 	txdelay = 0;
2428 	halfclk = 0;
2429 	tmaxunmask = 0;
2430 	tmaxpi = 0;
2431 	repeat = 2;
2432 	feature = 0;
2433 	cwb = 0;
2434 	pimdclk = 0;
2435 	reg32 = 0;
2436 	push = 0;
2437 	reg8 = 0;
2438 
2439 	mdclk = (s->selected_timings.mem_clock == MEM_CLOCK_667MHz) ? 3000 : 2500;
2440 	refclk = 3000 - mdclk;
2441 
2442 	coretomcp = ((mchbar_read8(C0ADDCSCTRL) >> 2) & 0x3) + 1;
2443 	coretomcp *= mdclk;
2444 
2445 	reg8 = (mchbar_read8(CSHRFIFOCTL) & 0x0e) >> 1;
2446 
2447 	while (repeat) {
2448 		txdelay = mdclk * (
2449 				((mchbar_read16(C0GNT2LNCH1) >> 8) & 0x7) +
2450 				(mchbar_read8(C0WRDATACTRL) & 0xf) +
2451 				(mchbar_read8(C0WRDATACTRL + 1) & 0x1)
2452 				) +
2453 				txfifotab[reg8]*(mdclk / 2) +
2454 				coretomcp +
2455 				refclk +
2456 				cwb;
2457 		halfclk = (mchbar_read8(C0MISCCTL) >> 1) & 0x1;
2458 		if (halfclk) {
2459 			txdelay -= mdclk / 2;
2460 			reg32 = dqdqs_outdelay + coretomcp - mdclk / 2;
2461 		} else {
2462 			reg32 = dqdqs_outdelay + coretomcp;
2463 		}
2464 
2465 		tmaxunmask = txdelay - mdclk - dqdqs_out;
2466 		tmaxpi = tmaxunmask - tpi;
2467 
2468 		if ((tmaxunmask >= reg32) && tmaxpi >= dqdqs_delay) {
2469 			if (repeat == 2) {
2470 				mchbar_clrbits32(C0COREBONUS, 1 << 23);
2471 			}
2472 			feature = 1;
2473 			repeat = 0;
2474 		} else {
2475 			repeat--;
2476 			mchbar_setbits32(C0COREBONUS, 1 << 23);
2477 			cwb = 2 * mdclk;
2478 		}
2479 	}
2480 
2481 	if (!feature) {
2482 		mchbar_clrbits8(CLOCKGATINGI, 3);
2483 		return;
2484 	}
2485 	mchbar_setbits8(CLOCKGATINGI, 3);
2486 	mchbar_clrsetbits16(CLOCKGATINGIII, 0xf << 12, pimdclk << 12);
2487 	mchbar_clrsetbits8(CSHWRIOBONUSX, 0x77, push << 4 | push);
2488 	mchbar_clrsetbits32(C0COREBONUS, 0xf << 24, 3 << 24);
2489 }
2490 
2491 /**
2492  * @param boot_path: 0 = normal, 1 = reset, 2 = resume from s3
2493  */
sdram_initialize(int boot_path,const u8 * spd_addresses)2494 void sdram_initialize(int boot_path, const u8 *spd_addresses)
2495 {
2496 	struct sysinfo si;
2497 	const char *boot_str[] = {"Normal", "Reset", "Resume"};
2498 
2499 	PRINTK_DEBUG("Setting up RAM controller.\n");
2500 
2501 	memset(&si, 0, sizeof(si));
2502 
2503 	si.boot_path = boot_path;
2504 	printk(BIOS_DEBUG, "Boot path: %s\n", boot_str[boot_path]);
2505 	si.spd_map[0] = spd_addresses[0];
2506 	si.spd_map[1] = spd_addresses[1];
2507 	si.spd_map[2] = spd_addresses[2];
2508 	si.spd_map[3] = spd_addresses[3];
2509 
2510 	sdram_read_spds(&si);
2511 
2512 	/* Choose Common Frequency */
2513 	sdram_detect_ram_speed(&si);
2514 
2515 	/* Determine smallest common tRAS, tRP, tRCD, etc */
2516 	sdram_detect_smallest_params(&si);
2517 
2518 	/* Enable HPET */
2519 	enable_hpet();
2520 
2521 	mchbar_setbits16(CPCTL, 1 << 15);
2522 
2523 	sdram_clk_crossing(&si);
2524 
2525 	sdram_checkreset();
2526 	PRINTK_DEBUG("Done checkreset\n");
2527 
2528 	sdram_clkmode(&si);
2529 	PRINTK_DEBUG("Done clkmode\n");
2530 
2531 	sdram_timings(&si);
2532 	PRINTK_DEBUG("Done timings (dqs dll enabled)\n");
2533 
2534 	if (si.boot_path != BOOT_PATH_RESET) {
2535 		sdram_dlltiming(&si);
2536 		PRINTK_DEBUG("Done dlltiming\n");
2537 	}
2538 
2539 	if (si.boot_path != BOOT_PATH_RESET) {
2540 		sdram_rcomp(&si);
2541 		PRINTK_DEBUG("Done RCOMP\n");
2542 	}
2543 
2544 	sdram_odt(&si);
2545 	PRINTK_DEBUG("Done odt\n");
2546 
2547 	if (si.boot_path != BOOT_PATH_RESET) {
2548 		while ((mchbar_read8(COMPCTRL1) & 1) != 0)
2549 			;
2550 	}
2551 
2552 	sdram_mmap(&si);
2553 	PRINTK_DEBUG("Done mmap\n");
2554 
2555 	/* Enable DDR IO buffer */
2556 	mchbar_clrsetbits8(C0IOBUFACTCTL, 0x3f, 0x08);
2557 	mchbar_setbits8(C0RSTCTL, 1 << 0);
2558 
2559 	sdram_rcompupdate(&si);
2560 	PRINTK_DEBUG("Done RCOMP update\n");
2561 
2562 	mchbar_setbits8(HIT4, 1 << 1);
2563 
2564 	if (si.boot_path != BOOT_PATH_RESUME) {
2565 		mchbar_setbits32(C0CKECTRL, 1 << 27);
2566 
2567 		sdram_jedecinit(&si);
2568 		PRINTK_DEBUG("Done MRS\n");
2569 	}
2570 
2571 	sdram_misc(&si);
2572 	PRINTK_DEBUG("Done misc\n");
2573 
2574 	sdram_zqcl(&si);
2575 	PRINTK_DEBUG("Done zqcl\n");
2576 
2577 	if (si.boot_path != BOOT_PATH_RESUME) {
2578 		mchbar_setbits32(C0REFRCTRL2, 3 << 30);
2579 	}
2580 
2581 	sdram_dradrb(&si);
2582 	PRINTK_DEBUG("Done dradrb\n");
2583 
2584 	sdram_rcven(&si);
2585 	PRINTK_DEBUG("Done rcven\n");
2586 
2587 	sdram_new_trd(&si);
2588 	PRINTK_DEBUG("Done tRD\n");
2589 
2590 	sdram_mmap_regs(&si);
2591 	PRINTK_DEBUG("Done mmap regs\n");
2592 
2593 	sdram_enhancedmode(&si);
2594 	PRINTK_DEBUG("Done enhanced mode\n");
2595 
2596 	sdram_powersettings(&si);
2597 	PRINTK_DEBUG("Done power settings\n");
2598 
2599 	sdram_programddr();
2600 	PRINTK_DEBUG("Done programming ddr\n");
2601 
2602 	sdram_programdqdqs(&si);
2603 	PRINTK_DEBUG("Done programming dqdqs\n");
2604 
2605 	sdram_periodic_rcomp();
2606 	PRINTK_DEBUG("Done periodic RCOMP\n");
2607 
2608 	/* Set init done */
2609 	mchbar_setbits32(C0REFRCTRL2, 1 << 30);
2610 
2611 	/* Tell ICH7 that we're done */
2612 	pci_and_config8(PCI_DEV(0, 0x1f, 0), 0xa2, (u8)~(1 << 7));
2613 
2614 	/* Tell northbridge we're done */
2615 	pci_or_config8(HOST_BRIDGE, 0xf4, 1);
2616 
2617 	printk(BIOS_DEBUG, "RAM initialization finished.\n");
2618 }
2619