/*
 * This file is part of the coreboot project.
 *
 * Copyright (C) 2005 Eric W. Biederman and Tom Zimmerman
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
 *
 */

#include <cpu/x86/mtrr.h>
#include <cpu/x86/cache.h>
#include <stdlib.h>
#include "raminit.h"
#include "e7525.h"
#include <pc80/mc146818rtc.h>
#if CONFIG_HAVE_OPTION_TABLE
#include "option_table.h"
#endif

#define BAR 0x40000000

static void sdram_set_registers(const struct mem_controller *ctrl)
{
	static const unsigned int register_values[] = {

		/* CKDIS 0x8c disable clocks */
	PCI_ADDR(0, 0x00, 0, CKDIS), 0xffff0000, 0x0000ffff,

		/* 0x9c Device present and extended RAM control
		 * DEVPRES is very touchy, hard code the initialization
		 * of PCI-E ports here.
		 */
	PCI_ADDR(0, 0x00, 0, DEVPRES), 0x00000000, 0x07020801 | DEVPRES_CONFIG,

		/* 0xc8 Remap RAM base and limit off */
	PCI_ADDR(0, 0x00, 0, REMAPLIMIT), 0x00000000, 0x03df0000,

		/* ??? */
	PCI_ADDR(0, 0x00, 0, 0xd8), 0x00000000, 0xb5930000,
	PCI_ADDR(0, 0x00, 0, 0xe8), 0x00000000, 0x00004a2a,

		/* 0x50 scrub */
	PCI_ADDR(0, 0x00, 0, MCHCFG0), 0xfce0ffff, 0x00006000, /* 6000 */

		/* 0x58 0x5c PAM */
	PCI_ADDR(0, 0x00, 0, PAM-1), 0xcccccc7f, 0x33333000,
	PCI_ADDR(0, 0x00, 0, PAM+3), 0xcccccccc, 0x33333333,

		/* 0xf4 */
	PCI_ADDR(0, 0x00, 0, DEVPRES1), 0xffbffff, (1<<22)|(6<<2) | DEVPRES1_CONFIG,

		/* 0x14 */
	PCI_ADDR(0, 0x00, 0, IURBASE), 0x00000fff, BAR |0,
	};
	int i;
	int max;

	max = ARRAY_SIZE(register_values);
	for(i = 0; i < max; i += 3) {
		device_t dev;
		unsigned where;
		unsigned long reg;
		dev = (register_values[i] & ~0xff) - PCI_DEV(0, 0x00, 0) + ctrl->f0;
		where = register_values[i] & 0xff;
		reg = pci_read_config32(dev, where);
		reg &= register_values[i+1];
		reg |= register_values[i+2];
		pci_write_config32(dev, where, reg);
	}
	print_spew("done.\n");
}



struct dimm_size {
	unsigned long side1;
	unsigned long side2;
};

static struct dimm_size spd_get_dimm_size(unsigned device)
{
	/* Calculate the log base 2 size of a DIMM in bits */
	struct dimm_size sz;
	int value, low, ddr2;
	sz.side1 = 0;
	sz.side2 = 0;

	/* test for ddr2 */
	ddr2=0;
	value = spd_read_byte(device, 2);       /* type */
        if (value < 0) goto hw_err;
	if (value == 8) ddr2 = 1;

	/* Note it might be easier to use byte 31 here, it has the DIMM size as
	 * a multiple of 4MB.  The way we do it now we can size both
	 * sides of an assymetric dimm.
	 */
	value = spd_read_byte(device, 3);	/* rows */
	if (value < 0) goto hw_err;
	if ((value & 0xf) == 0) goto val_err;
	sz.side1 += value & 0xf;

	value = spd_read_byte(device, 4);	/* columns */
	if (value < 0) goto hw_err;
	if ((value & 0xf) == 0) goto val_err;
	sz.side1 += value & 0xf;

	value = spd_read_byte(device, 17);	/* banks */
	if (value < 0) goto hw_err;
	if ((value & 0xff) == 0) goto val_err;
	sz.side1 += log2(value & 0xff);

	/* Get the module data width and convert it to a power of two */
	value = spd_read_byte(device, 7);	/* (high byte) */
	if (value < 0) goto hw_err;
	value &= 0xff;
	value <<= 8;

	low = spd_read_byte(device, 6);	/* (low byte) */
	if (low < 0) goto hw_err;
	value = value | (low & 0xff);
	if ((value != 72) && (value != 64)) goto val_err;
	sz.side1 += log2(value);

	/* side 2 */
	value = spd_read_byte(device, 5);	/* number of physical banks */

	if (value < 0) goto hw_err;
	value &= 7;
	if(ddr2) value++;
	if (value == 1) goto out;
	if (value != 2) goto val_err;

	/* Start with the symmetrical case */
	sz.side2 = sz.side1;

	value = spd_read_byte(device, 3);	/* rows */
	if (value < 0) goto hw_err;
	if ((value & 0xf0) == 0) goto out;	/* If symmetrical we are done */
	sz.side2 -= (value & 0x0f);		/* Subtract out rows on side 1 */
	sz.side2 += ((value >> 4) & 0x0f);	/* Add in rows on side 2 */

	value = spd_read_byte(device, 4);	/* columns */
	if (value < 0) goto hw_err;
	if ((value & 0xff) == 0) goto val_err;
	sz.side2 -= (value & 0x0f);		/* Subtract out columns on side 1 */
	sz.side2 += ((value >> 4) & 0x0f);	/* Add in columsn on side 2 */
	goto out;

 val_err:
	die("Bad SPD value\n");
	/* If an hw_error occurs report that I have no memory */
hw_err:
	sz.side1 = 0;
	sz.side2 = 0;
out:
	return sz;

}

static long spd_set_ram_size(const struct mem_controller *ctrl, long dimm_mask)
{
	int i;
	int cum;

	for(i = cum = 0; i < DIMM_SOCKETS; i++) {
		struct dimm_size sz;
		if (dimm_mask & (1 << i)) {
			sz = spd_get_dimm_size(ctrl->channel0[i]);
			if (sz.side1 < 29) {
				return -1; /* Report SPD error */
			}
			/* convert bits to multiples of 64MB */
			sz.side1 -= 29;
			cum += (1 << sz.side1);
			/* DRB = 0x60 */
			pci_write_config8(ctrl->f0, DRB + (i*2), cum);
			if( sz.side2 > 28) {
				sz.side2 -= 29;
				cum += (1 << sz.side2);
			}
			pci_write_config8(ctrl->f0, DRB+1 + (i*2), cum);
		}
		else {
			pci_write_config8(ctrl->f0, DRB + (i*2), cum);
			pci_write_config8(ctrl->f0, DRB+1 + (i*2), cum);
		}
	}
	/* set TOM top of memory 0xcc */
	pci_write_config16(ctrl->f0, TOM, cum);
	/* set TOLM top of low memory */
	if(cum > 0x18) {
		cum = 0x18;
	}
	cum <<= 11;
	/* 0xc4 TOLM */
	pci_write_config16(ctrl->f0, TOLM, cum);
	return 0;
}


static unsigned int spd_detect_dimms(const struct mem_controller *ctrl)
{
	unsigned dimm_mask;
	int i;
	dimm_mask = 0;
	for(i = 0; i < DIMM_SOCKETS; i++) {
		int byte;
		unsigned device;
		device = ctrl->channel0[i];
		if (device) {
			byte = spd_read_byte(device, 2);  /* Type */
			if ((byte == 7) || (byte == 8)) {
				dimm_mask |= (1 << i);
			}
		}
		device = ctrl->channel1[i];
		if (device) {
			byte = spd_read_byte(device, 2);
			if ((byte == 7) || (byte == 8)) {
				dimm_mask |= (1 << (i + DIMM_SOCKETS));
			}
		}
	}
	return dimm_mask;
}


static int spd_set_row_attributes(const struct mem_controller *ctrl,
		long dimm_mask)
{

	int value;
	int reg;
	int dra;
	int cnt;

	dra = 0;
	for(cnt=0; cnt < 4; cnt++) {
		if (!(dimm_mask & (1 << cnt))) {
			continue;
		}
		reg =0;
		value = spd_read_byte(ctrl->channel0[cnt], 3);	/* rows */
		if (value < 0) goto hw_err;
		if ((value & 0xf) == 0) goto val_err;
		reg += value & 0xf;

		value = spd_read_byte(ctrl->channel0[cnt], 4);	/* columns */
		if (value < 0) goto hw_err;
		if ((value & 0xf) == 0) goto val_err;
		reg += value & 0xf;

		value = spd_read_byte(ctrl->channel0[cnt], 17);	/* banks */
		if (value < 0) goto hw_err;
		if ((value & 0xff) == 0) goto val_err;
		reg += log2(value & 0xff);

		/* Get the device width and convert it to a power of two */
		value = spd_read_byte(ctrl->channel0[cnt], 13);
		if (value < 0) goto hw_err;
		value = log2(value & 0xff);
		reg += value;
		if(reg < 27) goto hw_err;
		reg -= 27;
		reg += (value << 2);

		dra += reg << (cnt*8);
		value = spd_read_byte(ctrl->channel0[cnt], 5);
		if (value & 2)
			dra += reg << ((cnt*8)+4);
	}

	/* 0x70 DRA */
	pci_write_config32(ctrl->f0, DRA, dra);
	goto out;

 val_err:
	die("Bad SPD value\n");
	/* If an hw_error occurs report that I have no memory */
hw_err:
	dra = 0;
out:
	return dra;

}


static int spd_set_drt_attributes(const struct mem_controller *ctrl,
		long dimm_mask, uint32_t drc)
{
	int value;
	int reg;
	uint32_t drt;
	int cnt;
	int first_dimm;
	int cas_latency=0;
	int latency;
	uint32_t index = 0;
	uint32_t index2 = 0;
	static const unsigned char cycle_time[3] = {0x75,0x60,0x50};
	static const int latency_indicies[] = { 26, 23, 9 };

	/* 0x78 DRT */
	drt = pci_read_config32(ctrl->f0, DRT);
	drt &= 3;  /* save bits 1:0 */

	for(first_dimm = 0; first_dimm < 4; first_dimm++) {
		if (dimm_mask & (1 << first_dimm))
			break;
	}

	/* get dimm type */
	value = spd_read_byte(ctrl->channel0[first_dimm], 2);
	if(value == 8) {
		drt |= (3<<5); /* back to bark write turn around & cycle add */
	}

	drt |= (3<<18);  /* Trasmax */

	for(cnt=0; cnt < 4; cnt++) {
		if (!(dimm_mask & (1 << cnt))) {
			continue;
		}
		reg = spd_read_byte(ctrl->channel0[cnt], 18); /* CAS Latency */
		/* Compute the lowest cas latency supported */
		latency = log2(reg) -2;

		/* Loop through and find a fast clock with a low latency */
		for(index = 0; index < 3; index++, latency++) {
			if ((latency < 2) || (latency > 4) ||
				(!(reg & (1 << latency)))) {
				continue;
			}
			value = spd_read_byte(ctrl->channel0[cnt],
				        latency_indicies[index]);

			if(value <= cycle_time[drc&3]) {
				if( latency > cas_latency) {
					cas_latency = latency;
				}
				break;
			}
		}
	}
	index = (cas_latency-2);
	if((index)==0) cas_latency = 20;
	else if((index)==1) cas_latency = 25;
	else cas_latency = 30;

	for(cnt=0;cnt<4;cnt++) {
		if (!(dimm_mask & (1 << cnt))) {
                        continue;
                }
		reg = spd_read_byte(ctrl->channel0[cnt], 27)&0x0ff;
		if(((index>>8)&0x0ff)<reg) {
			index &= ~(0x0ff << 8);
			index |= (reg << 8);
		}
		reg = spd_read_byte(ctrl->channel0[cnt], 28)&0x0ff;
		if(((index>>16)&0x0ff)<reg) {
			index &= ~(0x0ff << 16);
			index |= (reg<<16);
		}
		reg = spd_read_byte(ctrl->channel0[cnt], 29)&0x0ff;
		if(((index2>>0)&0x0ff)<reg) {
			index2 &= ~(0x0ff << 0);
			index2 |= (reg<<0);
		}
		reg = spd_read_byte(ctrl->channel0[cnt], 41)&0x0ff;
		if(((index2>>8)&0x0ff)<reg) {
			index2 &= ~(0x0ff << 8);
			index2 |= (reg<<8);
		}
		reg = spd_read_byte(ctrl->channel0[cnt], 42)&0x0ff;
		if(((index2>>16)&0x0ff)<reg) {
			index2 &= ~(0x0ff << 16);
			index2 |= (reg<<16);
		}
	}

	/* get dimm speed */
	value = cycle_time[drc&3];
	if(value <= 0x50) {  /* 200 MHz */
		if((index&7) > 2) {
			drt |= (2<<2);  /* CAS latency 4 */
			cas_latency = 40;
		} else {
			drt |= (1<<2);  /* CAS latency 3 */
			cas_latency = 30;
		}
		if((index&0x0ff00)<=0x03c00) {
			drt |= (1<<8);  /* Trp RAS Precharg */
		} else {
			drt |= (2<<8);  /* Trp RAS Precharg */
		}

		/* Trcd RAS to CAS delay */
		if((index2&0x0ff)<=0x03c) {
			drt |= (0<<10);
		} else {
			drt |= (1<<10);
		}

		/* Tdal Write auto precharge recovery delay */
		drt |= (1<<12);

		/* Trc TRS min */
		if((index2&0x0ff00)<=0x03700)
			drt |= (0<<14);
		else if((index2&0xff00)<=0x03c00)
			drt |= (1<<14);
		else
			drt |= (2<<14); /* spd 41 */

		drt |= (2<<16);  /* Twr not defined for DDR docs say use 2 */

		/* Trrd Row Delay */
		if((index&0x0ff0000)<=0x0140000) {
			drt |= (0<<20);
		} else if((index&0x0ff0000)<=0x0280000) {
			drt |= (1<<20);
		} else if((index&0x0ff0000)<=0x03c0000) {
			drt |= (2<<20);
		} else {
			drt |= (3<<20);
		}

		/* Trfc Auto refresh cycle time */
		if((index2&0x0ff0000)<=0x04b0000) {
			drt |= (0<<22);
		} else if((index2&0x0ff0000)<=0x0690000) {
			drt |= (1<<22);
		} else {
			drt |= (2<<22);
		}
		/* Docs say use 55 for all 200Mhz */
		drt |= (0x055<<24);
	}
	else if(value <= 0x60) { /* 167 Mhz */
		/* according to new documentation CAS latency is 00
		 * for bits 3:2 for all 167 Mhz
		drt |= ((index&3)<<2); */  /* set CAS latency */
		if((index&0x0ff00)<=0x03000) {
			drt |= (1<<8);  /* Trp RAS Precharg */
		} else {
			drt |= (2<<8);  /* Trp RAS Precharg */
		}

		/* Trcd RAS to CAS delay */
		if((index2&0x0ff)<=0x030) {
			drt |= (0<<10);
		} else {
			drt |= (1<<10);
		}

		/* Tdal Write auto precharge recovery delay */
		drt |= (2<<12);

		/* Trc TRS min */
		drt |= (2<<14); /* spd 41, but only one choice */

		drt |= (2<<16);  /* Twr not defined for DDR docs say 2 */

		/* Trrd Row Delay */
		if((index&0x0ff0000)<=0x0180000) {
			drt |= (0<<20);
		} else if((index&0x0ff0000)<=0x0300000) {
			drt |= (1<<20);
		} else {
			drt |= (2<<20);
		}

		/* Trfc Auto refresh cycle time */
		if((index2&0x0ff0000)<=0x0480000) {
			drt |= (0<<22);
		} else if((index2&0x0ff0000)<=0x0780000) {
			drt |= (2<<22);
		} else {
			drt |= (2<<22);
		}
		/* Docs state to use 99 for all 167 Mhz */
		drt |= (0x099<<24);
	}
	else if(value <= 0x75) { /* 133 Mhz */
		drt |= ((index&3)<<2);  /* set CAS latency */
		if((index&0x0ff00)<=0x03c00) {
			drt |= (1<<8);  /* Trp RAS Precharg */
		} else {
			drt |= (2<<8);  /* Trp RAS Precharg */
		}

		/* Trcd RAS to CAS delay */
		if((index2&0x0ff)<=0x03c) {
			drt |= (0<<10);
		} else {
			drt |= (1<<10);
		}

		/* Tdal Write auto precharge recovery delay */
		drt |= (1<<12);

		/* Trc TRS min */
		drt |= (2<<14); /* spd 41, but only one choice */

		drt |= (1<<16);  /* Twr not defined for DDR docs say 1 */

		/* Trrd Row Delay */
		if((index&0x0ff0000)<=0x01e0000) {
			drt |= (0<<20);
		} else if((index&0x0ff0000)<=0x03c0000) {
			drt |= (1<<20);
		} else {
			drt |= (2<<20);
		}

		/* Trfc Auto refresh cycle time */
		if((index2&0x0ff0000)<=0x04b0000) {
			drt |= (0<<22);
		} else if((index2&0x0ff0000)<=0x0780000) {
			drt |= (2<<22);
		} else {
			drt |= (2<<22);
		}

		/* Based on CAS latency */
		if(index&7)
			drt |= (0x099<<24);
		else
			drt |= (0x055<<24);

	}
	else {
		die("Invalid SPD 9 bus speed.\n");
	}

	/* 0x78 DRT */
	pci_write_config32(ctrl->f0, DRT, drt);

	return(cas_latency);
}

static int spd_set_dram_controller_mode(const struct mem_controller *ctrl,
		long dimm_mask)
{
	int value;
	int reg;
	int drc;
	int cnt;
	msr_t msr;
	unsigned char dram_type = 0xff;
	unsigned char ecc = 0xff;
	unsigned char rate = 62;
	static const unsigned char spd_rates[6] = {15,3,7,7,62,62};
	static const unsigned char drc_rates[5] = {0,15,7,62,3};
	static const unsigned char fsb_conversion[4] = {3,1,3,2};

	/* 0x7c DRC */
	drc = pci_read_config32(ctrl->f0, DRC);
	for(cnt=0; cnt < 4; cnt++) {
		if (!(dimm_mask & (1 << cnt))) {
			continue;
		}
		value = spd_read_byte(ctrl->channel0[cnt], 11);	/* ECC */
		reg = spd_read_byte(ctrl->channel0[cnt], 2); /* Type */
		if (value == 2) {    /* RAM is ECC capable */
			if (reg == 8) {
				if ( ecc == 0xff ) {
					ecc = 2;
				}
				else if (ecc == 1) {
					die("ERROR - Mixed DDR & DDR2 RAM\n");
				}
			}
			else if ( reg == 7 ) {
				if ( ecc == 0xff) {
					ecc = 1;
				}
				else if ( ecc > 1 ) {
					die("ERROR - Mixed DDR & DDR2 RAM\n");
				}
			}
			else {
				die("ERROR - RAM not DDR\n");
			}
		}
		else {
			die("ERROR - Non ECC memory dimm\n");
		}

		value = spd_read_byte(ctrl->channel0[cnt], 12);	/*refresh rate*/
		value &= 0x0f;    /* clip self refresh bit */
		if (value > 5) goto hw_err;
		if (rate > spd_rates[value])
			rate = spd_rates[value];

		value = spd_read_byte(ctrl->channel0[cnt], 9);	/* cycle time */
		if (value > 0x75) goto hw_err;
		if (value <= 0x50) {
			if (dram_type >= 2) {
				if (reg == 8) { /*speed is good, is this ddr2?*/
					dram_type = 2;
				} else { /* not ddr2 so use ddr333 */
					dram_type = 1;
				}
			}
		}
		else if (value <= 0x60) {
			if (dram_type >= 1)  dram_type = 1;
		}
		else dram_type = 0; /* ddr266 */

	}
	ecc = 2;
#if CONFIG_HAVE_OPTION_TABLE
	if (read_option(ECC_memory, 1) == 0) {
		ecc = 0;  /* ECC off in CMOS so disable it */
		print_debug("ECC off\n");
	} else
#endif
	{
		print_debug("ECC on\n");
	}
	drc &= ~(3 << 20); /* clear the ecc bits */
	drc |= (ecc << 20);  /* or in the calculated ecc bits */
	for ( cnt = 1; cnt < 5; cnt++)
		if (drc_rates[cnt] == rate)
			break;
	if (cnt < 5) {
		drc &= ~(7 << 8);  /* clear the rate bits */
		drc |= (cnt << 8);
	}

	if (reg == 8) { /* independant clocks */
		drc |= (1 << 4);
	}

	drc |= (1 << 26); /* set the overlap bit - the factory BIOS does */
	drc |= (1 << 27); /* set DED retry enable - the factory BIOS does */
	/* front side bus */
	msr = rdmsr(0x2c);
	value = msr.lo >> 16;
	value &= 0x03;
	drc &= ~(3 << 2); /* set the front side bus */
	drc |= (fsb_conversion[value] << 2);
	drc &= ~(3 << 0); /* set the dram type */
	drc |= (dram_type << 0);

	goto out;

 val_err:
	die("Bad SPD value\n");
	/* If an hw_error occurs report that I have no memory */
hw_err:
	drc = 0;
out:
	return drc;
}

static void sdram_set_spd_registers(const struct mem_controller *ctrl)
{
	long dimm_mask;

	/* Test if we can read the spd and if ram is ddr or ddr2 */
	dimm_mask = spd_detect_dimms(ctrl);
	if (!(dimm_mask & ((1 << DIMM_SOCKETS) - 1))) {
		print_err("No memory for this cpu\n");
		return;
	}
	return;
}

static void do_delay(void)
{
	int i;
	unsigned char b;
	for(i=0;i<16;i++)
		b=inb(0x80);
}

#define TIMEOUT_LOOPS 300000

#define DCALCSR  0x100
#define DCALADDR 0x104
#define DCALDATA 0x108

static void set_on_dimm_termination_enable(const struct mem_controller *ctrl)
{
	unsigned char c1,c2;
        unsigned int dimm,i;
        unsigned int data32;
	unsigned int t4;

	/* Set up northbridge values */
	/* ODT enable */
  	pci_write_config32(ctrl->f0, 0x88, 0xf0000180);
	/* Figure out which slots are Empty, Single, or Double sided */
	for(i=0,t4=0,c2=0;i<8;i+=2) {
		c1 = pci_read_config8(ctrl->f0, DRB+i);
		if(c1 == c2) continue;
		c2 = pci_read_config8(ctrl->f0, DRB+1+i);
		if(c1 == c2)
			t4 |= (1 << (i*4));
		else
			t4 |= (2 << (i*4));
	}
	for(i=0;i<1;i++) {
	    if((t4&0x0f) == 1) {
		if( ((t4>>8)&0x0f) == 0 ) {
			data32 = 0x00000010; /* EEES */
			break;
		}
		if ( ((t4>>16)&0x0f) == 0 ) {
			data32 = 0x00003132; /* EESS */
			break;
		}
		if ( ((t4>>24)&0x0f)  == 0 ) {
			data32 = 0x00335566; /* ESSS */
			break;
		}
		data32 = 0x77bbddee; /* SSSS */
		break;
	    }
	    if((t4&0x0f) == 2) {
		if( ((t4>>8)&0x0f) == 0 ) {
			data32 = 0x00003132; /* EEED */
			break;
		}
		if ( ((t4>>8)&0x0f) == 2 ) {
			data32 = 0xb373ecdc; /* EEDD */
			break;
		}
		if ( ((t4>>16)&0x0f) == 0 ) {
			data32 = 0x00b3a898; /* EESD */
			break;
		}
		data32 = 0x777becdc; /* ESSD */
		break;
	    }
	    die("Error - First dimm slot empty\n");
	}

	print_debug("ODT Value = ");
	print_debug_hex32(data32);
	print_debug("\n");

  	pci_write_config32(ctrl->f0, 0xb0, data32);

	for(dimm=0;dimm<8;dimm+=1) {

		write32(BAR+DCALADDR, 0x0b840001);
		write32(BAR+DCALCSR, 0x83000003 | (dimm << 20));

		for(i=0;i<1001;i++) {
			data32 = read32(BAR+DCALCSR);
			if(!(data32 & (1<<31)))
				break;
		}
	}
}
static void set_receive_enable(const struct mem_controller *ctrl)
{
	unsigned int i;
	unsigned int cnt,bit;
	uint32_t recena=0;
	uint32_t recenb=0;

	{
	unsigned int dimm;
	unsigned int edge;
	int32_t data32;
	uint32_t data32_dram;
	uint32_t dcal_data32_0;
	uint32_t dcal_data32_1;
	uint32_t dcal_data32_2;
	uint32_t dcal_data32_3;
	uint32_t work32l;
	uint32_t work32h;
	uint32_t data32r;
	int32_t recen;
	for(dimm=0;dimm<8;dimm+=1) {

		if(!(dimm&1)) {
			write32(BAR+DCALDATA+(17*4), 0x04020000);
			write32(BAR+DCALCSR, 0x83800004 | (dimm << 20));

			for(i=0;i<1001;i++) {
				data32 = read32(BAR+DCALCSR);
				if(!(data32 & (1<<31)))
					break;
			}
			if(i>=1000)
				continue;

			dcal_data32_0 = read32(BAR+DCALDATA + 0);
			dcal_data32_1 = read32(BAR+DCALDATA + 4);
			dcal_data32_2 = read32(BAR+DCALDATA + 8);
			dcal_data32_3 = read32(BAR+DCALDATA + 12);
		}
		else {
			dcal_data32_0 = read32(BAR+DCALDATA + 16);
			dcal_data32_1 = read32(BAR+DCALDATA + 20);
			dcal_data32_2 = read32(BAR+DCALDATA + 24);
			dcal_data32_3 = read32(BAR+DCALDATA + 28);
		}

		/* check if bank is installed */
		if((dcal_data32_0 == 0) && (dcal_data32_2 == 0))
			continue;
		/* Calculate the timing value */
		for(i=0,edge=0,bit=63,cnt=31,data32r=0,
			work32l=dcal_data32_1,work32h=dcal_data32_3;
				(i<4) && bit; i++) {
			for(;;bit--,cnt--) {
				if(work32l & (1<<cnt))
					break;
				if(!cnt) {
					work32l = dcal_data32_0;
					work32h = dcal_data32_2;
					cnt = 32;
				}
				if(!bit) break;
			}
			for(;;bit--,cnt--) {
				if(!(work32l & (1<<cnt)))
					break;
				if(!cnt) {
					work32l = dcal_data32_0;
					work32h = dcal_data32_2;
					cnt = 32;
				}
				if(!bit) break;
			}
			if(!bit) {
				break;
			}
			data32 = ((bit%8) << 1);
			if(work32h & (1<<cnt))
				data32 += 1;
			if(data32 < 4) {
				if(!edge) {
					edge = 1;
				}
				else {
					if(edge != 1) {
						data32 = 0x0f;
					}
				}
			}
			if(data32 > 12) {
				if(!edge) {
					edge = 2;
				}
				else {
					if(edge != 2) {
						data32 = 0x00;
					}
				}
			}
			data32r += data32;
		}

		work32l = dcal_data32_0;
		work32h = dcal_data32_2;
		recen = data32r;
		recen += 3;
		recen = recen>>2;
		for(cnt=5;cnt<24;) {
			for(;;cnt++)
				if(!(work32l & (1<<cnt)))
					break;
			for(;;cnt++) {
				if(work32l & (1<<cnt))
					break;
			}
			data32 = (((cnt-1)%8)<<1);
			if(work32h & (1<<(cnt-1))) {
				data32++;
			}
			/* test for frame edge cross overs */
			if((edge == 1) && (data32 > 12) &&
			    (((recen+16)-data32) < 3)) {
				data32 = 0;
				cnt += 2;
			}
			if((edge == 2) && (data32 < 4) &&
			    ((recen - data32) > 12))  {
				data32 = 0x0f;
				cnt -= 2;
			}
			if(((recen+3) >= data32) && ((recen-3) <= data32))
				break;
		}
		cnt--;
		cnt /= 8;
		cnt--;
		if(recen&1)
			recen+=2;
		recen >>= 1;
		recen += (cnt*8);
	recen+=2;
		recen <<= (dimm/2) * 8;
		if(!(dimm&1)) {
			recena |= recen;
		}
		else {
			recenb |= recen;
		}
	}
	}
	/* Check for Eratta problem */
	for(i=cnt=bit=0;i<4;i++) {
		if (((recena>>(i*8))&0x0f)>7) {
			cnt++; bit++;
		}
		else {
			if((recena>>(i*8))&0x0f) {
				cnt++;
			}
		}
	}
	if(bit) {
		cnt-=bit;
		if(cnt>1) {
			for(i=0;i<4;i++) {
				if(((recena>>(i*8))&0x0f)>7) {
					recena &= ~(0x0f<<(i*8));
					recena |= (7<<(i*8));
				}
			}
		}
		else {
			for(i=0;i<4;i++) {
				if(((recena>>(i*8))&0x0f)<8) {
					recena &= ~(0x0f<<(i*8));
					recena |= (8<<(i*8));
				}
			}
		}
	}
	for(i=cnt=bit=0;i<4;i++) {
		if (((recenb>>(i*8))&0x0f)>7) {
			cnt++; bit++;
		}
		else {
			if((recenb>>(i*8))&0x0f) {
				cnt++;
			}
		}
	}
	if(bit) {
		cnt-=bit;
		if(cnt>1) {
			for(i=0;i<4;i++) {
				if(((recenb>>(i*8))&0x0f)>7) {
					recenb &= ~(0x0f<<(i*8));
					recenb |= (7<<(i*8));
				}
			}
		}
		else {
			for(i=0;i<4;i++) {
				if(((recenb>>(i*8))&0x0f)<8) {
					recenb &= ~(0x0f<<(i*8));
					recenb |= (8<<(i*8));
				}
			}
		}
	}

//  recena = 0x0000090a;
//  recenb = 0x0000090a;

	print_debug("Receive enable A = ");
	print_debug_hex32(recena);
	print_debug(",  Receive enable B = ");
	print_debug_hex32(recenb);
	print_debug("\n");

	/* clear out the calibration area */
	write32(BAR+DCALDATA+(16*4), 0x00000000);
	write32(BAR+DCALDATA+(17*4), 0x00000000);
	write32(BAR+DCALDATA+(18*4), 0x00000000);
	write32(BAR+DCALDATA+(19*4), 0x00000000);

	/* No command */
	write32(BAR+DCALCSR, 0x0000000f);

	write32(BAR+0x150, recena);
	write32(BAR+0x154, recenb);
}


static void sdram_enable(int controllers, const struct mem_controller *ctrl)
{
	int i;
	int cs;
	int cnt;
	int cas_latency;
	long mask;
	uint32_t drc;
	uint32_t data32;
	uint32_t mode_reg;
	uint32_t *iptr;
	volatile unsigned long *iptrv;
	msr_t msr;
	uint32_t scratch;
	uint8_t byte;
	uint16_t data16;
	static const struct {
		uint32_t clkgr[4];
	} gearing [] = {
		/* FSB 133 DIMM 266 */
	{{ 0x00000001, 0x00000000, 0x00000001, 0x00000000}},
		/* FSB 133 DIMM 333 */
	{{ 0x00000000, 0x00000000, 0x00000000, 0x00000000}},
		/* FSB 133 DIMM 400 */
	{{ 0x00000120, 0x00000000, 0x00000032, 0x00000010}},
		/* FSB 167 DIMM 266 */
	{{ 0x00005432, 0x00001000, 0x00004325, 0x00000000}},
		/* FSB 167 DIMM 333 */
	{{ 0x00000001, 0x00000000, 0x00000001, 0x00000000}},
		/* FSB 167 DIMM 400 */
	{{ 0x00154320, 0x00000000, 0x00065432, 0x00010000}},
		/* FSB 200 DIMM 266 */
	{{ 0x00000032, 0x00000010, 0x00000120, 0x00000000}},
		/* FSB 200 DIMM 333 */
	{{ 0x00065432, 0x00010000, 0x00054326, 0x00000000}},
		/* FSB 200 DIMM 400 */
	{{ 0x00000001, 0x00000000, 0x00000001, 0x00000000}},
	};

	static const uint32_t dqs_data[] = {
		0xffffffff, 0xffffffff, 0x000000ff,
		0xffffffff, 0xffffffff, 0x000000ff,
		0xffffffff, 0xffffffff,	0x000000ff,
		0xffffffff, 0xffffffff, 0x000000ff,
		0xffffffff, 0xffffffff, 0x000000ff,
		0xffffffff, 0xffffffff, 0x000000ff,
		0xffffffff, 0xffffffff, 0x000000ff,
		0xffffffff, 0xffffffff, 0x000000ff};

	mask = spd_detect_dimms(ctrl);
	print_debug("Starting SDRAM Enable\n");

	/* 0x80 */
	pci_write_config32(ctrl->f0, DRM,
		0x00210000 | CONFIG_DIMM_MAP_LOGICAL);
	/* set dram type and Front Side Bus freq. */
	drc = spd_set_dram_controller_mode(ctrl, mask);
	if( drc == 0) {
		die("Error calculating DRC\n");
	}
	data32 = drc & ~(3 << 20);  /* clear ECC mode */
	data32 = data32 & ~(7 << 8);  /* clear refresh rates */
	data32 = data32 | (1 << 5);  /* temp turn off of ODT */
  	/* Set gearing, then dram controller mode */
  	/* drc bits 1:0 = DIMM speed, bits 3:2 = FSB speed */
  	for(iptr = gearing[(drc&3)+((((drc>>2)&3)-1)*3)].clkgr,cnt=0;
			cnt<4;cnt++) {
  		pci_write_config32(ctrl->f0, 0xa0+(cnt*4), iptr[cnt]);
	}
	/* 0x7c DRC */
  	pci_write_config32(ctrl->f0, DRC, data32);

		/* turn the clocks on */
	/* 0x8c CKDIS */
  	pci_write_config16(ctrl->f0, CKDIS, 0x0000);

		/* 0x9a DDRCSR Take subsystem out of idle */
  	data16 = pci_read_config16(ctrl->f0, DDRCSR);
	data16 &= ~(7 << 12);
	data16 |= (3 << 12);   /* use dual channel lock step */
  	pci_write_config16(ctrl->f0, DDRCSR, data16);

		/* program row size DRB */
	spd_set_ram_size(ctrl, mask);

		/* program page size DRA */
	spd_set_row_attributes(ctrl, mask);

		/* program DRT timing values */
	cas_latency = spd_set_drt_attributes(ctrl, mask, drc);

	for(i=0;i<8;i++) { /* loop throught each dimm to test for row */
		print_debug("DIMM ");
		print_debug_hex8(i);
		print_debug("\n");
		/* Apply NOP */
		do_delay();

		write32(BAR + 0x100, (0x03000000 | (i<<20)));

		write32(BAR+0x100, (0x83000000 | (i<<20)));

		do data32 = read32(BAR+DCALCSR);
		while(data32 & 0x80000000);

	}

	/* Apply NOP */
	do_delay();

	for(cs=0;cs<8;cs++) {
		write32(BAR + DCALCSR, (0x83000000 | (cs<<20)));
		do data32 = read32(BAR+DCALCSR);
		while(data32 & 0x80000000);
	}

	/* Precharg all banks */
	do_delay();
	for(cs=0;cs<8;cs++) {
		if ((drc & 3) == 2) /* DDR2  */
                        write32(BAR+DCALADDR, 0x04000000);
                else   /* DDR1  */
                        write32(BAR+DCALADDR, 0x00000000);
		write32(BAR+DCALCSR, (0x83000002 | (cs<<20)));
		do data32 = read32(BAR+DCALCSR);
		while(data32 & 0x80000000);
	}

	/* EMRS dll's enabled */
	do_delay();
	for(cs=0;cs<8;cs++) {
		if ((drc & 3) == 2) /* DDR2  */
			/* fixme hard code AL additive latency */
                        write32(BAR+DCALADDR, 0x0b940001);
                else   /* DDR1  */
                        write32(BAR+DCALADDR, 0x00000001);
		write32(BAR+DCALCSR, (0x83000003 | (cs<<20)));
		do data32 = read32(BAR+DCALCSR);
		while(data32 & 0x80000000);
	}
	/* MRS reset dll's */
	do_delay();
	if ((drc & 3) == 2) {  /* DDR2  */
                if(cas_latency == 30)
                        mode_reg = 0x053a0000;
                else
                        mode_reg = 0x054a0000;
        }
        else {  /* DDR1  */
                if(cas_latency == 20)
                        mode_reg = 0x012a0000;
                else  /*  CAS Latency 2.5 */
                        mode_reg = 0x016a0000;
        }
	for(cs=0;cs<8;cs++) {
		write32(BAR+DCALADDR, mode_reg);
		write32(BAR+DCALCSR, (0x83000003 | (cs<<20)));
		do data32 = read32(BAR+DCALCSR);
		while(data32 & 0x80000000);
	}

	/* Precharg all banks */
	do_delay();
	do_delay();
	do_delay();
	for(cs=0;cs<8;cs++) {
		if ((drc & 3) == 2) /* DDR2  */
                        write32(BAR+DCALADDR, 0x04000000);
                else   /* DDR1  */
                        write32(BAR+DCALADDR, 0x00000000);
		write32(BAR+DCALCSR, (0x83000002 | (cs<<20)));
		do data32 = read32(BAR+DCALCSR);
		while(data32 & 0x80000000);
	}

	/* Do 2 refreshes */
	do_delay();
	for(cs=0;cs<8;cs++) {
		write32(BAR+DCALCSR, (0x83000001 | (cs<<20)));
		do data32 = read32(BAR+DCALCSR);
		while(data32 & 0x80000000);
	}
	do_delay();
	for(cs=0;cs<8;cs++) {
		write32(BAR+DCALCSR, (0x83000001 | (cs<<20)));
		do data32 = read32(BAR+DCALCSR);
		while(data32 & 0x80000000);
	}
	do_delay();
	/* for good luck do 6 more */
	for(cs=0;cs<8;cs++) {
		write32(BAR+DCALCSR, (0x83000001 | (cs<<20)));
	}
	do_delay();
	for(cs=0;cs<8;cs++) {
		write32(BAR+DCALCSR, (0x83000001 | (cs<<20)));
	}
	do_delay();
	for(cs=0;cs<8;cs++) {
		write32(BAR+DCALCSR, (0x83000001 | (cs<<20)));
	}
	do_delay();
	for(cs=0;cs<8;cs++) {
		write32(BAR+DCALCSR, (0x83000001 | (cs<<20)));
	}
	do_delay();
	for(cs=0;cs<8;cs++) {
		write32(BAR+DCALCSR, (0x83000001 | (cs<<20)));
	}
	do_delay();
	for(cs=0;cs<8;cs++) {
		write32(BAR+DCALCSR, (0x83000001 | (cs<<20)));
	}
	do_delay();
	/* MRS reset dll's normal */
	do_delay();
	for(cs=0;cs<8;cs++) {
		write32(BAR+DCALADDR, (mode_reg & ~(1<<24)));
		write32(BAR+DCALCSR, (0x83000003 | (cs<<20)));
		do data32 = read32(BAR+DCALCSR);
		while(data32 & 0x80000000);
	}

	/* Do only if DDR2  EMRS dll's enabled */
        if ((drc & 3) == 2) { /* DDR2  */
                do_delay();
                for(cs=0;cs<8;cs++) {
                        write32(BAR+DCALADDR, (0x0b940001));
                        write32(BAR+DCALCSR, (0x83000003 | (cs<<20)));
			do data32 = read32(BAR+DCALCSR);
			while(data32 & 0x80000000);
                }
        }

	do_delay();
	/* No command */
	write32(BAR+DCALCSR, 0x0000000f);

	/* DDR1 This is test code to copy some codes in the factory setup */

	write32(BAR, 0x00100000);

        if ((drc & 3) == 2) { /* DDR2  */
	/* enable on dimm termination */
		set_on_dimm_termination_enable(ctrl);
	}

	/* receive enable calibration */
	set_receive_enable(ctrl);

	/* DQS */
	pci_write_config32(ctrl->f0, 0x94, 0x3904a100 );
	for(i = 0, cnt = (BAR+0x200); i < 24; i++, cnt+=4) {
		write32(cnt, dqs_data[i]);
	}
	pci_write_config32(ctrl->f0, 0x94, 0x3904a100 );

	/* Enable refresh */
	/* 0x7c DRC */
	data32 = drc & ~(3 << 20);  /* clear ECC mode */
	pci_write_config32(ctrl->f0, DRC, data32);
	write32(BAR+DCALCSR, 0x0008000f);

	/* clear memory and init ECC */
	print_debug("Clearing memory\n");
	for(i=0;i<64;i+=4) {
		write32(BAR+DCALDATA+i, 0x00000000);
	}

	for(cs=0;cs<8;cs++) {
		write32(BAR+DCALCSR, (0x830831d8 | (cs<<20)));
		do data32 = read32(BAR+DCALCSR);
		while(data32 & 0x80000000);
	}

	/* Bring memory subsystem on line */
	data32 = pci_read_config32(ctrl->f0, 0x98);
	data32 |= (1 << 31);
	pci_write_config32(ctrl->f0, 0x98, data32);
	/* wait for completion */
	print_debug("Waiting for mem complete\n");
	while(1) {
		data32 = pci_read_config32(ctrl->f0, 0x98);
		if( (data32 & (1<<31)) == 0)
			break;
	}
	print_debug("Done\n");

	/* Set initialization complete */
	/* 0x7c DRC */
	drc |= (1 << 29);
	data32 = drc & ~(3 << 20);  /* clear ECC mode */
	pci_write_config32(ctrl->f0, DRC, data32);

	/* Set the ecc mode */
	pci_write_config32(ctrl->f0, DRC, drc);

	/* Enable memory scrubbing */
	/* 0x52 MCHSCRB */
	data16 = pci_read_config16(ctrl->f0, MCHSCRB);
	data16 &= ~0x0f;
	data16 |= ((2 << 2) | (2 << 0));
	pci_write_config16(ctrl->f0, MCHSCRB, data16);

	/* The memory is now setup, use it */
	cache_ramstage();
}
