/*
 * Copyright (c) 2004 Picture Elements, Inc.
 *    Stephen Williams (steve@icarus.com)
 *
 *    This source code is free software; you can redistribute it
 *    and/or modify it in source code form 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 <ppc4xx.h>
#include <asm/processor.h>

# define SDRAM_LEN 0x08000000

/*
 * this is even after checkboard. It returns the size of the SDRAM
 * that we have installed. This function is called by board_init_f
 * in lib_ppc/board.c to initialize the memory and return what I
 * found.
 */
long int initdram (int board_type)
{
	/* Configure the SDRAMS */

	/* disable memory controller */
	mtdcr (memcfga, mem_mcopt1);
	mtdcr (memcfgd, 0x00000000);

	udelay (500);

	/* Clear SDRAM0_BESR0 (Bus Error Syndrome Register) */
	mtdcr (memcfga, mem_besra);
	mtdcr (memcfgd, 0xffffffff);

	/* Clear SDRAM0_BESR1 (Bus Error Syndrome Register) */
	mtdcr (memcfga, mem_besrb);
	mtdcr (memcfgd, 0xffffffff);

	/* Clear SDRAM0_ECCCFG (disable ECC) */
	mtdcr (memcfga, mem_ecccf);
	mtdcr (memcfgd, 0x00000000);

	/* Clear SDRAM0_ECCESR (ECC Error Syndrome Register) */
	mtdcr (memcfga, mem_eccerr);
	mtdcr (memcfgd, 0xffffffff);

	/* Timing register: CASL=2, PTA=2, CTP=2, LDF=1, RFTA=5, RCD=2 */
	mtdcr (memcfga, mem_sdtr1);
	mtdcr (memcfgd, 0x010a4016);

	/* Memory Bank 0 Config == BA=0x00000000, SZ=64M, AM=3, BE=1 */
	mtdcr (memcfga, mem_mb0cf);
	mtdcr (memcfgd, 0x00084001);

	/* Memory Bank 1 Config == BA=0x04000000, SZ=64M, AM=3, BE=1 */
	mtdcr (memcfga, mem_mb1cf);
	mtdcr (memcfgd, 0x04084001);

	/* Memory Bank 2 Config ==  BE=0 */
	mtdcr (memcfga, mem_mb2cf);
	mtdcr (memcfgd, 0x00000000);

	/* Memory Bank 3 Config ==  BE=0 */
	mtdcr (memcfga, mem_mb3cf);
	mtdcr (memcfgd, 0x00000000);

	/* refresh timer = 0x400  */
	mtdcr (memcfga, mem_rtr);
	mtdcr (memcfgd, 0x04000000);

	/* Power management idle timer set to the default. */
	mtdcr (memcfga, mem_pmit);
	mtdcr (memcfgd, 0x07c00000);

	udelay (500);

	/* Enable banks (DCE=1, BPRF=1, ECCDD=1, EMDUL=1) */
	mtdcr (memcfga, mem_mcopt1);
	mtdcr (memcfgd, 0x80e00000);

	return SDRAM_LEN;
}

/*
 * The U-Boot core, as part of the initialization to prepare for
 * loading the monitor into SDRAM, requests of this function that the
 * memory be tested. Return 0 if the memory tests OK.
 */
int testdram (void)
{
	unsigned long idx;
	unsigned val;
	unsigned errors;
	volatile unsigned long *sdram;

#ifdef DEBUG
	printf ("SDRAM Controller Registers --\n");

	mtdcr (memcfga, mem_mcopt1);
	val = mfdcr (memcfgd);
	printf ("    SDRAM0_CFG   : 0x%08x\n", val);

	mtdcr (memcfga, 0x24);
	val = mfdcr (memcfgd);
	printf ("    SDRAM0_STATUS: 0x%08x\n", val);

	mtdcr (memcfga, mem_mb0cf);
	val = mfdcr (memcfgd);
	printf ("    SDRAM0_B0CR  : 0x%08x\n", val);

	mtdcr (memcfga, mem_mb1cf);
	val = mfdcr (memcfgd);
	printf ("    SDRAM0_B1CR  : 0x%08x\n", val);

	mtdcr (memcfga, mem_sdtr1);
	val = mfdcr (memcfgd);
	printf ("    SDRAM0_TR    : 0x%08x\n", val);

	mtdcr (memcfga, mem_rtr);
	val = mfdcr (memcfgd);
	printf ("    SDRAM0_RTR   : 0x%08x\n", val);
#endif

	/* Wait for memory to be ready by testing MRSCMPbit
	   bit. Really, there should already have been plenty of time,
	   given it was started long ago. But, best to check. */
	for (idx = 0; idx < 1000000; idx += 1) {
		mtdcr (memcfga, 0x24);
		val = mfdcr (memcfgd);
		if (val & 0x80000000)
			break;
	}

	if (!(val & 0x80000000)) {
		printf ("SDRAM ERROR: SDRAM0_STATUS never set!\n");
		return 1;
	}

	/* Start memory test. */
	printf ("test: %u MB - ", SDRAM_LEN / 1048576);

	sdram = (unsigned long *) CFG_SDRAM_BASE;

	printf ("write - ");
	for (idx = 2; idx < SDRAM_LEN / 4; idx += 2) {
		sdram[idx + 0] = idx;
		sdram[idx + 1] = ~idx;
	}

	printf ("read - ");
	errors = 0;
	for (idx = 2; idx < SDRAM_LEN / 4; idx += 2) {
		if (sdram[idx + 0] != idx)
			errors += 1;
		if (sdram[idx + 1] != ~idx)
			errors += 1;
		if (errors > 0)
			break;
	}

	if (errors > 0) {
		printf ("NOT OK\n");
		printf ("FIRST ERROR at %p: 0x%08lx:0x%08lx != 0x%08lx:0x%08lx\n",
			sdram + idx, sdram[idx + 0], sdram[idx + 1], idx, ~idx);
		return 1;
	}

	printf ("ok\n");
	return 0;
}
