/*
 * Copyright 2004 Freescale Semiconductor.
 *
 * 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
 */
 
#undef PQ37PC_DEBUG
#ifdef PQ37PC_DEBUG
	#define DEBUG(arg...) printf(arg)
#else
	#define DEBUG(arg...)
#endif
 
 
#include <common.h>
#include <pci.h>
#include <asm/immap_85xx.h>
#include <asm/processor.h>
#include <miiphy.h>
#include "pq37pc.h"
#include "../../../drivers/tsec.h"

#if defined(CONFIG_DDR_ECC)
extern void ddr_enable_ecc(unsigned int dram_size);
#endif


/*
 * sysclk for MPC85xx
 *
 * Two valid values are:
 *    33333333
 *    66666666
 *
 * Most PCI cards are still 33Mhz, so in the presence of PCI, 33MHz
 * is likely the desired value here, so that is now the default.
 * The board, however, can run at 66MHz.
 */
unsigned long get_clock_freq(void)
{
    volatile unsigned int *base = (volatile unsigned int *)CFG_LED_BASE;
    uint pci1_speed = (*base & 0x4) >> 2;
    if (pci1_speed == 0) return 33333334;
      else  return 66666667;
}


/*Get boot port size from PORMBSR register for BR0*/
/*For PQ37PC REVB, the flash is 8-bit */
/*For PQ37PC REVC, the flash is 16-bit */
unsigned long get_br0(void)
{
	volatile immap_t    *immap = (immap_t *)CFG_IMMR;
    volatile ccsr_gur_t *gur = &immap->im_gur;
    
    long temp = (gur->porbmsr & 0x07000000)>>24;
    if (temp == 0x5)
    	return 0xff800801;

    else if (temp == 0x6)
		return 0xff801001;
     
}

/*Get boot port size from PORMBSR register for BR1*/
/*For PQ37PC REVB, the flash is 8-bit */
/*For PQ37PC REVC, the flash is 16-bit */
unsigned long get_br1(void)
{
	
	volatile immap_t    *immap = (immap_t *)CFG_IMMR;
    volatile ccsr_gur_t *gur = &immap->im_gur;
    
	long temp = (gur->porbmsr & 0x07000000)>>24;
    if (temp == 0x5)
       	return 0xff000801;

    else if (temp == 0x6)
		return 0xff001001;
      
}


char* get_prompt(void)
{
  volatile immap_t *immr = (immap_t *)CFG_IMMR;
  uint svr = get_svr();
  uint ver = SVR_VER(svr);
  
  switch (ver){
	  	case SVR_8560:
      	return "PQ37PC_8560=> ";
    	case SVR_8540:
      	return "PQ37PC_8540=> ";
	  	case SVR_8555:
      	return "PQ37PC_8555=> ";
	  	case SVR_8541:
      	return "PQ37PC_8541=> ";
    	default:
      	return "=> ";
  }
}

int board_early_init_f (void)
{
	DEBUG("%s: ENTER\n", __FUNCTION__);
    return 0;
}

int	board_early_init_r (void)
{
	volatile immap_t    *immap = (immap_t *)CFG_IMMR;
	volatile ccsr_lbc_t *memctl = &immap->im_lbc;
	
	/*Set the initial value for scan the flash*/
		memctl->br0 = CFG_BR0_SCAN;
		memctl->or0 = CFG_OR0_SCAN;
		memctl->or1 = CFG_OR1_SCAN;
		memctl->br1 = CFG_BR1_SCAN;
		return 0;
}

#define ECNTRL_RPM		0x00000010

void reset_phy(void)
{
	/*Need switch to detect if RGMII is used and set RGMII 1.5ns clk skew*/
	/*Need switch to detect if Marvell phy to set RGMII 1.5ns*/
	volatile immap_t    *immap = (immap_t *)CFG_IMMR;
	volatile ccsr_tsec_t *tsec1 = &immap->im_tsec1;
	volatile ccsr_tsec_t *tsec2 = &immap->im_tsec2;
	struct eth_device *dev;
	struct tsec_private *priv;
	struct phy_info *theInfo;

    	vu_char* base = (vu_char *)CFG_LED_BASE;
	DEBUG("%s: ENTER\n", __FUNCTION__);

	dev = (struct eth_device *)eth_get_dev_by_name("TSEC0");
	priv = (struct tsec_private*)dev->priv;
	if (tsec1->ecntrl&ECNTRL_RPM){
		printf("TSEC0 & TSEC1 in Reduce mode\n");
		/*set RGMII 1.5ns on tx, rx clk in Marvell*/
		if (priv->phyinfo->name == "Marvell 88E1111S")
		{
			DEBUG("TSEC0: Add 1.5ns clk skew in Marvell\n");
			DEBUG("Phyaddr = %d\n",priv->phyaddr);
			tsec_miiphy_write("TSEC0", priv->phyaddr,20,0x0ce2);
		}
	}
   	/*reset Phy*/
   	tsec_miiphy_write("TSEC0", priv->phyaddr,0,0x9140);

	dev = (struct eth_device *)eth_get_dev_by_name("TSEC1");
	priv = (struct tsec_private*)dev->priv;
	if ((tsec2->ecntrl&ECNTRL_RPM)&&(priv->phyinfo->name == "Marvell 88E1111S"))
	{
		DEBUG("TSEC1: Add 1.5ns clk skew in Marvell\n");
		DEBUG("Phyaddr = %d\n",priv->phyaddr);
		/*set RGMII 1.5ns on tx, rx clk in Marvell*/
		tsec_miiphy_write("TSEC1", priv->phyaddr,20,0x0ce2);
	}
	/*reset Phy*/
   	tsec_miiphy_write("TSEC1", priv->phyaddr,0,0x9140);

	udelay(1000);
	*base = 0xf0;
	DEBUG("%s: EXIT\n", __FUNCTION__);
}


int auto_ddr_timing(sys_info_t * sysinfopt)	/* Auto select for CCB speed function */
{
  volatile immap_t *immap = (immap_t *)CFG_IMMR;
  volatile ccsr_ddr_t *ddr= &immap->im_ddr;
  
  uint pretoact, acttopre, acttorw, caslat, refrec, wrrec, acttoact, wrtord, refint;
  uint time_factor;

  DEBUG("%s: ENTER\n", __FUNCTION__);

  /* Initialization */
  pretoact = acttopre = acttorw = caslat = refrec = wrrec = acttoact = wrtord = refint = 0;

  DEBUG("System Freq: %lu\n", sysinfopt->freqSystemBus);
  time_factor = sysinfopt->freqSystemBus / 2000000;	/* A time factor =  DDR Frequency / 10^6*/
  
  DEBUG("Time factor: %lu\n",time_factor);
  
#if (defined(CFG_DDR_TRP) && defined(CFG_DDR_TRAS) && defined(CFG_DDR_TRCD)\
  && defined(CFG_DDR_CAS) && defined(CFG_DDR_TRFC) && defined(CFG_DDR_TWR) \
  && defined(CFG_DDR_TRRD) && defined(CFG_DDR_TWTR) && defined(CFG_DDR_TREFI))
  
  /* Finding PRETOACT */
  if ((CFG_DDR_TRP * time_factor) <= 1000)
      pretoact = 0x00000001;
  else if ((CFG_DDR_TRP * time_factor) <= 2000)
      pretoact = 0x00000002;
  else if ((CFG_DDR_TRP * time_factor) <= 3000)
      pretoact = 0x00000003;
  else if ((CFG_DDR_TRP * time_factor) <= 4000)
      pretoact = 0x00000004;
  else if ((CFG_DDR_TRP * time_factor) <= 5000)
      pretoact = 0x00000005;
  else if ((CFG_DDR_TRP * time_factor) <= 6000)
      pretoact = 0x00000006;
  else if ((CFG_DDR_TRP * time_factor) <= 7000)
      pretoact = 0x00000007;
  else pretoact = 0;
  DEBUG("PRETOACT: %lu %08x \n", (CFG_DDR_TRP * time_factor), pretoact);
  
  /* Fidning ACTTOPRE */
  if ((CFG_DDR_TRAS * time_factor) <= 1000)
      acttopre = 0x00000001;
  else if ((CFG_DDR_TRAS * time_factor) <= 2000)
      acttopre = 0x00000002;
  else if ((CFG_DDR_TRAS * time_factor) <= 3000)
      acttopre = 0x00000003;
  else if ((CFG_DDR_TRAS * time_factor) <= 4000)
      acttopre = 0x00000004;
  else if ((CFG_DDR_TRAS * time_factor) <= 5000)
      acttopre = 0x00000005;
  else if ((CFG_DDR_TRAS * time_factor) <= 6000)
      acttopre = 0x00000006;
  else if ((CFG_DDR_TRAS * time_factor) <= 7000)
      acttopre = 0x00000007;
  else if ((CFG_DDR_TRAS * time_factor) <= 8000)
      acttopre = 0x00000008;
  else if ((CFG_DDR_TRAS * time_factor) <= 9000)
      acttopre = 0x00000009;
  else if ((CFG_DDR_TRAS * time_factor) <= 10000)
      acttopre = 0x0000000a;
  else if ((CFG_DDR_TRAS * time_factor) <= 11000)
      acttopre = 0x0000000b;
  else if ((CFG_DDR_TRAS * time_factor) <= 12000)
      acttopre = 0x0000000c;
  else if ((CFG_DDR_TRAS * time_factor) <= 13000)
      acttopre = 0x0000000d;
  else if ((CFG_DDR_TRAS * time_factor) <= 14000)
      acttopre = 0x0000000e;
  else if ((CFG_DDR_TRAS * time_factor) <= 15000)
      acttopre = 0x0000000f;
  else acttopre = 0;
  DEBUG("ACTTOPRE: %lu %08x\n", CFG_DDR_TRAS * time_factor, acttopre);

  /* Finding ACTTORW */
  if ((CFG_DDR_TRCD * time_factor) <= 1000)
      acttorw = 0x00000001;
  else if ((CFG_DDR_TRCD * time_factor) <= 2000)
      acttorw = 0x00000002;
  else if ((CFG_DDR_TRCD * time_factor) <= 3000)
      acttorw = 0x00000003;
  else if ((CFG_DDR_TRCD * time_factor) <= 4000)
      acttorw = 0x00000004;
  else if ((CFG_DDR_TRCD * time_factor) <= 5000)
      acttorw = 0x00000005;
  else if ((CFG_DDR_TRCD * time_factor) <= 6000)
      acttorw = 0x00000006;
  else if ((CFG_DDR_TRCD * time_factor) <= 7000)
      acttorw = 0x00000007;
  else acttorw = 0;
  DEBUG("ACTTORW: %lu %08x\n", CFG_DDR_TRCD * time_factor, acttorw);
  
  /* Finding CASLAT */
  if ((CFG_DDR_CAS * time_factor) <= 1000)
      caslat = 0x00000001;
  else if ((CFG_DDR_CAS * time_factor) <= 1500)
      caslat = 0x00000002;
  else if ((CFG_DDR_CAS * time_factor) <= 2000)
      caslat = 0x00000003;
  else if ((CFG_DDR_CAS * time_factor) <= 2500)
      caslat = 0x00000004;
  else if ((CFG_DDR_CAS * time_factor) <= 3000)
      caslat = 0x00000005;
  else if ((CFG_DDR_CAS * time_factor) <= 3500)
      caslat = 0x00000006;
  else if ((CFG_DDR_CAS * time_factor) <= 4000)
      caslat = 0x00000007;
  else caslat = 0;
  DEBUG("CASLAT: %lu %08x\n", CFG_DDR_CAS * time_factor, caslat);
    
  /* Fidning REFREC */
  if ((CFG_DDR_TRFC * time_factor) <= 9000)
      refrec = 0x00000001;
  else if ((CFG_DDR_TRFC * time_factor) <= 10000)
      refrec = 0x00000002;
  else if ((CFG_DDR_TRFC * time_factor) <= 11000)
      refrec = 0x00000003;
  else if ((CFG_DDR_TRFC * time_factor) <= 12000)
      refrec = 0x00000004;
  else if ((CFG_DDR_TRFC * time_factor) <= 13000)
      refrec = 0x00000005;
  else if ((CFG_DDR_TRFC * time_factor) <= 14000)
      refrec = 0x00000006;
  else if ((CFG_DDR_TRFC * time_factor) <= 15000)
      refrec = 0x00000007;
  else if ((CFG_DDR_TRFC * time_factor) <= 16000)
      refrec = 0x00000008;
  else if ((CFG_DDR_TRFC * time_factor) <= 17000)
      refrec = 0x00000009;
  else if ((CFG_DDR_TRFC * time_factor) <= 18000)
      refrec = 0x0000000a;
  else if ((CFG_DDR_TRFC * time_factor) <= 19000)
      refrec = 0x0000000b;
  else if ((CFG_DDR_TRFC * time_factor) <= 20000)
      refrec = 0x0000000c;
  else if ((CFG_DDR_TRFC * time_factor) <= 21000)
      refrec = 0x0000000d;
  else if ((CFG_DDR_TRFC * time_factor) <= 22000)
      refrec = 0x0000000e;
  else if ((CFG_DDR_TRFC * time_factor) <= 23000)
      refrec = 0x0000000f;
  else refrec = 0;
  DEBUG("REFREC: %lu %08x\n", CFG_DDR_TRFC * time_factor, refrec);
  
  /* Finding WRREC */
  if ((CFG_DDR_TWR * time_factor) <= 1000)
      wrrec = 0x00000001;
  else if ((CFG_DDR_TWR * time_factor) <= 2000)
      wrrec = 0x00000002;
  else if ((CFG_DDR_TWR * time_factor) <= 3000)
       wrrec = 0x00000003;
  else if ((CFG_DDR_TWR * time_factor) <= 4000)
      wrrec = 0x00000004;
  else if ((CFG_DDR_TWR * time_factor) <= 5000)
      wrrec = 0x00000005;
  else if ((CFG_DDR_TWR * time_factor) <= 6000)
      wrrec = 0x00000006;
  else if ((CFG_DDR_TWR * time_factor) <= 7000)
      wrrec = 0x00000007;
  else wrrec = 0;
  DEBUG("WRREC: %lu %08x\n", CFG_DDR_TWR * time_factor, wrrec);
  
  /* Finding ACTTOACT */
  if ((CFG_DDR_TRRD * time_factor) <= 1000)
      acttoact = 0x00000001;
  else if ((CFG_DDR_TRRD * time_factor) <= 2000)
      acttoact = 0x00000002;
  else if ((CFG_DDR_TRRD * time_factor) <= 3000)
      acttoact = 0x00000003;
  else if ((CFG_DDR_TRRD * time_factor) <= 4000)
      acttoact = 0x00000004;
  else acttoact = 0;
  DEBUG("ACTTOACT: %lu %08x\n", CFG_DDR_TRRD * time_factor, acttoact);
  
  /* Finding WRTORD */
  if ((CFG_DDR_TWTR * time_factor) <= 1000)
      wrtord = 0x00000001;
  else if ((CFG_DDR_TWTR * time_factor) <= 2000)
      wrtord = 0x00000002;
  else if ((CFG_DDR_TWTR * time_factor) <= 3000)
      wrtord = 0x00000003;
  else if ((CFG_DDR_TWTR * time_factor) <= 4000)
      wrtord = 0x00000004;
  else if ((CFG_DDR_TWTR * time_factor) <= 5000)
      wrtord = 0x00000005;
  else if ((CFG_DDR_TWTR * time_factor) <= 6000)
      wrtord = 0x00000006;
  else if ((CFG_DDR_TWTR * time_factor) <= 7000)
      wrtord = 0x00000007;
  else wrtord = 0;
  DEBUG("WRTORD: %lu %08x\n", CFG_DDR_TWTR * time_factor, wrtord);
  
  /* Finding REFINT */
  if (CFG_DDR_TREFI && ((CFG_DDR_TREFI * time_factor / 1000) <= 0x3FFF)) /* 0x3FFF is the max. of 13 bit value, the REFINT in PQ3*/
    refint = CFG_DDR_TREFI * time_factor / 1000;
  else refint = 0;
  DEBUG("REFINE: %08x\n", refint);
#endif

  if (pretoact && acttopre && acttorw && caslat && refrec && wrrec && acttoact && wrtord){	/* if all time parameter are valid */
    /* setting ddr timing configuration register 1 */
    ddr->timing_cfg_1 = (pretoact << 28) + (acttopre << 24) + (acttorw << 20) + (caslat << 16) + (refrec << 12) + (wrrec << 8) + (acttoact << 4) + wrtord;
    DEBUG("Timing Cfg value: %08x\n", ddr->timing_cfg_1);
  
    /* setting ddr timing configuration register 2, default value */  
    ddr->timing_cfg_2 = CFG_DDR_TIMING_2;
      
#if defined(FAST_DDR)	/* For Fast DDR, CASLAT (set in mode register) = CASLAT (set in timing 1 register)  - 0.5 clock cycle */
    /* checked for case 0x03 and 0x04 */
    switch(caslat) {
    case 0x01:
      ddr->sdram_mode = 0x00000002 + 0x00000050;
      DEBUG("mode: %08x\n",ddr->sdram_mode);
      break;
    case 0x02:
      ddr->sdram_mode = 0x00000002 + 0x00000020;
      DEBUG("mode: %08x\n",ddr->sdram_mode);
      break;
    case 0x03:
      ddr->sdram_mode = 0x00000002 + 0x00000060;
      DEBUG("mode: %08x\n",ddr->sdram_mode);
      break;
    case 0x04:
      ddr->sdram_mode = 0x00000002 + 0x00000030;
      DEBUG("mode: %08x\n",ddr->sdram_mode);
      break;
    case 0x05:	/* 3 clock cycles */
      ddr->sdram_mode = 0x00000002 + 0x00000030;
      DEBUG("mode: %08x\n",ddr->sdram_mode);
      break;
    default:
      ddr->sdram_mode = CFG_DDR_MODE;
      DEBUG("mode: %08x\n",ddr->sdram_mode);
      break;
    }
#else
    switch(caslat) {
    case 0x03:	/* 2 clock cycles */
      ddr->sdram_mode = 0x00000002 + 0x00000020;
      DEBUG("mode: %08x\n",ddr->sdram_mode);
      break;
    case 0x05:	/* 3 clock cycles */
      ddr->sdram_mode = 0x00000002 + 0x00000030;
      DEBUG("mode: %08x\n",ddr->sdram_mode);
      break;
    case 0x02:	/* 1.5 clock cycles */
      ddr->sdram_mode = 0x00000002 + 0x00000050;
      DEBUG("mode: %08x\n",ddr->sdram_mode);
      break;
    case 0x04:	/* 2.5 clock cycles */
      ddr->sdram_mode = 0x00000002 + 0x00000060;
      DEBUG("mode: %08x\n",ddr->sdram_mode);
      break;
    default:
      ddr->sdram_mode = CFG_DDR_MODE;
      DEBUG("mode: %08x\n",ddr->sdram_mode);
      break;
    }
#endif
    if (refint){
      ddr->sdram_interval = (((refint << 16) & CFG_DDR_REFINT_MASK) + (CFG_DDR_BSTOPRE & CFG_DDR_BSTOPRE_MASK));
      DEBUG("DDR_INTERVAL: %08x\n", ddr->sdram_interval);
      return 0;
    }
    else{
      ddr->sdram_interval = CFG_DDR_INTERVAL;
      printf("\tAuto not works on interval.\n");
      return -1;
    }
  }else if (refint){
          ddr->timing_cfg_1 = CFG_DDR_TIMING_1;
          ddr->timing_cfg_2 = CFG_DDR_TIMING_2;
          ddr->sdram_mode = CFG_DDR_MODE;
          ddr->sdram_interval = (((refint << 16) & CFG_DDR_REFINT_MASK) + (CFG_DDR_BSTOPRE & CFG_DDR_BSTOPRE_MASK));
          printf("\tAuto only works on interval.\n");
          return -1;
        }  
        else {	/* use default settings if the time parameter is unvalid */
          ddr->timing_cfg_1 = CFG_DDR_TIMING_1;
          ddr->timing_cfg_2 = CFG_DDR_TIMING_2;
          ddr->sdram_mode = CFG_DDR_MODE;
          ddr->sdram_interval = CFG_DDR_INTERVAL;
          printf("\tAuto not works.\n");
        return -1;
    }
}

long int initdram(int board_type)
{
	long dram_size = 0;
	extern long spd_sdram (void);
	volatile immap_t *immap = (immap_t *)CFG_IMMR;
	volatile ccsr_gur_t *gur= &immap->im_gur;
	volatile ccsr_ddr_t	*ddr= &immap->im_ddr;
    vu_char* base = (vu_char *)CFG_LED_BASE;
	sys_info_t sysinfo;

	unsigned long val;
    *base = 0xf7;
	val = mfmsr();
	DEBUG("MSR = 0x%x\n",val);

	DEBUG("%s: ENTER\n", __FUNCTION__);

	puts("Initializing\n");
	
#if defined(CONFIG_DDR_DLL)
	/* DDR DLL workaround */
	DEBUG("DDRDLLCR = 0x81000000\n");
	gur->ddrdllcr = 0x81000000;
	asm("sync;isync;msync");
	udelay(200);
#endif
/*Added which had been removed since u-boot-1.1.1*/
#if defined(MPC85xx_DDR_SDRAM_CLK_CNTL)
	DEBUG("DDR_SDRAM_CLK_CNTL = 0x82000000\n");
	ddr->sdram_clk_cntl = 0x82000000;
	asm("sync;isync;msync");
	udelay(200);
#endif

	dram_size = fixed_sdram(&sysinfo);

	val = mfmsr();
	DEBUG("MSR = 0x%x\n",val);

#if defined(CONFIG_DDR_ECC)
	/*
	 * Initialize and enable DDR ECC.
	 */
	ddr_enable_ecc(dram_size);
#endif

	puts("DDR:   ");

	DEBUG("%s: EXIT\n", __FUNCTION__);
	*base = 0xf3;
	return dram_size;
}


/*
 * Initialize Local Bus
 */

void
local_bus_init(void)
{
	volatile immap_t *immap = (immap_t *)CFG_IMMR;
	volatile ccsr_gur_t *gur = &immap->im_gur;
	volatile ccsr_lbc_t *lbc = &immap->im_lbc;
    vu_char* base = (vu_char *)CFG_LED_BASE;

/*	uint clkdiv;*/
	uint lbc_hz;
	sys_info_t sysinfo;

	DEBUG("%s: ENTER\n", __FUNCTION__);
	
	/*
	 * Errata LBC11.
	 * Fix Local Bus clock glitch when DLL is enabled.
	 *
	 * If localbus freq is < 66Mhz, DLL bypass mode must be used.
	 * If localbus freq is > 133Mhz, DLL can be safely enabled.
	 * Between 66 and 133, the DLL is enabled with an override workaround.
	 */

	get_sys_info(&sysinfo);
/*	clkdiv = lbc->lcrr & 0x0f;*/
/*	lbc_hz = sysinfo.freqSystemBus / 1000000 / clkdiv;*/
	lbc_hz = sysinfo.freqSystemBus / 1000000 / (CFG_LBC_LCRR & 0x0f);
	
	DEBUG("(CFG_LBC_LCRR & 0x0f): %d\n", (CFG_LBC_LCRR & 0x0f));
	DEBUG("sysinfo.freqSystemBus %d\n", sysinfo.freqSystemBus);
	DEBUG("lbc_hz: %d\n", lbc_hz);	
	
	if (lbc_hz < 66) {
		lbc->lcrr = CFG_LBC_LCRR | 0x80000000;	/* DLL Bypass */
	}
	else if (lbc_hz >= 133){
		if (lbc_hz > 166)		/* LBC not support > 166 */
			lbc->lcrr = CFG_LBC_LCRR4 & (~0x80000000); /* DLL Enabled */
		else
		 	lbc->lcrr = CFG_LBC_LCRR2 & (~0x80000000); /* DLL Enabled */
		udelay(200);
	}
	else {
		/*
		 * On REV1 boards, need to change CLKDIV before enable DLL.
		 * Default CLKDIV is 8, change it to 4 temporarily.
		 */
		uint pvr = get_pvr();
		uint temp_lbcdll = 0;

		if (pvr == PVR_85xx_REV1) {
			/* FIXME: Justify the high bit here. */
			lbc->lcrr = 0x10000004;
		}
		
		lbc->lcrr = CFG_LBC_LCRR & (~0x80000000);/* DLL Enabled */
		udelay(200);

		/*
		 * Sample LBC DLL ctrl reg, upshift it to set the
		 * override bits.
		 */
		temp_lbcdll = gur->lbcdllcr;
		gur->lbcdllcr = (((temp_lbcdll & 0xff) << 16) | 0x80000000);
		asm("sync;isync;msync");
	}
	DEBUG("%s: EXIT\n", __FUNCTION__);
	*base = 0xf1;
}

#if defined(CFG_DRAM_TEST)
int testdram (void)
{
	uint *pstart = (uint *) CFG_MEMTEST_START;
	uint *pend = (uint *) CFG_MEMTEST_END;
	uint *p;

	printf("SDRAM test phase 1:\n");
	for (p = pstart; p < pend; p++)
		*p = 0xaaaaaaaa;

	for (p = pstart; p < pend; p++) {
		if (*p != 0xaaaaaaaa) {
			printf ("SDRAM test fails at: %08x\n", (uint) p);
			return 1;
		}
	}

	printf("SDRAM test phase 2:\n");
	for (p = pstart; p < pend; p++)
		*p = 0x55555555;

	for (p = pstart; p < pend; p++) {
		if (*p != 0x55555555) {
			printf ("SDRAM test fails at: %08x\n", (uint) p);
			return 1;
		}
	}

	printf("SDRAM test passed.\n");
	return 0;
}
#endif


/*************************************************************************
 *  fixed sdram init -- doesn't use serial presence detect.
 ************************************************************************/
long int fixed_sdram (sys_info_t * sysinfopt)
{
	volatile immap_t *immap = (immap_t *)CFG_IMMR;
	volatile ccsr_ddr_t *ddr= &immap->im_ddr;
	long size,temp;
	volatile long *addr;
	DEBUG("%s: ENTER\n", __FUNCTION__);
	get_sys_info(sysinfopt);
		
	/*set to max with 14 row 10 col*/
	ddr->cs0_bnds = CFG_DDR_CS0_BNDS_512;
	ddr->cs0_config = CFG_DDR_CS0_CONFIG_512;
	
	/* Auto select for CCB speed function */
	DEBUG("call auto_ddr_timing\n");
 	auto_ddr_timing(sysinfopt);
	
	ddr->sdram_cfg = CFG_DDR_CONTROL;
	asm("sync; isync; msync");
	udelay(500);
	addr = 0x00001800;
	*addr = 0x10101010;
	DEBUG("Write 0x%x to addr 0x%x\n",0x10101010,addr);
	ppcDcbf((unsigned long) addr);
	udelay(100);
	addr = 0x00000800;
	*addr = 0x09090909;
	DEBUG("Write 0x%x to addr 0x%x\n",0x09090909,addr);
	ppcDcbf((unsigned long) addr);
	udelay(100);
	addr = 0x00001800;
	temp = *addr;
	DEBUG("col probe addr 0x%x = 0x%x\n",addr,temp);
	if (temp == 0x10101010)
	{
		DEBUG("10 col bits DDR SDRAM\n");
		addr = 0x1ffffffc;
		*addr = 0x14141414;
		DEBUG("Write 0x%x to addr 0x%x\n",0x14141414,addr);
		ppcDcbf((unsigned long) addr);
		udelay(100);
		addr = 0x0ffffffc;
		*addr = 0x13131313;
		DEBUG("Write 0x%x to addr 0x%x\n",0x13131313,addr);
		ppcDcbf((unsigned long) addr);
		udelay(100);
		addr = 0x1ffffffc;
		temp = *addr;
		DEBUG("row probe addr 0x%x = 0x%x\n",addr,temp);
		if (temp == 0x14141414)
		{
			DEBUG("14 row DDR SDRAM\n");
			size = 0x20000000;
			ddr->cs0_bnds = CFG_DDR_CS0_BNDS_512;
			ddr->cs0_config = CFG_DDR_CS0_CONFIG_512;
			asm("sync; isync; msync");
			udelay(500);
			return size;
		} else {
			DEBUG("13 row DDR SDRAM\n");
			size = 0x10000000;
			ddr->cs0_bnds = CFG_DDR_CS0_BNDS_256;
			ddr->cs0_config = CFG_DDR_CS0_CONFIG_256;
			asm("sync; isync; msync");
			udelay(500);
			return size;
		} 			
			
	} else if (temp == 0x09090909)
	{
		DEBUG("9 col bits DDR SDRAM\n");
		ddr->cs0_config = 0x80000201; /*adjust to 9 col*/
		asm("sync; isync; msync");
		addr = 0x07fffffc;
		*addr = 0x13131313;
		DEBUG("Write 0x%x to addr 0x%x\n",0x13131313,addr);
		ppcDcbf((unsigned long) addr);
		udelay(100);
		addr = 0x03fffffc;
		*addr = 0x12121212;
		DEBUG("Write 0x%x to addr 0x%x\n",0x12121212,addr);
		ppcDcbf((unsigned long) addr);
		udelay(100);
		addr = 0x07fffffc;
		temp = *addr;
		DEBUG("row probe 0x%x = 0x%x\n",addr,temp);
		if (temp == 0x13131313)
		{
			DEBUG("13 row DDR SDRAM\n");
			size = 0x8000000;
			ddr->cs0_bnds = CFG_DDR_CS0_BNDS_128;
			ddr->cs0_config = CFG_DDR_CS0_CONFIG_128;
			asm("sync; isync; msync");
			udelay(500);
			return size;
		} else {
			DEBUG("12 row DDR SDRAM\n");
			size = 0x4000000;
			ddr->cs0_bnds = CFG_DDR_CS0_BNDS_64;
			ddr->cs0_config = CFG_DDR_CS0_CONFIG_64;
			asm("sync; isync; msync");
			udelay(500);
			return size;
		}
		
	} else
		DEBUG("No supported DDR SDRAM found\n");
			
	return 0;
}

#if defined(CONFIG_PCI)
/*
 * Initialize PCI Devices, report devices found.
 */

#ifndef CONFIG_PCI_PNP
static struct pci_config_table pci_pq37pc_config_table[] = {
    { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
      PCI_IDSEL_NUMBER, PCI_ANY_ID,
      pci_cfgfunc_config_device, { PCI_ENET0_IOADDR,
				   PCI_ENET0_MEMADDR,
				   PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER
      } },
    { }
};
#endif


static struct pci_controller hose = {
#ifndef CONFIG_PCI_PNP
	config_table: pci_pq37pc_config_table,
#endif
};

#endif	/* CONFIG_PCI */

void pci_init_board(void)
{
#ifdef CONFIG_PCI
	extern void pci_mpc85xx_init(struct pci_controller *hose);

	pci_mpc85xx_init(&hose);
#endif /* CONFIG_PCI */
}
