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

static 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;
}

int misc_init_r(void)
{
	uchar enetaddr[6];

	if (!eth_getenv_enetaddr("ethaddr", enetaddr)) {
		board_get_enetaddr(enetaddr);
		eth_setenv_enetaddr("ethaddr", enetaddr);
	}

	return 0;
}
