/*
 * (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"

DECLARE_GLOBAL_DATA_PTR;

#define SPD_SIZE	CONFIG_SYS_SDRAM_SPD_SIZE
#define DRAM_SPD	(CONFIG_SYS_SDRAM_SPD_I2C_ADDR)<<1	/* on Board SPD eeprom */
#define TOTAL_BANK	CONFIG_SYS_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)
{
	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 &= ~CONFIG_SYS_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 = CONFIG_SYS_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)
{
	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 */
	sysconf->sdramds = CONFIG_SYS_SDRAM_DRIVE_STRENGTH;

	/* ********************** 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 (CONFIG_SYS_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;
}
