/*
 * (C) Copyright 2003
 * MuLogic B.V.
 *
 * (C) Copyright 2002
 * Simple Network Magic Corporation, dnevil@snmc.com
 *
 * (C) Copyright 2000
 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 *
 * 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 <asm/u-boot.h>
#include <commproc.h>
#include "mpc8xx.h"

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

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

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

const uint sdram_table[] =
{
	/*
	 * Single Read. (Offset 0 in UPMA RAM)
	 */
	0x0f07cc04,  0x00adcc04,  0x00a74c00,  0x00bfcc04,
	0x1fffcc05,  0xffffcc05,  0xffffcc05,  0xffffcc05,
	/*
	 * Burst Read. (Offset 8 in UPMA RAM)
	 */
	0x0ff7fc04,  0x0ffffc04,  0x00bdfc04,  0x00fffc00,
	0x00fffc00,  0x00fffc00,  0x0ff77c00,  0x1ffffc05,
	0x1ffffc05,  0x1ffffc05,  0x1ffffc05,  0x1ffffc05,
	0x1ffffc05,  0x1ffffc05,  0x1ffffc05,  0x1ffffc05,
	/*
	 * Single Write. (Offset 18 in UPMA RAM)
	 */
	0x0f07cc04,  0x0fafcc00,  0x01ad0c04,  0x1ff74c07,
	0xffffcc05,  0xffffcc05,  0xffffcc05,  0xffffcc05,
	/*
	 * Burst Write. (Offset 20 in UPMA RAM)
	 */
	0x0ff7fc04,  0x0ffffc00,  0x00bd7c00,  0x00fffc00,
	0x00fffc00,  0x00fffc00,  0x0ffffc04,  0x0ff77c04,
	0x1ffffc05,  0x1ffffc05,  0x1ffffc05,  0x1ffffc05,
	0x1ffffc05,  0x1ffffc05,  0x1ffffc05,  0x1ffffc05,
	/*
	 * Refresh  (Offset 30 in UPMA RAM)
	 */
	0xffffcc04,  0x1ff5cc84,  0xffffcc04,  0xffffcc04,
	0xffffcc84,  0xffffcc05,  0xffffcc04,  0xffffcc04,
	0xffffcc04,  0xffffcc04,  0xffffcc04,  0xffffcc04,
	/*
	 * Exception. (Offset 3c in UPMA RAM)
	 */
	0x1ff74c04,  0xffffcc07,  0xffffaa34,  0x1fb54a37
};

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


/*
 * Check Board Identity:
 *
 * Test ID string (QS850, QS823, ...)
 *
 * Always return 1
 */
#if defined(CONFIG_QS850)
#define BOARD_IDENTITY	"QS850"
#elif defined(CONFIG_QS823)
#define BOARD_IDENTITY	"QS823"
#else
#define	BOARD_IDENTITY	"QS???"
#endif

int checkboard (void)
{
	char *s, *e;
	char buf[64];
	int i;

	i = getenv_r("serial#", buf, sizeof(buf));
	s = (i>0) ? buf : NULL;

	if (!s || strncmp(s, BOARD_IDENTITY, 5)) {
		puts ("### No HW ID - assuming " BOARD_IDENTITY);
	} else {
		for (e=s; *e; ++e) {
		if (*e == ' ')
		break;
	}

	for ( ; s<e; ++s) {
		putc (*s);
		}
	}
	putc ('\n');

	return (0);
}

/* ------------------------------------------------------------------------- */
/* SDRAM Mode Register Definitions */

/* Set SDRAM Burst Length to 4 (010) */
/* See Motorola MPC850 User Manual, Page 13-14 */
#define SDRAM_BURST_LENGTH      (2)

/* Set Wrap Type to Sequential (0) */
/* See Motorola MPC850 User Manual, Page 13-14 */
#define SDRAM_WRAP_TYPE         (0 << 3)

/* Set /CAS Latentcy to 2 clocks */
#define SDRAM_CAS_LATENTCY      (2 << 4)

/* The Mode Register value must be shifted left by 2, since it is */
/* placed on the address bus, and the 2 LSBs are ignored for 32-bit accesses */
#define SDRAM_MODE_REG  ((SDRAM_BURST_LENGTH|SDRAM_WRAP_TYPE|SDRAM_CAS_LATENTCY) << 2)

#define UPMA_RUN(loops,index)   (0x80002000 + (loops<<8) + index)

/* Please note a value of zero = 16 loops */
#define REFRESH_INIT_LOOPS (0)


phys_size_t initdram (int board_type)
{
	volatile immap_t     *immap  = (immap_t *)CFG_IMMR;
	volatile memctl8xx_t *memctl = &immap->im_memctl;
	long int size;

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

	/*
	* Prescaler for refresh
	*/
	memctl->memc_mptpr = CFG_MPTPR;

	/*
	* Map controller bank 1 to the SDRAM address
	*/
	memctl->memc_or1 = CFG_OR1;
	memctl->memc_br1 = CFG_BR1;
	udelay(1000);

	/* perform SDRAM initialization sequence */
	memctl->memc_mamr = CFG_16M_MAMR;
	udelay(100);

	/* Program the SDRAM's Mode Register */
	memctl->memc_mar  = SDRAM_MODE_REG;

	/* Run the Prechard Pattern at 0x3C */
	memctl->memc_mcr  = UPMA_RUN(1,0x3c);
	udelay(1);

	/* Run the Refresh program residing at MAD index 0x30 */
	/* This contains the CBR Refresh command with a loop */
	/* The SDRAM must be refreshed at least 2 times */
	/* Please note a value of zero = 16 loops */
	memctl->memc_mcr  = UPMA_RUN(REFRESH_INIT_LOOPS,0x30);
	udelay(1);

	/* Run the Exception program residing at MAD index 0x3E */
	/* This contains the Write Mode Register command */
	/* The Write Mode Register command uses the value written to MAR */
	memctl->memc_mcr  = UPMA_RUN(1,0x3e);

	udelay (1000);

	/*
	* Check for 32M SDRAM Memory Size
	*/
	size = dram_size(CFG_32M_MAMR|MAMR_PTAE,
	(long *)SDRAM_BASE, SDRAM_32M_MAX_SIZE);
	udelay (1000);

	/*
	* Check for 16M SDRAM Memory Size
	*/
	if (size != SDRAM_32M_MAX_SIZE) {
	size = dram_size(CFG_16M_MAMR|MAMR_PTAE,
	(long *)SDRAM_BASE, SDRAM_16M_MAX_SIZE);
	udelay (1000);
	}

	udelay(10000);
	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 *)CFG_IMMR;
	volatile memctl8xx_t *memctl = &immap->im_memctl;

	memctl->memc_mamr = mamr_value;

	return (get_ram_size(base, maxsize));
}
