/*
 * (C) Copyright 2001
 * Paul Geerinckx
 *
 * 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
 */

#include <common.h>
#include <mpc8xx.h>
#include "atm.h"
#include <i2c.h>

/* ------------------------------------------------------------------------- */

static long int dram_size (long int, long int *, long int);

/* ------------------------------------------------------------------------- */

/* used PLD registers */
#  define PLD_GCR1_REG (unsigned char *) (0x10000000 + 0)
#  define PLD_EXT_RES  (unsigned char *) (0x10000000 + 10)
#  define PLD_EXT_FETH (unsigned char *) (0x10000000 + 11)
#  define PLD_EXT_LED  (unsigned char *) (0x10000000 + 12)
#  define PLD_EXT_X21  (unsigned char *) (0x10000000 + 13)

#define	_NOT_USED_	0xFFFFFFFF

const uint sdram_table[] = {
	/*
	 * Single Read. (Offset 0 in UPMA RAM)
	 */
	0xFE2DB004, 0xF0AA7004, 0xF0A5F400, 0xF3AFFC47,	/* last */
	_NOT_USED_,
	/*
	 * SDRAM Initialization (offset 5 in UPMA RAM)
	 *
	 * This is no UPM entry point. The following definition uses
	 * the remaining space to establish an initialization
	 * sequence, which is executed by a RUN command.
	 *
	 */
	0xFFFAF834, 0xFFE5B435,	/* last */
	_NOT_USED_,
	/*
	 * Burst Read. (Offset 8 in UPMA RAM)
	 */
	0xFE2DB004, 0xF0AF7404, 0xF0AFFC00, 0xF0AFFC00,
	0xF0AFFC00, 0xF0AAF800, 0xF1A5E447,	/* last */
	_NOT_USED_,
	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
	/*
	 * Single Write. (Offset 18 in UPMA RAM)
	 */
	0xFE29B300, 0xF1A27304, 0xFFA5F747,	/* last */
	_NOT_USED_,
	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
	/*
	 * Burst Write. (Offset 20 in UPMA RAM)
	 */
	0x1F0DFC04, 0xEEABBC00, 0x10A77C00, 0xF0AFFC00,
	0xF1AAF804, 0xFFA5F447,	/* last */
	_NOT_USED_, _NOT_USED_,
	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
	_NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
	/*
	 * Refresh  (Offset 30 in UPMA RAM)
	 */
	0xFFAC3884, 0xFFAC3404, 0xFFAFFC04, 0xFFAFFC84,
	0xFFAFFC07,		/* last */
	_NOT_USED_, _NOT_USED_, _NOT_USED_,
	/*
	 * MRS sequence  (Offset 38 in UPMA RAM)
	 */
	0xFFAAB834, 0xFFA57434, 0xFFAFFC05,	/* last */
	_NOT_USED_,
	/*
	 * Exception. (Offset 3c in UPMA RAM)
	 */
	0xFFAFFC04, 0xFFAFFC05,	/* last */
	_NOT_USED_, _NOT_USED_,
};

/* ------------------------------------------------------------------------- */


phys_size_t initdram (int board_type)
{
	volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
	volatile memctl8xx_t *memctl = &immap->im_memctl;
	volatile iop8xx_t *iop = &immap->im_ioport;
	volatile fec_t *fecp = &immap->im_cpm.cp_fec;
	long int size;

	upmconfig (UPMA, (uint *) sdram_table,
		   sizeof (sdram_table) / sizeof (uint));

	/*
	 * Preliminary prescaler for refresh (depends on number of
	 * banks): This value is selected for four cycles every 62.4 us
	 * with two SDRAM banks or four cycles every 31.2 us with one
	 * bank. It will be adjusted after memory sizing.
	 */
	memctl->memc_mptpr = CONFIG_SYS_MPTPR;

	memctl->memc_mar = 0x00000088;

	/*
	 * Map controller banks 2 and 3 to the SDRAM banks 2 and 3 at
	 * preliminary addresses - these have to be modified after the
	 * SDRAM size has been determined.
	 */
	memctl->memc_or2 = CONFIG_SYS_OR2_PRELIM;
	memctl->memc_br2 = CONFIG_SYS_BR2_PRELIM;

	memctl->memc_mamr = CONFIG_SYS_MAMR & (~(MAMR_PTAE));	/* no refresh yet */

	udelay (200);

	/* perform SDRAM initializsation sequence */

	memctl->memc_mcr = 0x80004105;	/* SDRAM bank 0 */
	udelay (1);
	memctl->memc_mcr = 0x80004230;	/* SDRAM bank 0 - execute twice */
	udelay (1);

	memctl->memc_mcr = 0x80004105;	/* SDRAM precharge */
	udelay (1);
	memctl->memc_mcr = 0x80004030;	/* SDRAM 16x autorefresh */
	udelay (1);
	memctl->memc_mcr = 0x80004138;	/* SDRAM upload parameters */
	udelay (1);

	memctl->memc_mamr |= MAMR_PTAE;	/* enable refresh */

	udelay (1000);

	/*
	 * Check Bank 0 Memory Size for re-configuration
	 *
	 */
	size = dram_size (CONFIG_SYS_MAMR, (long *) SDRAM_BASE_PRELIM,
			  SDRAM_MAX_SIZE);

	udelay (1000);


	memctl->memc_mamr = CONFIG_SYS_MAMR;
	udelay (1000);

	/*
	 * Final mapping
	 */
	memctl->memc_or2 = ((-size) & 0xFFFF0000) | CONFIG_SYS_OR2_PRELIM;
	memctl->memc_br2 = ((CONFIG_SYS_SDRAM_BASE & BR_BA_MSK) | BR_MS_UPMA | BR_V);

	udelay (10000);

	/* prepare pin multiplexing for fast ethernet */

	atmLoad ();
	fecp->fec_ecntrl = 0x00000004;	/* rev D3 pinmux SET */
	iop->iop_pdpar |= 0x0080;	/* set pin as MII_clock */


	return (size);
}

/* ------------------------------------------------------------------------- */

/*
 * Check memory range for valid RAM. A simple memory test determines
 * the actually available RAM size between addresses `base' and
 * `base + maxsize'. Some (not all) hardware errors are detected:
 * - short between address lines
 * - short between data lines
 */

static long int dram_size (long int mamr_value, long int *base,
			   long int maxsize)
{
	volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
	volatile memctl8xx_t *memctl = &immap->im_memctl;

	memctl->memc_mamr = mamr_value;

	return (get_ram_size (base, maxsize));
}

/*
 * Check Board Identity:
 */

int checkboard (void)
{
	return (0);
}

void board_serial_init (void)
{
	;			/* nothing to do here */
}

void board_ether_init (void)
{
	volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
	volatile iop8xx_t *iop = &immap->im_ioport;
	volatile fec_t *fecp = &immap->im_cpm.cp_fec;

	atmLoad ();
	fecp->fec_ecntrl = 0x00000004;	/* rev D3 pinmux SET */
	iop->iop_pdpar |= 0x0080;	/* set pin as MII_clock */
}

int board_early_init_f (void)
{
	volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
	volatile cpmtimer8xx_t *timers = &immap->im_cpmtimer;
	volatile memctl8xx_t *memctl = &immap->im_memctl;
	volatile iop8xx_t *iop = &immap->im_ioport;

	/* configure the LED timing output pins - port A pin 4 */
	iop->iop_papar = 0x0800;
	iop->iop_padir = 0x0800;

	/* start timer 2 for the 4hz LED blink rate */
	timers->cpmt_tmr2 = 0xff2c;	/* 4HZ for 64MHz */
	timers->cpmt_trr2 = 0x000003d0;	/* clk/16 , prescale=256 */
	timers->cpmt_tgcr = 0x00000810;	/* run timer 2 */

	/* chip select for PLD access */
	memctl->memc_br6 = 0x10000401;
	memctl->memc_or6 = 0xFC000908;

	/* PLD initial values ( set LEDs, remove reset on LXT) */

	*PLD_GCR1_REG = 0x06;
	*PLD_EXT_RES = 0xC0;
	*PLD_EXT_FETH = 0x40;
	*PLD_EXT_LED = 0xFF;
	*PLD_EXT_X21 = 0x04;
	return 0;
}

void board_get_enetaddr (uchar * addr)
{
	int i;
	volatile immap_t *immap = (immap_t *) CONFIG_SYS_IMMR;
	volatile cpm8xx_t *cpm = &immap->im_cpm;
	unsigned int rccrtmp;

	char default_mac_addr[] = { 0x00, 0x08, 0x01, 0x02, 0x03, 0x04 };

	for (i = 0; i < 6; i++)
		addr[i] = default_mac_addr[i];

	printf ("There is an error in the i2c driver .. /n");
	printf ("You need to fix it first....../n");

	rccrtmp = cpm->cp_rccr;
	cpm->cp_rccr |= 0x0020;

	i2c_reg_read (0xa0, 0);
	printf ("seep = '-%c-%c-%c-%c-%c-%c-'\n",
		i2c_reg_read (0xa0, 0), i2c_reg_read (0xa0, 0),
		i2c_reg_read (0xa0, 0), i2c_reg_read (0xa0, 0),
		i2c_reg_read (0xa0, 0), i2c_reg_read (0xa0, 0));

	cpm->cp_rccr = rccrtmp;
}
