/ src / northbridge / intel / pineview / raminit.c
raminit.c
   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  
  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  
  88  static inline void barrier(void)
  89  {
  90  	 __asm__ __volatile__("": : :"memory");
  91  }
  92  
  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   */
 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  
 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)
 265  static u32 fsb_reg_to_mhz(u32 speed)
 266  {
 267  	return (speed * 133) + 667;
 268  }
 269  
 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.
 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.
 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  
 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  
 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  
 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  
 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  
 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 */
 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 */
 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 */
 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 */
 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  
 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  
 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 */
 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 */
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  
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 */
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! */
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  
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  
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  
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))
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  
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  
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  
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  
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  
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  
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  
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  
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 */
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  
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  
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  
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  
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  
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  
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   */
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  }