/*
 * (C) Copyright 2004, Freescale, Inc
 * TsiChung Liew, Tsi-Chung.Liew@freescale.com
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * 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., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */

/*
DESCRIPTION
Read Dram spd and base on its information to calculate the memory size,
characteristics to initialize the dram on MPC8220
*/

#include <common.h>
#include <mpc8220.h>
#include "i2cCore.h"
#include "dramSetup.h"

#define SPD_SIZE	CFG_SDRAM_SPD_SIZE
#define DRAM_SPD	(CFG_SDRAM_SPD_I2C_ADDR)<<1	/* on Board SPD eeprom */
#define TOTAL_BANK	CFG_SDRAM_TOTAL_BANKS

int spd_status (volatile i2c8220_t * pi2c, u8 sta_bit, u8 truefalse)
{
	int i;

	for (i = 0; i < I2C_POLL_COUNT; i++) {
		if ((pi2c->sr & sta_bit) == (truefalse ? sta_bit : 0))
			return (OK);
	}

	return (ERROR);
}

int spd_clear (volatile i2c8220_t * pi2c)
{
	pi2c->adr = 0;
	pi2c->fdr = 0;
	pi2c->cr = 0;
	pi2c->sr = 0;

	return (OK);
}

int spd_stop (volatile i2c8220_t * pi2c)
{
	pi2c->cr &= ~I2C_CTL_STA;	/* Generate stop signal         */
	if (spd_status (pi2c, I2C_STA_BB, 0) != OK)
		return ERROR;

	return (OK);
}

int spd_readbyte (volatile i2c8220_t * pi2c, u8 * readb, int *index)
{
	pi2c->sr &= ~I2C_STA_IF;	/* Clear Interrupt Bit          */
	*readb = pi2c->dr;	/* Read a byte                  */

	/*
	   Set I2C_CTRL_TXAK will cause Transfer pending and
	   set I2C_CTRL_STA will cause Interrupt pending
	 */
	if (*index != 2) {
		if (spd_status (pi2c, I2C_STA_CF, 1) != OK)	/* Transfer not complete?       */
			return ERROR;
	}

	if (*index != 1) {
		if (spd_status (pi2c, I2C_STA_IF, 1) != OK)
			return ERROR;
	}

	return (OK);
}

int readSpdData (u8 * spdData)
{
	DECLARE_GLOBAL_DATA_PTR;

	volatile i2c8220_t *pi2cReg;
	volatile pcfg8220_t *pcfg;
	u8 slvAdr = DRAM_SPD;
	u8 Tmp;
	int Length = SPD_SIZE;
	int i = 0;

	/* Enable Port Configuration for SDA and SDL signals */
	pcfg = (volatile pcfg8220_t *) (MMAP_PCFG);
	__asm__ ("sync");
	pcfg->pcfg3 &= ~CFG_I2C_PORT3_CONFIG;
	__asm__ ("sync");

	/* Points the structure to I2c mbar memory offset */
	pi2cReg = (volatile i2c8220_t *) (MMAP_I2C);


	/* Clear FDR, ADR, SR and CR reg */
	pi2cReg->adr = 0;
	pi2cReg->fdr = 0;
	pi2cReg->cr = 0;
	pi2cReg->sr = 0;

	/* Set for fix XLB Bus Frequency */
	switch (gd->bus_clk) {
	case 60000000:
		pi2cReg->fdr = 0x15;
		break;
	case 70000000:
		pi2cReg->fdr = 0x16;
		break;
	case 80000000:
		pi2cReg->fdr = 0x3a;
		break;
	case 90000000:
		pi2cReg->fdr = 0x17;
		break;
	case 100000000:
		pi2cReg->fdr = 0x3b;
		break;
	case 110000000:
		pi2cReg->fdr = 0x18;
		break;
	case 120000000:
		pi2cReg->fdr = 0x19;
		break;
	case 130000000:
		pi2cReg->fdr = 0x1a;
		break;
	}

	pi2cReg->adr = CFG_I2C_SLAVE<<1;

	pi2cReg->cr = I2C_CTL_EN;	/* Set Enable         */

	/*
	   The I2C bus should be in Idle state. If the bus is busy,
	   clear the STA bit in control register
	 */
	if (spd_status (pi2cReg, I2C_STA_BB, 0) != OK) {
		if ((pi2cReg->cr & I2C_CTL_STA) == I2C_CTL_STA)
			pi2cReg->cr &= ~I2C_CTL_STA;

		/* Check again if it is still busy, return error if found */
		if (spd_status (pi2cReg, I2C_STA_BB, 1) == OK)
			return ERROR;
	}

	pi2cReg->cr |= I2C_CTL_TX;	/* Enable the I2c for TX, Ack   */
	pi2cReg->cr |= I2C_CTL_STA;	/* Generate start signal        */

	if (spd_status (pi2cReg, I2C_STA_BB, 1) != OK)
		return ERROR;


	/* Write slave address */
	pi2cReg->sr &= ~I2C_STA_IF;	/* Clear Interrupt              */
	pi2cReg->dr = slvAdr;	/* Write a byte                 */

	if (spd_status (pi2cReg, I2C_STA_CF, 1) != OK) {	/* Transfer not complete?       */
		spd_stop (pi2cReg);
		return ERROR;
	}

	if (spd_status (pi2cReg, I2C_STA_IF, 1) != OK) {
		spd_stop (pi2cReg);
		return ERROR;
	}


	/* Issue the offset to start */
	pi2cReg->sr &= ~I2C_STA_IF;	/* Clear Interrupt              */
	pi2cReg->dr = 0;	/* Write a byte                 */

	if (spd_status (pi2cReg, I2C_STA_CF, 1) != OK) {	/* Transfer not complete?       */
		spd_stop (pi2cReg);
		return ERROR;
	}

	if (spd_status (pi2cReg, I2C_STA_IF, 1) != OK) {
		spd_stop (pi2cReg);
		return ERROR;
	}


	/* Set repeat start */
	pi2cReg->cr |= I2C_CTL_RSTA;	/* Repeat Start                 */

	pi2cReg->sr &= ~I2C_STA_IF;	/* Clear Interrupt              */
	pi2cReg->dr = slvAdr | 1;	/* Write a byte                 */

	if (spd_status (pi2cReg, I2C_STA_CF, 1) != OK) {	/* Transfer not complete?       */
		spd_stop (pi2cReg);
		return ERROR;
	}

	if (spd_status (pi2cReg, I2C_STA_IF, 1) != OK) {
		spd_stop (pi2cReg);
		return ERROR;
	}

	if (((pi2cReg->sr & 0x07) == 0x07) || (pi2cReg->sr & 0x01))
		return ERROR;

	pi2cReg->cr &= ~I2C_CTL_TX;	/* Set receive mode             */

	if (((pi2cReg->sr & 0x07) == 0x07) || (pi2cReg->sr & 0x01))
		return ERROR;

	/* Dummy Read */
	if (spd_readbyte (pi2cReg, &Tmp, &i) != OK) {
		spd_stop (pi2cReg);
		return ERROR;
	}

	i = 0;
	while (Length) {
		if (Length == 2)
			pi2cReg->cr |= I2C_CTL_TXAK;

		if (Length == 1)
			pi2cReg->cr &= ~I2C_CTL_STA;

		if (spd_readbyte (pi2cReg, spdData, &Length) != OK) {
			return spd_stop (pi2cReg);
		}
		i++;
		Length--;
		spdData++;
	}

	/* Stop the service */
	spd_stop (pi2cReg);

	return OK;
}

int getBankInfo (int bank, draminfo_t * pBank)
{
	int status;
	int checksum;
	int count;
	u8 spdData[SPD_SIZE];


	if (bank > 2 || pBank == 0) {
		/* illegal values */
		return (-42);
	}

	status = readSpdData (&spdData[0]);
	if (status < 0)
		return (-1);

	/* check the checksum */
	for (count = 0, checksum = 0; count < LOC_CHECKSUM; count++)
		checksum += spdData[count];

	checksum = checksum - ((checksum / 256) * 256);

	if (checksum != spdData[LOC_CHECKSUM])
		return (-2);

	/* Get the memory type */
	if (!
	    ((spdData[LOC_TYPE] == TYPE_DDR)
	     || (spdData[LOC_TYPE] == TYPE_SDR)))
		/* not one of the types we support */
		return (-3);

	pBank->type = spdData[LOC_TYPE];

	/* Set logical banks */
	pBank->banks = spdData[LOC_LOGICAL_BANKS];

	/* Check that we have enough physical banks to cover the bank we are
	 * figuring out.  Odd-numbered banks correspond to the second bank
	 * on the device.
	 */
	if (bank & 1) {
		/* Second bank of a "device" */
		if (spdData[LOC_PHYS_BANKS] < 2)
			/* this bank doesn't exist on the "device" */
			return (-4);

		if (spdData[LOC_ROWS] & 0xf0)
			/* Two asymmetric banks */
			pBank->rows = spdData[LOC_ROWS] >> 4;
		else
			pBank->rows = spdData[LOC_ROWS];

		if (spdData[LOC_COLS] & 0xf0)
			/* Two asymmetric banks */
			pBank->cols = spdData[LOC_COLS] >> 4;
		else
			pBank->cols = spdData[LOC_COLS];
	} else {
		/* First bank of a "device" */
		pBank->rows = spdData[LOC_ROWS];
		pBank->cols = spdData[LOC_COLS];
	}

	pBank->width = spdData[LOC_WIDTH_HIGH] << 8 | spdData[LOC_WIDTH_LOW];
	pBank->bursts = spdData[LOC_BURSTS];
	pBank->CAS = spdData[LOC_CAS];
	pBank->CS = spdData[LOC_CS];
	pBank->WE = spdData[LOC_WE];
	pBank->Trp = spdData[LOC_Trp];
	pBank->Trcd = spdData[LOC_Trcd];
	pBank->buffered = spdData[LOC_Buffered] & 1;
	pBank->refresh = spdData[LOC_REFRESH];

	return (0);
}


/* checkMuxSetting -- given a row/column device geometry, return a mask
 *                    of the valid DRAM controller addr_mux settings for
 *                    that geometry.
 *
 *  Arguments:        u8 rows:     number of row addresses in this device
 *                    u8 columns:  number of column addresses in this device
 *
 *  Returns:          a mask of the allowed addr_mux settings for this
 *                    geometry.  Each bit in the mask represents a
 *                    possible addr_mux settings (for example, the
 *                    (1<<2) bit in the mask represents the 0b10 setting)/
 *
 */
u8 checkMuxSetting (u8 rows, u8 columns)
{
	muxdesc_t *pIdx, *pMux;
	u8 mask;
	int lrows, lcolumns;
	u32 mux[4] = { 0x00080c04, 0x01080d03, 0x02080e02, 0xffffffff };

	/* Setup MuxDescriptor in SRAM space */
	/* MUXDESC AddressRuns [] = {
	   { 0, 8, 12, 4 },         / setting, columns, rows, extra columns /
	   { 1, 8, 13, 3 },         / setting, columns, rows, extra columns /
	   { 2, 8, 14, 2 },         / setting, columns, rows, extra columns /
	   { 0xff }                 / list terminator /
	   }; */

	pIdx = (muxdesc_t *) & mux[0];

	/* Check rows x columns against each possible address mux setting */
	for (pMux = pIdx, mask = 0;; pMux++) {
		lrows = rows;
		lcolumns = columns;

		if (pMux->MuxValue == 0xff)
			break;	/* end of list */

		/* For a given mux setting, since we want all the memory in a
		 * device to be contiguous, we want the device "use up" the
		 * address lines such that there are no extra column or row
		 * address lines on the device.
		 */

		lcolumns -= pMux->Columns;
		if (lcolumns < 0)
			/* Not enough columns to get to the rows */
			continue;

		lrows -= pMux->Rows;
		if (lrows > 0)
			/* we have extra rows left -- can't do that! */
			continue;

		/* At this point, we either have to have used up all the
		 * rows or we have to have no columns left.
		 */

		if (lcolumns != 0 && lrows != 0)
			/* rows AND columns are left.  Bad! */
			continue;

		lcolumns -= pMux->MoreColumns;

		if (lcolumns <= 0)
			mask |= (1 << pMux->MuxValue);
	}

	return (mask);
}


u32 dramSetup (void)
{
	DECLARE_GLOBAL_DATA_PTR;

	draminfo_t DramInfo[TOTAL_BANK];
	draminfo_t *pDramInfo;
	u32 size, temp, cfg_value, mode_value, refresh;
	u8 *ptr;
	u8 bursts, Trp, Trcd, type, buffered;
	u8 muxmask, rows, columns;
	int count, banknum;
	u32 *prefresh, *pIdx;
	u32 refrate[8] = { 15625, 3900, 7800, 31300,
		62500, 125000, 0xffffffff, 0xffffffff
	};
	volatile sysconf8220_t *sysconf;
	volatile memctl8220_t *memctl;

	sysconf = (volatile sysconf8220_t *) MMAP_MBAR;
	memctl = (volatile memctl8220_t *) MMAP_MEMCTL;

	/* Set everything in the descriptions to zero */
	ptr = (u8 *) & DramInfo[0];
	for (count = 0; count < sizeof (DramInfo); count++)
		*ptr++ = 0;

	for (banknum = 0; banknum < TOTAL_BANK; banknum++)
		sysconf->cscfg[banknum];

	/* Descriptions of row/column address muxing for various
	 * addr_mux settings.
	 */

	pIdx = prefresh = (u32 *) & refrate[0];

	/* Get all the info for all three logical banks */
	bursts = 0xff;
	Trp = 0;
	Trcd = 0;
	type = 0;
	buffered = 0xff;
	refresh = 0xffffffff;
	muxmask = 0xff;

	/* Two bank, CS0 and CS1 */
	for (banknum = 0, pDramInfo = &DramInfo[0];
	     banknum < TOTAL_BANK; banknum++, pDramInfo++) {
		pDramInfo->ordinal = banknum;	/* initial sorting */
		if (getBankInfo (banknum, pDramInfo) < 0)
			continue;

		/* get cumulative parameters of all three banks */
		if (type && pDramInfo->type != type)
			return 0;

		type = pDramInfo->type;
		rows = pDramInfo->rows;
		columns = pDramInfo->cols;

		/* This chip only supports 13 DRAM memory lines, but some devices
		 * have 14 rows.  To deal with this, ignore the 14th address line
		 * by limiting the number of rows (and columns) to 13.  This will
		 * mean that for 14-row devices we will only be able to use
		 * half of the memory, but it's better than nothing.
		 */
		if (rows > 13)
			rows = 13;
		if (columns > 13)
			columns = 13;

		pDramInfo->size =
			((1 << (rows + columns)) * pDramInfo->width);
		pDramInfo->size *= pDramInfo->banks;
		pDramInfo->size >>= 3;

		/* figure out which addr_mux configurations will support this device */
		muxmask &= checkMuxSetting (rows, columns);
		if (muxmask == 0)
			return 0;

		buffered = pDramInfo->buffered;
		bursts &= pDramInfo->bursts;	/* union of all bursts */
		if (pDramInfo->Trp > Trp)	/* worst case (longest) Trp */
			Trp = pDramInfo->Trp;

		if (pDramInfo->Trcd > Trcd)	/* worst case (longest) Trcd */
			Trcd = pDramInfo->Trcd;

		prefresh = pIdx;
		/* worst case (shortest) Refresh period */
		if (refresh > prefresh[pDramInfo->refresh & 7])
			refresh = prefresh[pDramInfo->refresh & 7];

	}			/* for loop */


	/* We only allow a burst length of 8! */
	if (!(bursts & 8))
		bursts = 8;

	/* Sort the devices.  In order to get each chip select region
	 * aligned properly, put the biggest device at the lowest address.
	 * A simple bubble sort will do the trick.
	 */
	for (banknum = 0, pDramInfo = &DramInfo[0];
	     banknum < TOTAL_BANK; banknum++, pDramInfo++) {
		int i;

		for (i = 0; i < TOTAL_BANK; i++) {
			if (pDramInfo->size < DramInfo[i].size &&
			    pDramInfo->ordinal < DramInfo[i].ordinal) {
				/* If the current bank is smaller, but if the ordinal is also
				 * smaller, swap the ordinals
				 */
				u8 temp8;

				temp8 = DramInfo[i].ordinal;
				DramInfo[i].ordinal = pDramInfo->ordinal;
				pDramInfo->ordinal = temp8;
			}
		}
	}


	/* Now figure out the base address for each bank.  While
	 * we're at it, figure out how much memory there is.
	 *
	 */
	size = 0;
	for (banknum = 0; banknum < TOTAL_BANK; banknum++) {
		int i;

		for (i = 0; i < TOTAL_BANK; i++) {
			if (DramInfo[i].ordinal == banknum
			    && DramInfo[i].size != 0) {
				DramInfo[i].base = size;
				size += DramInfo[i].size;
			}
		}
	}

	/* Set up the Drive Strength register */
	temp = ((DRIVE_STRENGTH_LOW << SDRAMDS_SBE_SHIFT)
		| (DRIVE_STRENGTH_HIGH << SDRAMDS_SBC_SHIFT)
		| (DRIVE_STRENGTH_LOW << SDRAMDS_SBA_SHIFT)
		| (DRIVE_STRENGTH_OFF << SDRAMDS_SBS_SHIFT)
		| (DRIVE_STRENGTH_LOW << SDRAMDS_SBD_SHIFT));
	sysconf->sdramds = temp;

	/* ********************** Cfg 1 ************************* */

	/* Set the single read to read/write/precharge delay */
	cfg_value = CFG1_SRD2RWP ((type == TYPE_DDR) ? 7 : 0xb);

	/* Set the single write to read/write/precharge delay.
	 * This may or may not be correct.  The controller spec
	 * says "tWR", but "tWR" does not appear in the SPD.  It
	 * always seems to be 15nsec for the class of device we're
	 * using, which turns out to be 2 clock cycles at 133MHz,
	 * so that's what we're going to use.
	 *
	 * HOWEVER, because of a bug in the controller, for DDR
	 * we need to set this to be the same as the value
	 * calculated for bwt2rwp.
	 */
	cfg_value |= CFG1_SWT2RWP ((type == TYPE_DDR) ? 7 : 2);

	/* Set the Read CAS latency.  We're going to use a CL of
	 * 2.5 for DDR and 2 SDR.
	 */
	cfg_value |= CFG1_RLATENCY ((type == TYPE_DDR) ? 7 : 2);


	/* Set the Active to Read/Write delay.  This depends
	 * on Trcd which is reported as nanoseconds times 4.
	 * We want to calculate Trcd (in nanoseconds) times XLB clock (in Hz)
	 * which gives us a dimensionless quantity.  Play games with
	 * the divisions so we don't run out of dynamic ranges.
	 */
	/* account for megaherz and the times 4 */
	temp = (Trcd * (gd->bus_clk / 1000000)) / 4;

	/* account for nanoseconds and round up, with a minimum value of 2 */
	temp = ((temp + 999) / 1000) - 1;
	if (temp < 2)
		temp = 2;

	cfg_value |= CFG1_ACT2WR (temp);

	/* Set the precharge to active delay.  This depends
	 * on Trp which is reported as nanoseconds times 4.
	 * We want to calculate Trp (in nanoseconds) times XLB clock (in Hz)
	 * which gives us a dimensionless quantity.  Play games with
	 * the divisions so we don't run out of dynamic ranges.
	 */
	/* account for megaherz and the times 4 */
	temp = (Trp * (gd->bus_clk / 1000000)) / 4;

	/* account for nanoseconds and round up, then subtract 1, with a
	 * minumum value of 1 and a maximum value of 7.
	 */
	temp = (((temp + 999) / 1000) - 1) & 7;
	if (temp < 1)
		temp = 1;

	cfg_value |= CFG1_PRE2ACT (temp);

	/* Set refresh to active delay.  This depends
	 * on Trfc which is not reported in the SPD.
	 * We'll use a nominal value of 75nsec which is
	 * what the controller spec uses.
	 */
	temp = (75 * (gd->bus_clk / 1000000));
	/* account for nanoseconds and round up, then subtract 1 */
	cfg_value |= CFG1_REF2ACT (((temp + 999) / 1000) - 1);

	/* Set the write latency, using the values given in the controller spec */
	cfg_value |= CFG1_WLATENCY ((type == TYPE_DDR) ? 3 : 0);
	memctl->cfg1 = cfg_value;	/* cfg 1 */
	asm volatile ("sync");


	/* ********************** Cfg 2 ************************* */

	/* Set the burst read to read/precharge delay */
	cfg_value = CFG2_BRD2RP ((type == TYPE_DDR) ? 5 : 8);

	/* Set the burst write to read/precharge delay.  Semi-magic numbers
	 * based on the controller spec recommendations, assuming tWR is
	 * two clock cycles.
	 */
	cfg_value |= CFG2_BWT2RWP ((type == TYPE_DDR) ? 7 : 10);

	/* Set the Burst read to write delay.  Semi-magic numbers
	 * based on the DRAM controller documentation.
	 */
	cfg_value |= CFG2_BRD2WT ((type == TYPE_DDR) ? 7 : 0xb);

	/* Set the burst length -- must be 8!! Well, 7, actually, becuase
	 * it's burst lenght minus 1.
	 */
	cfg_value |= CFG2_BURSTLEN (7);
	memctl->cfg2 = cfg_value;	/* cfg 2 */
	asm volatile ("sync");


	/* ********************** mode ************************* */

	/* Set enable bit, CKE high/low bits, and the DDR/SDR mode bit,
	 * disable automatic refresh.
	 */
	cfg_value = CTL_MODE_ENABLE | CTL_CKE_HIGH |
		((type == TYPE_DDR) ? CTL_DDR_MODE : 0);

	/* Set the address mux based on whichever setting(s) is/are common
	 * to all the devices we have.  If there is more than one, choose
	 * one arbitrarily.
	 */
	if (muxmask & 0x4)
		cfg_value |= CTL_ADDRMUX (2);
	else if (muxmask & 0x2)
		cfg_value |= CTL_ADDRMUX (1);
	else
		cfg_value |= CTL_ADDRMUX (0);

	/* Set the refresh interval. */
	temp = ((refresh * (gd->bus_clk / 1000000)) / (1000 * 64)) - 1;
	cfg_value |= CTL_REFRESH_INTERVAL (temp);

	/* Set buffered/non-buffered memory */
	if (buffered)
		cfg_value |= CTL_BUFFERED;

	memctl->ctrl = cfg_value;	/* ctrl */
	asm volatile ("sync");

	if (type == TYPE_DDR) {
		/* issue precharge all */
		temp = cfg_value | CTL_PRECHARGE_CMD;
		memctl->ctrl = temp;	/* ctrl */
		asm volatile ("sync");
	}


	/* Set up mode value for CAS latency */
#if (CFG_SDRAM_CAS_LATENCY==5) /* CL=2.5 */
	mode_value = (MODE_MODE | MODE_BURSTLEN (MODE_BURSTLEN_8) |
		MODE_BT_SEQUENTIAL | MODE_CL (MODE_CL_2p5) | MODE_CMD);
#else
	mode_value = (MODE_MODE | MODE_BURSTLEN (MODE_BURSTLEN_8) |
		      MODE_BT_SEQUENTIAL | MODE_CL (MODE_CL_2) | MODE_CMD);
#endif
	asm volatile ("sync");

	/* Write Extended Mode  - enable DLL */
	if (type == TYPE_DDR) {
		temp = MODE_EXTENDED | MODE_X_DLL_ENABLE |
			MODE_X_DS_NORMAL | MODE_CMD;
		memctl->mode = (temp >> 16);	/* mode */
		asm volatile ("sync");

		/* Write Mode - reset DLL, set CAS latency */
		temp = mode_value | MODE_OPMODE (MODE_OPMODE_RESETDLL);
		memctl->mode = (temp >> 16);	/* mode */
		asm volatile ("sync");
	}

	/* Program the chip selects. */
	for (banknum = 0; banknum < TOTAL_BANK; banknum++) {
		if (DramInfo[banknum].size != 0) {
			u32 mask;
			int i;

			for (i = 0, mask = 1; i < 32; mask <<= 1, i++) {
				if (DramInfo[banknum].size & mask)
					break;
			}
			temp = (DramInfo[banknum].base & 0xfff00000) | (i -
									1);

			sysconf->cscfg[banknum] = temp;
			asm volatile ("sync");
		}
	}

	/* Wait for DLL lock */
	udelay (200);

	temp = cfg_value | CTL_PRECHARGE_CMD;	/* issue precharge all */
	memctl->ctrl = temp;	/* ctrl */
	asm volatile ("sync");

	temp = cfg_value | CTL_REFRESH_CMD;	/* issue precharge all */
	memctl->ctrl = temp;	/* ctrl */
	asm volatile ("sync");

	memctl->ctrl = temp;	/* ctrl */
	asm volatile ("sync");

	/* Write Mode - DLL normal */
	temp = mode_value | MODE_OPMODE (MODE_OPMODE_NORMAL);
	memctl->mode = (temp >> 16);	/* mode */
	asm volatile ("sync");

	/* Enable refresh, enable DQS's (if DDR), and lock the control register */
	cfg_value &= ~CTL_MODE_ENABLE;	/* lock register */
	cfg_value |= CTL_REFRESH_ENABLE;	/* enable refresh */

	if (type == TYPE_DDR)
		cfg_value |= CTL_DQSOEN (0xf);	/* enable DQS's for DDR */

	memctl->ctrl = cfg_value;	/* ctrl */
	asm volatile ("sync");

	return size;
}
