/*
 * (C) Copyright 2007
 * Niklaus Giger (Niklaus.Giger@netstal.com)
 * (C) Copyright 2006
 * Sylvie Gohl,             AMCC/IBM, gohl.sylvie@fr.ibm.com
 * Jacqueline Pira-Ferriol, AMCC/IBM, jpira-ferriol@fr.ibm.com
 * Thierry Roman,           AMCC/IBM, thierry_roman@fr.ibm.com
 * Alain Saurel,            AMCC/IBM, alain.saurel@fr.ibm.com
 * Robert Snyder,           AMCC/IBM, rob.snyder@fr.ibm.com
 *
 * (C) Copyright 2006
 * Stefan Roese, DENX Software Engineering, sr@denx.de.
 *
 * 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
 */

/* define DEBUG for debug output */
#undef DEBUG

#include <common.h>
#include <asm/processor.h>
#include <asm/io.h>
#include <asm/mmu.h>
#include <asm/cache.h>
#include <ppc440.h>

void hcu_led_set(u32 value);
void dcbz_area(u32 start_address, u32 num_bytes);

#define ECC_RAM				0x03267F0B
#define NO_ECC_RAM			0x00267F0B

#define HCU_HW_SDRAM_CONFIG_MASK	0x7

#define MY_TLB_WORD2_I_ENABLE TLB_WORD2_I_ENABLE
	/* disable caching on DDR2 */

void board_add_ram_info(int use_default)
{
	PPC4xx_SYS_INFO board_cfg;
	u32 val;

	mfsdram(DDR0_22, val);
	val &= DDR0_22_CTRL_RAW_MASK;
	switch (val) {
	case DDR0_22_CTRL_RAW_ECC_DISABLE:
		puts(" (ECC disabled");
		break;
	case DDR0_22_CTRL_RAW_ECC_CHECK_ONLY:
		puts(" (ECC check only");
		break;
	case DDR0_22_CTRL_RAW_NO_ECC_RAM:
		puts(" (no ECC ram");
		break;
	case DDR0_22_CTRL_RAW_ECC_ENABLE:
		puts(" (ECC enabled");
		break;
	}

	get_sys_info(&board_cfg);
	printf(", %lu MHz", (board_cfg.freqPLB * 2) / 1000000);

	mfsdram(DDR0_03, val);
	val = DDR0_03_CASLAT_DECODE(val);
	printf(", CL%d)", val);
}

/*--------------------------------------------------------------------
 * wait_for_dlllock.
 *--------------------------------------------------------------------*/
static int wait_for_dlllock(void)
{
	unsigned long val;
	int wait = 0;

	/* -----------------------------------------------------------+
	 * Wait for the DCC master delay line to finish calibration
	 * ----------------------------------------------------------*/
	mtdcr(memcfga, DDR0_17);
	val = DDR0_17_DLLLOCKREG_UNLOCKED;

	while (wait != 0xffff) {
		val = mfdcr(memcfgd);
		if ((val & DDR0_17_DLLLOCKREG_MASK) ==
		    DDR0_17_DLLLOCKREG_LOCKED)
			/* dlllockreg bit on */
			return 0;
		else
			wait++;
	}
	debug("0x%04x: DDR0_17 Value (dlllockreg bit): 0x%08x\n", wait, val);
	debug("Waiting for dlllockreg bit to raise\n");

	return -1;
}

/***********************************************************************
 *
 * sdram_panic -- Panic if we cannot configure the sdram correctly
 *
 ************************************************************************/
void sdram_panic(const char *reason)
{
	printf("\n%s: reason %s",  __FUNCTION__,  reason);
	hcu_led_set(0xff);
	while (1) {
	}
	/* Never return */
}

#ifdef CONFIG_DDR_ECC
void blank_string(int size)
{
	int i;

	for (i=0; i<size; i++)
		putc('\b');
	for (i=0; i<size; i++)
		putc(' ');
	for (i=0; i<size; i++)
		putc('\b');
}
/*---------------------------------------------------------------------------+
 * program_ecc.
 *---------------------------------------------------------------------------*/
static void program_ecc(unsigned long start_address, unsigned long num_bytes)
{
	u32 val;
	char str[] = "ECC generation -";
#if defined(CONFIG_PRAM)
	u32 *magicPtr;
	u32 magic;

	if ((mfspr(dbcr0) & 0x80000000) == 0) {
		/* only if no external debugger is alive!
		 * Check whether vxWorks is using EDR logging, if yes zero
		 * also PostMortem and user reserved memory
		 */
		magicPtr = (u32 *)(start_address + num_bytes -
				(CONFIG_PRAM*1024) + sizeof(u32));
		magic = in_be32(magicPtr);
		debug("%s:  CONFIG_PRAM %d kB magic 0x%x 0x%p\n",
		      __FUNCTION__, CONFIG_PRAM,
		      magicPtr, magic);
		if (magic == 0xbeefbabe) {
			printf("%s: preserving at %p\n", __FUNCTION__, magicPtr);
			num_bytes -= (CONFIG_PRAM*1024) - PM_RESERVED_MEM;
		}
	}
#endif

	sync();

	puts(str);

	/* ECC bit set method for cached memory */
	/* Fast method, no noticeable delay */
	dcbz_area(start_address, num_bytes);
	/* Write modified dcache lines back to memory */
	clean_dcache_range(start_address, start_address + num_bytes);
	blank_string(strlen(str));

	/* Clear error status */
	mfsdram(DDR0_00, val);
	mtsdram(DDR0_00, val | DDR0_00_INT_ACK_ALL);

	/*
	 * Clear possible ECC errors
	 * If not done, then we could get an interrupt later on when
	 * exceptions are enabled.
	 */
	mtspr(mcsr, mfspr(mcsr));

	/* Set 'int_mask' parameter to functionnal value */
	mfsdram(DDR0_01, val);
	mtsdram(DDR0_01, ((val &~ DDR0_01_INT_MASK_MASK) |
			  DDR0_01_INT_MASK_ALL_OFF));

	return;
}
#endif


/***********************************************************************
 *
 * initdram -- 440EPx's DDR controller is a DENALI Core
 *
 ************************************************************************/
phys_size_t initdram (int board_type)
{
	unsigned int dram_size = 0;

	mtsdram(DDR0_02, 0x00000000);

	/* Values must be kept in sync with Excel-table <<A0001492.>> ! */
	mtsdram(DDR0_00, 0x0000190A);
	mtsdram(DDR0_01, 0x01000000);
	mtsdram(DDR0_03, 0x02030602);
	mtsdram(DDR0_04, 0x0A020200);
	mtsdram(DDR0_05, 0x02020307);
	switch (in_be16((u16 *)HCU_HW_VERSION_REGISTER) & HCU_HW_SDRAM_CONFIG_MASK) {
	case 1:
		dram_size = 256 * 1024 * 1024 ;
		mtsdram(DDR0_06, 0x0102C812);  /* 256MB RAM */
		mtsdram(DDR0_11, 0x0014C800);  /* 256MB RAM */
		mtsdram(DDR0_43, 0x030A0200);  /* 256MB RAM */
		break;
	case 0:
	default:
		dram_size = 128 * 1024 * 1024 ;
		mtsdram(DDR0_06, 0x0102C80D);  /* 128MB RAM */
		mtsdram(DDR0_11, 0x000FC800);  /* 128MB RAM */
		mtsdram(DDR0_43, 0x030A0300);  /* 128MB RAM */
		break;
	}
	mtsdram(DDR0_07, 0x00090100);

	/*
	 * TCPD=200 cycles of clock input is required to lock the DLL.
	 * CKE must be HIGH the entire time.mtsdram(DDR0_08, 0x02C80001);
	 */
	mtsdram(DDR0_08, 0x02C80001);
	mtsdram(DDR0_09, 0x00011D5F);
	mtsdram(DDR0_10, 0x00000100);
	mtsdram(DDR0_12, 0x00000003);
	mtsdram(DDR0_14, 0x00000000);
	mtsdram(DDR0_17, 0x1D000000);
	mtsdram(DDR0_18, 0x1D1D1D1D);
	mtsdram(DDR0_19, 0x1D1D1D1D);
	mtsdram(DDR0_20, 0x0B0B0B0B);
	mtsdram(DDR0_21, 0x0B0B0B0B);
#ifdef CONFIG_DDR_ECC
	mtsdram(DDR0_22, ECC_RAM);
#else
	mtsdram(DDR0_22, NO_ECC_RAM);
#endif

	mtsdram(DDR0_23, 0x00000000);
	mtsdram(DDR0_24, 0x01020001);
	mtsdram(DDR0_26, 0x2D930517);
	mtsdram(DDR0_27, 0x00008236);
	mtsdram(DDR0_28, 0x00000000);
	mtsdram(DDR0_31, 0x00000000);
	mtsdram(DDR0_42, 0x01000006);
	mtsdram(DDR0_44, 0x00000003);
	mtsdram(DDR0_02, 0x00000001);
	wait_for_dlllock();
	mtsdram(DDR0_00, 0x40000000);  /* Zero init bit */

	/*
	 * Program tlb entries for this size (dynamic)
	 */
	remove_tlb(CONFIG_SYS_SDRAM_BASE, 256 << 20);
	program_tlb(0, 0, dram_size, TLB_WORD2_W_ENABLE | TLB_WORD2_I_ENABLE);

	/*
	 * Setup 2nd TLB with same physical address but different virtual
	 * address with cache enabled. This is done for fast ECC generation.
	 */
	program_tlb(0, CONFIG_SYS_DDR_CACHED_ADDR, dram_size, 0);

#ifdef CONFIG_DDR_ECC
	/*
	 * If ECC is enabled, initialize the parity bits.
	 */
	program_ecc(CONFIG_SYS_DDR_CACHED_ADDR, dram_size);
#endif

	return (dram_size);
}
